@Override public RelocationRecord markRelocationSite(int offset, int length, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { return ((RelocatableSectionImpl) getElement()).markRelocationSite(offset, length, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); }
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; }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { OutputAssembler out = AssemblyBuffer.createOutputAssembler(getOwner().getByteOrder()); for (RelocationInfo rec : infos.keySet()) { rec.write(out, alreadyDecided); } assert getOrDecideSize(alreadyDecided, -1) == out.pos(); return out.getBlob(); }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { OutputAssembler out = AssemblyBuffer.createOutputAssembler(getOwner().getByteOrder()); ArrayList<LayoutDecision> decisionsOfInterest = new ArrayList<>(); for (Section s : getSections()) { MachOSection ms = (MachOSection) s; if (ms.flags.contains(SectionFlag.SOME_INSTRUCTIONS)) { decisionsOfInterest.add(alreadyDecided.get(s).getDecision(LayoutDecision.Kind.OFFSET)); } } // sort these sections by their decided offset Collections.sort(decisionsOfInterest, new IntegerDecisionComparator(false)); // we should not have any undecideds! assert decisionsOfInterest.size() == 0 || decisionsOfInterest.get(0).isTaken(); EntryStruct ent = new EntryStruct(); for (int i = 0; i < decisionsOfInterest.size(); ++i) { LayoutDecision decision = decisionsOfInterest.get(i); ent.fileOffset = (int) decision.getValue(); int fileSize = (int) alreadyDecided.get(decision.getElement()).getDecidedValue(LayoutDecision.Kind.SIZE); int sectionEndInFile = ent.fileOffset + fileSize; Integer nextOffset = (i + 1 < decisionsOfInterest.size()) ? (int) decisionsOfInterest.get(i + 1).getValue() : null; int nextPageBoundary = (sectionEndInFile % getPageSize()) == 0 ? sectionEndInFile : (((sectionEndInFile >> getPageSizeShift()) + 1) << getPageSizeShift()); ent.length = (short) (nextOffset == null ? nextPageBoundary : Math.min(nextPageBoundary, nextOffset)); ent.entryKind = (short) 0; // FIXME ent.write(out); } return out.getBlob(); } }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { // Generate the native symbol table from our internal representation PECoffSymtabStruct sts = getNativeSymtab(); ByteBuffer outBuffer = ByteBuffer.allocate(getWrittenSize()).order(getOwner().getByteOrder()); OutputAssembler out = AssemblyBuffer.createOutputAssembler(outBuffer); out.writeBlob(sts.getSymtabArray()); out.writeBlob(sts.getStrtabArray()); return out.getBlob(); }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { OutputAssembler out = AssemblyBuffer.createOutputAssembler(ByteBuffer.allocate(65536).order(getOwner().getByteOrder())); // HACK // int loadCommandsSizeInBytes = computeLoadCommandsSize(loadCommands); out.skip((new HeaderStruct()).getWrittenSize()); out.align(8); int loadCommandsSizeInBytes = 0; for (LoadCommand cmd : loadCommands) { loadCommandsSizeInBytes += (int) alreadyDecided.get(cmd).getDecidedValue(LayoutDecision.Kind.SIZE); } out.pushSeek(0); new HeaderStruct(getOwner().getByteOrder() == nativeOrder ? MAGIC : CIGAM, cpuType, MachOObjectFile.this.cpuSubType, loadCommands.size(), loadCommandsSizeInBytes, (int) ObjectFile.flagSetAsLong(MachOObjectFile.this.flags)).write(out); out.pop(); return out.getBlob(); }
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(); }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { OutputAssembler out = AssemblyBuffer.createOutputAssembler(getOwner().getByteOrder()); TreeSet<Integer> fileOffsets = new TreeSet<>(); // merge duplicates (aliased symbols) for (Symbol sym : symbolsOfInterest()) {
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { /* We need to build a prefix tree out of our exported symbols. */ for (MachOSymtab.Entry ent : ((LinkEditSegment64Command) owner.getLinkEditSegment()).getSymtab().getSortedEntries()) { if (ent.isExternal() && ent.isDefined()) { // FIXME: do we really want the vaddr? long symbolVaddr = (int) alreadyDecided.get(ent.getDefinedSection()).getDecidedValue(LayoutDecision.Kind.VADDR) + ent.getDefinedOffset(); addSymbol(ent.getNameInObject(), symbolVaddr); } } OutputAssembler oa = AssemblyBuffer.createOutputAssembler(getOwner().getByteOrder()); root.writeRoot(oa); return oa.getBlob(); }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { OutputAssembler oa = AssemblyBuffer.createOutputAssembler(getOwner().getByteOrder()); byte[] strtabContent = (byte[]) alreadyDecided.get(strtab).getDecidedValue(LayoutDecision.Kind.CONTENT); StringTable t = new StringTable(strtabContent); EntryStruct s = new EntryStruct(); for (Entry e : getSortedEntries()) { s.strx = t.indexFor(e.getNameInObject()); assert s.strx != -1; s.type = (byte) (e.type.value() | (e.privateExtern ? EntryStruct.N_PEXT : 0) | (e.extern ? EntryStruct.N_EXT : 0)); // NOTE: Mach-O section numbers are 1-based int sectionIndex = (e.section == null) ? 0 : getOwner().getSections().indexOf(e.section) + 1; assert !e.isDefined() || sectionIndex != -1; s.sect = (byte) (e.isDefined() ? sectionIndex : EntryStruct.NO_SECT); s.desc = (short) (ObjectFile.flagSetAsLong(e.descFlags) | e.refType.value()); /* * If we're a defined non-absolute symbol, we need to make this the virtual address * (even for relocatable files!), so add the vaddr of the section. Absolute symbols are * denoted by sectionIndex == 0. */ int valueToAdd = (sectionIndex == 0) ? 0 : (int) alreadyDecided.get(e.section).getDecidedValue(LayoutDecision.Kind.VADDR); s.value = e.value + valueToAdd; s.write(oa); } assert oa.pos() == getWrittenSize(); return oa.getBlob(); }
final RelocatableBuffer textBuffer = RelocatableBuffer.factory("text", textSectionSize, objectFile.getByteOrder()); final NativeTextSectionImpl textImpl = NativeTextSectionImpl.factory(textBuffer, objectFile, codeCache); final String textSectionName = SectionName.TEXT.getFormatDependentName(objectFile.getFormat()); final RelocatableBuffer roDataBuffer = RelocatableBuffer.factory("roData", roSectionSize, objectFile.getByteOrder()); final ProgbitsSectionImpl roDataImpl = new BasicProgbitsSectionImpl(roDataBuffer.getBytes()); final String roDataSectionName = SectionName.RODATA.getFormatDependentName(objectFile.getFormat()); final RelocatableBuffer rwDataBuffer = RelocatableBuffer.factory("rwData", rwSectionSize, objectFile.getByteOrder()); final ProgbitsSectionImpl rwDataImpl = new BasicProgbitsSectionImpl(rwDataBuffer.getBytes()); final String rwDataSectionName = SectionName.DATA.getFormatDependentName(objectFile.getFormat()); final long heapSize = heap.getReadOnlySectionSize() + heap.getWritableSectionSize(); heapSectionBuffer = RelocatableBuffer.factory("heap", heapSize, objectFile.getByteOrder()); heapSectionImpl = new BasicProgbitsSectionImpl(heapSectionBuffer.getBytes()); final String heapSectionName = SectionName.SVM_HEAP.getFormatDependentName(objectFile.getFormat());