public String getFilenameSuffix() { if (executable) { return ObjectFile.getNativeFormat() == ObjectFile.Format.PECOFF ? ".exe" : ""; } return ""; }
public static ObjectFile createRuntimeDebugInfo() { return getNativeObjectFile(true); }
public int roundUpToPageSize(int x) { int pageShift = getPageSizeShift(); if (x % getPageSize() == 0) { return x; } else { return ((x >> pageShift) + 1) << pageShift; } }
public Section newProgbitsSection(String name, int alignment, boolean writable, boolean executable, ProgbitsSectionImpl impl) { assert impl != null; final Segment segment = getOrCreateSegment(null, name, writable, executable); final int adaptedAlignment = lowestCommonMultiple(alignment, getWordSizeInBytes()); final Section result = newProgbitsSection(segment, name, adaptedAlignment, writable, executable, impl); return result; }
public Section newUserDefinedSection(String name, ElementImpl impl) { final Segment segment = getOrCreateSegment(null, name, false, false); final int alignment = getWordSizeInBytes(); final Section result = newUserDefinedSection(segment, name, alignment, impl); return result; }
public NativeBootImage(NativeImageKind k, HostedUniverse universe, HostedMetaAccess metaAccess, NativeLibraries nativeLibs, NativeImageHeap heap, NativeImageCodeCache codeCache, List<HostedMethod> entryPoints, HostedMethod mainEntryPoint, ClassLoader imageClassLoader) { super(k, universe, metaAccess, nativeLibs, heap, codeCache, entryPoints, imageClassLoader); uniqueEntryPoints.addAll(entryPoints); if (NativeImageOptions.MachODebugInfoTesting.getValue()) { objectFile = new MachOObjectFile(); } else { objectFile = ObjectFile.getNativeObjectFile(); if (objectFile == null) { throw new Error("Unsupported objectfile format: " + ObjectFile.getNativeFormat()); } } if (mainEntryPoint != null) { objectFile.setMainEntryPoint(globalSymbolNameForMethod(mainEntryPoint)); } objectFile.setByteOrder(ConfigurationValues.getTarget().arch.getByteOrder()); int pageSize = NativeImageOptions.PageSize.getValue(); if (pageSize > 0) { objectFile.setPageSize(pageSize); } wordSize = FrameAccess.wordSize(); assert objectFile.getWordSizeInBytes() == wordSize; }
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(); List<LayoutDecision> sortedOffsetDecisions = sortedDecisionValues(alreadyDecided, LayoutDecision.Kind.OFFSET, new IntegerDecisionComparator(true)); 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(); int vaddr = !requireModuloConstraint ? nextIntegerMultiple(nextAvailableVaddr, el.getAlignment()) : ObjectFile.nextIntegerMultipleWithCongruence(nextAvailableVaddr, el.getAlignment(), fileOffset % el.getOwner().getPageSize(), el.getOwner().getPageSize()); nextAvailableVaddr = vaddr + el.getMemSize(alreadyDecided);
heap.alignRelocatablePartition(objectFile.getPageSize()); 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()); textSection = objectFile.newProgbitsSection(textSectionName, objectFile.getPageSize(), false, true, textImpl); final RelocatableBuffer roDataBuffer = RelocatableBuffer.factory("roData", roSectionSize, objectFile.getByteOrder()); final ProgbitsSectionImpl roDataImpl = new BasicProgbitsSectionImpl(roDataBuffer.getBytes()); final String roDataSectionName = SectionName.RODATA.getFormatDependentName(objectFile.getFormat()); roDataSection = objectFile.newProgbitsSection(roDataSectionName, objectFile.getPageSize(), false, false, roDataImpl); final RelocatableBuffer rwDataBuffer = RelocatableBuffer.factory("rwData", rwSectionSize, objectFile.getByteOrder()); final ProgbitsSectionImpl rwDataImpl = new BasicProgbitsSectionImpl(rwDataBuffer.getBytes()); final String rwDataSectionName = SectionName.DATA.getFormatDependentName(objectFile.getFormat()); rwDataSection = objectFile.newProgbitsSection(rwDataSectionName, objectFile.getPageSize(), true, false, rwDataImpl); objectFile.createDefinedSymbol(textSection.getName(), textSection, 0, 0, false, false); objectFile.createDefinedSymbol("__svm_text_end", textSection, textSectionSize, 0, false, true); objectFile.createDefinedSymbol(roDataSection.getName(), roDataSection, 0, 0, false, false); objectFile.createDefinedSymbol(rwDataSection.getName(), rwDataSection, 0, 0, false, false); heapSectionBuffer = RelocatableBuffer.factory("heap", heapSize, objectFile.getByteOrder()); heapSectionImpl = new BasicProgbitsSectionImpl(heapSectionBuffer.getBytes()); final String heapSectionName = SectionName.SVM_HEAP.getFormatDependentName(objectFile.getFormat()); heapSection = objectFile.newProgbitsSection(heapSectionName, objectFile.getPageSize(), writable, false, heapSectionImpl); objectFile.createDefinedSymbol(heapSection.getName(), heapSection, 0, 0, false, true);
@Override public Iterable<BuildDependency> getDependencies(Map<Element, LayoutDecisionMap> decisions) { HashSet<BuildDependency> deps = ObjectFile.minimalDependencies(decisions, this); return deps; }
@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); }
protected final void write(Path outputFile) { try { Files.createDirectories(outputFile.normalize().getParent()); FileChannel channel = FileChannel.open(outputFile, StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); objectFile.write(channel); } catch (Exception ex) { throw shouldNotReachHere(ex); } resultingImageSize = (int) outputFile.toFile().length(); if (NativeImageOptions.PrintImageElementSizes.getValue()) { for (Element e : objectFile.getElements()) { System.out.printf("PrintImageElementSizes: size: %15d name: %s\n", e.getMemSize(objectFile.getDecisionsByElement()), e.getElementName()); } } }
protected Iterable<Element> elementsMappedOnPage(long vaddr, Map<Element, LayoutDecisionMap> alreadyDecided) { final long vaddrRoundedDown = (vaddr >> getPageSizeShift()) << getPageSizeShift(); // FIXME: use FilteringIterator instead of copying ArrayList<Element> ss = new ArrayList<>(); for (LayoutDecision d : decisionsByKind(LayoutDecision.Kind.VADDR, alreadyDecided)) { Element s = d.getElement(); assert d.getKind() == LayoutDecision.Kind.VADDR; int va = (int) d.getValue(); int sizeInMemory = d.getElement().getMemSize(alreadyDecided); assert sizeInMemory != -1; // if it begins before the end of this page // and doesn't end before the start, // it overlaps the page. int mappingBegin = va; int mappingEnd = va + sizeInMemory; long pageBegin = vaddrRoundedDown; long pageEnd = vaddrRoundedDown + getPageSize(); if (mappingBegin < pageEnd && mappingEnd > pageBegin) { ss.add(s); } } return ss; }
@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(); }
public final SymbolTable getOrCreateSymbolTable() { SymbolTable t = getSymbolTable(); if (t != null) { return t; } else { return createSymbolTable(); } } }
@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(); }
sectionImpl.markRelocationSite(offset, info.getRelocationSize(), info.getRelocationKind(), rwDataSection.getName(), false, addend); if (dataInfo.isSymbolReference()) { // create relocation for referenced symbol if (objectFile.getSymbolTable().getSymbol(data.symbolName) == null) { objectFile.createUndefinedSymbol(data.symbolName, 0, true);
public int getPageSizeShift() { int pagesize = getPageSize(); int pageSizeShift = Integer.numberOfTrailingZeros(pagesize); return pageSizeShift; }
public final void write(FileChannel outputChannel) { List<Element> sortedObjectFileElements = new ArrayList<>(); int totalSize = bake(sortedObjectFileElements); try { ByteBuffer buffer = outputChannel.map(MapMode.READ_WRITE, 0, totalSize); writeBuffer(sortedObjectFileElements, buffer); outputChannel.close(); } catch (IOException e) { throw new RuntimeException(e); } }
@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; } } } }
@Override public int bake(List<Element> sortedObjectFileElements) { minimumFileSize = 0; // re-zero it for this write-out return super.bake(sortedObjectFileElements); }