@Override public int getOrDecideSize(Map<Element, LayoutDecisionMap> alreadyDecided, int sizeHint) { return ((byte[]) alreadyDecided.get(this).getDecidedValue(LayoutDecision.Kind.CONTENT)).length; } }
@Override public int getOrDecideSize(java.util.Map<Element, LayoutDecisionMap> alreadyDecided, int sizeHint) { Object decidedContent = alreadyDecided.get(this).getDecidedValue(LayoutDecision.Kind.CONTENT); assert decidedContent != null; return ((byte[]) decidedContent).length; } //@formatter:on
@Override public int getMemSize(Map<Element, LayoutDecisionMap> alreadyDecided) { return (int) alreadyDecided.get(this).getDecidedValue(LayoutDecision.Kind.SIZE); }
@Override public int getMemSize(Map<Element, LayoutDecisionMap> alreadyDecided) { return (int) alreadyDecided.get(element).getDecidedValue(LayoutDecision.Kind.SIZE); }
@Override protected void writePayload(OutputAssembler out, Map<Element, LayoutDecisionMap> alreadyDecided) { int symtabOffset = (int) alreadyDecided.get(symtab).getDecidedValue(LayoutDecision.Kind.OFFSET); int symtabEntriesCount = symtab.getEntryCount(); int strtabOffset = (int) alreadyDecided.get(symtab.strtab).getDecidedValue(LayoutDecision.Kind.OFFSET); int strtabSize = (int) alreadyDecided.get(symtab.strtab).getDecidedValue(LayoutDecision.Kind.SIZE); writePayloadFields(out, symtabOffset, symtabEntriesCount, strtabOffset, strtabSize); }
@Override protected void writePayload(OutputAssembler out, Map<Element, LayoutDecisionMap> alreadyDecided) { // our payload is simply the offset and size of our element int elOffset = (int) alreadyDecided.get(el).getDecidedValue(LayoutDecision.Kind.OFFSET); int elSize = (int) alreadyDecided.get(el).getDecidedValue(LayoutDecision.Kind.SIZE); out.write4Byte(elOffset); out.write4Byte(elSize); }
@Override protected void writePayload(OutputAssembler out, Map<Element, LayoutDecisionMap> alreadyDecided) { out.write4Byte((int) alreadyDecided.get(el).getDecidedValue(LayoutDecision.Kind.OFFSET)); out.write4Byte((int) alreadyDecided.get(el).getDecidedValue(LayoutDecision.Kind.SIZE)); }
public void writeBuffer(List<Element> sortedObjectFileElements, ByteBuffer out) { /* Emit each one! */ for (Element e : sortedObjectFileElements) { int off = (int) decisionsTaken.get(e).getDecision(LayoutDecision.Kind.OFFSET).getValue(); assert off != Integer.MAX_VALUE; // not allowed any more -- this was a broken approach out.position(off); int expectedSize = (int) decisionsTaken.get(e).getDecidedValue(LayoutDecision.Kind.SIZE); byte[] content = (byte[]) decisionsTaken.get(e).getDecidedValue(LayoutDecision.Kind.CONTENT); out.put(content); int emittedSize = out.position() - off; assert emittedSize >= 0; if (emittedSize != expectedSize) { throw new IllegalStateException("For element " + e + ", expected size " + expectedSize + " but emitted size " + emittedSize); } } }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { // Calculate Section Count int sectSize = (int) alreadyDecided.get(sht).getDecidedValue(LayoutDecision.Kind.SIZE); hdr.setSectionCount(sectSize / IMAGE_SECTION_HEADER.totalsize); // Set offset of symbol table hdr.setSymbolOff((int) alreadyDecided.get(symtab).getDecidedValue(LayoutDecision.Kind.OFFSET)); // Set symbol table count hdr.setSymbolCount(symtab.getSymbolCount()); return hdr.getArray(); }
@SuppressWarnings("unchecked") public static <T> T defaultGetOrDecide(Map<Element, LayoutDecisionMap> alreadyDecided, Element el, LayoutDecision.Kind k, T hint) { /* By default, we return what's already been decided or else take the hint. */ LayoutDecisionMap m = alreadyDecided.get(el); if (m != null && m.getDecision(k) != null && m.getDecision(k).isTaken()) { return (T) m.getDecidedValue(k); } else { return hint; } }
@Override protected void writePayload(OutputAssembler out, Map<Element, LayoutDecisionMap> alreadyDecided) { out.write4Byte(0); // rebase off out.write4Byte(0); // rebase size out.write4Byte(0); // bind off out.write4Byte(0); // bind size out.write4Byte(0); // weak_bind off out.write4Byte(0); // weak_bind size out.write4Byte(0); // lazy_bind off out.write4Byte(0); // lazy_bind size out.write4Byte((int) alreadyDecided.get(export).getDecidedValue(LayoutDecision.Kind.OFFSET)); out.write4Byte((int) alreadyDecided.get(export).getDecidedValue(LayoutDecision.Kind.SIZE)); }
@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(); } }
protected static int nextAvailableVaddr(final Map<Element, LayoutDecisionMap> alreadyDecided, int base, int defaultValue) { int nextAvailable = -1; List<LayoutDecision> maxVaddrDecisions = maximalDecisionValues(alreadyDecided, LayoutDecision.Kind.VADDR, new IntegerDecisionComparator(false)); // break ties using size (nulls to head) Collections.sort(maxVaddrDecisions, new SizeTiebreakComparator(alreadyDecided, false)); // we sorted into ascending size order, so get the biggest LayoutDecision maxVaddrDecision = maxVaddrDecisions.get(maxVaddrDecisions.size() - 1); if (maxVaddrDecision == null || !maxVaddrDecision.isTaken()) { /* * This means we have not decided any vaddr yet. We use the caller-supplied default * value. */ nextAvailable = defaultValue; } else { assert alreadyDecided.get(maxVaddrDecision.getElement()).getDecision(LayoutDecision.Kind.SIZE).isTaken(); int vaddr = (int) alreadyDecided.get(maxVaddrDecision.getElement()).getDecidedValue(LayoutDecision.Kind.VADDR); int size = maxVaddrDecision.getElement().getMemSize(alreadyDecided); nextAvailable = vaddr + size; } if (nextAvailable < base) { return base; } else { return nextAvailable; } }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { /* We blat out our list of relocation records. */ OutputAssembler oa = AssemblyBuffer.createOutputAssembler(ByteBuffer.allocate(entries.size() * new EntryStruct().getWrittenSize()).order(getOwner().getByteOrder())); for (Entry ent : entries.keySet()) { long offset = !isDynamic() ? ent.offset : (int) alreadyDecided.get(ent.section).getDecidedValue(LayoutDecision.Kind.VADDR) + ent.offset; long info; int symIndex = syms.indexOf(ent.sym); assert symIndex >= 0 : "symbol not found"; switch (getOwner().getFileClass()) { case ELFCLASS32: info = ((symIndex << 8) & 0xffffffffL) + (ent.t.toLong() & 0xffL); break; case ELFCLASS64: info = (((long) symIndex) << 32) + (ent.t.toLong() & 0xffffffffL); break; default: throw new RuntimeException(getOwner().getFileClass().toString()); } long addend = ent.addend; new EntryStruct(offset, info, addend).write(oa); } return oa.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(); }
@Override public int getOrDecideVaddr(Map<Element, LayoutDecisionMap> alreadyDecided, int vaddrHint) { /* * We have to be careful about our vaddr. If we're the first section in the text segment, we * should have vaddr at least 4096. Why? to reproduce what the native tools do. */ int implVaddr = impl.getOrDecideVaddr(alreadyDecided, vaddrHint); // we should already have decided our file offset Object offsetObj = alreadyDecided.get(this).getDecidedValue(LayoutDecision.Kind.OFFSET); assert offsetObj != null; assert offsetObj instanceof Integer; // test for the special case if (getSegment() == getOwner().getSegments().iterator().next() && getSegment().get(0) == this) { if (implVaddr < getOwner().getPageSize()) { // choose the next congruent return ObjectFile.nextIntegerMultipleWithCongruence(getOwner().getPageSize(), impl.getAlignment(), (int) offsetObj, getOwner().getPageSize()); } } return implVaddr; }
@Override public byte[] getOrDecideContent(Map<Element, LayoutDecisionMap> alreadyDecided, byte[] contentHint) { byte[] strtabContent = (byte[]) alreadyDecided.get(strtab).getDecidedValue(LayoutDecision.Kind.CONTENT); StringTable table = new StringTable(ByteBuffer.wrap(strtabContent).order(getOwner().getByteOrder())); ByteBuffer outBuffer = ByteBuffer.allocate(getWrittenSize()).order(getOwner().getByteOrder()); s.value = isDynamic() ? ((int) alreadyDecided.get(e.getReferencedSection()).getDecidedValue(LayoutDecision.Kind.VADDR) + e.value) : e.value;
@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(); }
Section s = sym.getDefinedSection(); assert s != null; int sectionOffset = (int) alreadyDecided.get(s).getDecidedValue(LayoutDecision.Kind.OFFSET); fileOffsets.add(sectionOffset + (int) sym.getDefinedOffset());
@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(); }