private static boolean checkEmbeddedOffset(ProgbitsSectionImpl sectionImpl, final int offset, final RelocatableBuffer.Info info) { final ByteBuffer dataBuf = ByteBuffer.wrap(sectionImpl.getContent()).order(sectionImpl.getElement().getOwner().getByteOrder()); if (info.getRelocationSize() == Long.BYTES) { long value = dataBuf.getLong(offset); assert value == 0 || value == 0xDEADDEADDEADDEADL : "unexpected embedded offset"; } else if (info.getRelocationSize() == Integer.BYTES) { int value = dataBuf.getInt(offset); assert value == 0 || value == 0xDEADDEAD : "unexpected embedded offset"; } else { shouldNotReachHere("unsupported relocation size: " + info.getRelocationSize()); } return true; }
private BuildDependency(LayoutDecision depending, LayoutDecision dependedOn) throws DuplicateDependencyException { assert depending != null; assert dependedOn != null; assert depending != dependedOn; // 1-cycle is bad (all cycles are bad) // must be same file assert depending.getElement().getOwner() == dependedOn.getElement().getOwner(); ObjectFile of = depending.getElement().getOwner(); this.depending = depending; this.dependedOn = dependedOn; // avoid adding duplicate entries if (depending.dependsOn().contains(dependedOn)) { assert dependedOn.dependedOnBy().contains(depending); BuildDependency existing = of.getExistingDependency(this); assert existing != null; throw new DuplicateDependencyException(existing); } depending.dependsOn().add(dependedOn); dependedOn.dependedOnBy().add(depending); of.putDependency(this); } }
@Override public int compareTo(LayoutDecision arg) { ObjectFile.Element ourElement = getElement(); int ourElementIndex = ourElement == null ? -1 : ourElement.getOwner().getElements().indexOf(ourElement); int ourKindOrdinal = getKind().ordinal(); ObjectFile.Element argElement = arg.getElement(); int argElementIndex = argElement == null ? -1 : argElement.getOwner().getElements().indexOf(argElement); int argKindOrdinal = arg.getKind().ordinal(); // we can only compare decisions about the same object file if (ourElement != null && argElement != null && ourElement.getOwner() != argElement.getOwner()) { throw new IllegalArgumentException("cannot compare decisions across object files"); } if (ourElementIndex < argElementIndex) { return -1; } else if (ourElementIndex > argElementIndex) { return 1; } else { if (ourKindOrdinal < argKindOrdinal) { return -1; } else if (ourKindOrdinal > argKindOrdinal) { return 1; } else { return 0; } } } }
int nextAvailableVaddr = vaddrHint; Iterable<Element> onCurrentPage = el.getOwner().elementsMappedOnPage(vaddrHint, alreadyDecided); int existingSize = (int) alreadyDecided.get(alreadyMapped).getDecidedValue(LayoutDecision.Kind.SIZE); int existingEndPos = existingOffset + existingSize; int endPageNum = existingEndPos >> el.getOwner().getPageSizeShift(); int ourPageNum = fileOffset >> el.getOwner().getPageSizeShift(); mustStartNewPage |= endPageNum != ourPageNum; if (mustStartNewPage) { mustStartNewPage |= !el.getOwner().elementsCanSharePage(el, alreadyMapped, fileOffset, (int) alreadyDecided.get(alreadyMapped).getDecidedValue(LayoutDecision.Kind.OFFSET)); nextAvailableVaddr = ((nextAvailableVaddr >> el.getOwner().getPageSizeShift()) + 1) << el.getOwner().getPageSizeShift(); for (List<Element> l : el.getOwner().getSegments()) { if (l.get(0) == el) { firstSection = true; el.getOwner().elementsCanSharePage(el, predElement, myOffset, (int) alreadyDecided.get(predElement).getDecidedValue(LayoutDecision.Kind.OFFSET)); boolean predSectionIsAlloc = predElement.isLoadable(); : ObjectFile.nextIntegerMultipleWithCongruence(nextAvailableVaddr, el.getAlignment(), fileOffset % el.getOwner().getPageSize(), el.getOwner().getPageSize()); nextAvailableVaddr = vaddr + el.getMemSize(alreadyDecided);
private byte[] encode() { /* * Create a string table, put each string into it and blat it into a byte buffer. */ StringTable t = new StringTable(); if (contentProviders == null) { throw new IllegalStateException("no content provider assigned"); } /* * Add the empty string so that we begin with it (i.e. a '\0' byte). DWARF and ELF string * sections both require this, and it does no harm even if not required. */ t.add(""); for (String s : this) { assert s != null; t.add(s); } OutputAssembler oa = AssemblyBuffer.createOutputAssembler(getElement().getOwner().getByteOrder()); t.write(oa); return oa.getBlob(); }
public ObjectFile getOwner() { return element.getOwner(); }