void writeHeaderFiles(Path outputDir, String imageName, boolean dynamic) { /* Group methods by header files. */ Map<? extends Class<? extends Header>, List<HostedMethod>> hostedMethods = uniqueEntryPoints.stream() .filter(this::shouldWriteHeader) .map(m -> Pair.create(cHeader(m), m)) .collect(Collectors.groupingBy(Pair::getLeft, Collectors.mapping(Pair::getRight, Collectors.toList()))); hostedMethods.forEach((headerClass, methods) -> { methods.sort(NativeBootImage::sortMethodsByFileNameAndPosition); Header header = headerClass == Header.class ? defaultCHeaderAnnotation(imageName) : instantiateCHeader(headerClass); writeHeaderFile(outputDir, header, methods, dynamic); }); }
private void markRelocationSitesFromMaps(RelocatableBuffer relocationMap, ProgbitsSectionImpl sectionImpl, Map<Object, NativeImageHeap.ObjectInfo> objectMap) { // Create relocation records from a map. // TODO: Should this be a visitor to the map entries, // TODO: so I don't have to expose the entrySet() method? for (Map.Entry<Integer, RelocatableBuffer.Info> entry : relocationMap.entrySet()) { final int offset = entry.getKey(); final RelocatableBuffer.Info info = entry.getValue(); assert checkEmbeddedOffset(sectionImpl, offset, info); // Figure out what kind of relocation site it is. if (info.getTargetObject() instanceof CFunctionPointer) { // References to functions are via relocations to the symbol for the function. markFunctionRelocationSite(sectionImpl, offset, info); } else { // A data relocation. if (sectionImpl.getElement() == textSection) { // A wrinkle on relocations *from* the text section: they are *always* to // constants (in the "constant partition" of the roDataSection). markDataRelocationSiteFromText(relocationMap, sectionImpl, offset, info, objectMap); } else { // Relocations from other sections go to the section containing the target. // Pass along the information about the target. final Object targetObject = info.getTargetObject(); final NativeImageHeap.ObjectInfo targetObjectInfo = objectMap.get(targetObject); markDataRelocationSite(sectionImpl, offset, info, targetObjectInfo); } } } }
public static CEntryPointData create(ResolvedJavaMethod method, String name, Class<? extends Function<String, String>> nameTransformation, String documentation, Class<?> prologue, Class<?> epilogue, Class<?> exceptionHandler, Publish publishAs) { return create(name, () -> NativeBootImage.globalSymbolNameForMethod(method), nameTransformation, documentation, Builtin.NO_BUILTIN, prologue, epilogue, exceptionHandler, publishAs); }
long writableSectionOffset = heap.getReadOnlySectionSize(); heap.setWritableSection(heapSection.getName(), writableSectionOffset); defineDataSymbol(Isolates.IMAGE_HEAP_BEGIN_SYMBOL_NAME, heapSection, 0); defineDataSymbol(Isolates.IMAGE_HEAP_END_SYMBOL_NAME, heapSection, heapSize); defineDataSymbol(Isolates.IMAGE_HEAP_WRITABLE_BEGIN_SYMBOL_NAME, heapSection, writableSectionOffset); defineDataSymbol(Isolates.IMAGE_HEAP_WRITABLE_END_SYMBOL_NAME, heapSection, writableSectionOffset + heap.getWritableSectionSize()); defineDataSymbol(Isolates.IMAGE_HEAP_RELOCATABLE_BEGIN_SYMBOL_NAME, heapSection, relocatableOffset); defineDataSymbol(Isolates.IMAGE_HEAP_RELOCATABLE_END_SYMBOL_NAME, heapSection, relocatableOffset + relocatableSize); } else { heapSectionBuffer = null; cGlobals.writeData(rwDataBuffer, (offset, symbolName) -> defineDataSymbol(symbolName, rwDataSection, offset + RWDATA_CGLOBALS_PARTITION_OFFSET)); defineDataSymbol(CGlobalDataInfo.CGLOBALDATA_BASE_SYMBOL_NAME, rwDataSection, RWDATA_CGLOBALS_PARTITION_OFFSET); defineDataSymbol(Isolates.IMAGE_HEAP_RELOCATABLE_FIRST_RELOC_POINTER_NAME, heapSection, firstRelocOffset); assert castToByteBuffer(heapSectionBuffer).getLong((int) firstRelocOffset) == 0; } else { assert heapSectionBuffer == null; markRelocationSitesFromMaps(textBuffer, textImpl, heap.objects); markRelocationSitesFromMaps(roDataBuffer, roDataImpl, heap.objects); markRelocationSitesFromMaps(rwDataBuffer, rwDataImpl, heap.objects); if (heapSectionBuffer != null) { markRelocationSitesFromMaps(heapSectionBuffer, heapSectionImpl, heap.objects);
final String symName = localSymbolNameForMethod(ent.getKey()); final String signatureString = SubstrateUtil.uniqueShortName(ent.getKey()); final HostedMethod existing = methodsBySignature.get(signatureString); if (entryPointIndex != -1) { final String mangledSignature = mangleName(ent.getKey()); assert mangledSignature.equals(globalSymbolNameForMethod(method)); defineMethodSymbol(mangledSignature, textSection, method, null);
private static void markFunctionRelocationSite(final ProgbitsSectionImpl sectionImpl, final int offset, final RelocatableBuffer.Info info) { assert info.getTargetObject() instanceof CFunctionPointer : "Wrong type for FunctionPointer relocation: " + info.getTargetObject().toString(); final int functionPointerRelocationSize = 8; assert info.getRelocationSize() == functionPointerRelocationSize : "Function relocation: " + info.getRelocationSize() + " should be " + functionPointerRelocationSize + " bytes."; // References to functions are via relocations to the symbol for the function. ResolvedJavaMethod method = ((MethodPointer) info.getTargetObject()).getMethod(); // A reference to a method. Mark the relocation site using the symbol name. sectionImpl.markRelocationSite(offset, functionPointerRelocationSize, RelocationKind.DIRECT, localSymbolNameForMethod(method), false, 0L); }
public static CEntryPointData create(Method method) { return create(method.getAnnotation(CEntryPoint.class), method.getAnnotation(CEntryPointOptions.class), () -> NativeBootImage.globalSymbolNameForMethod(method)); }
public static CEntryPointData create(Method method, String name, Class<? extends Function<String, String>> nameTransformation, String documentation, Class<?> prologue, Class<?> epilogue, Class<?> exceptionHandler, Publish publishAs) { return create(name, () -> NativeBootImage.globalSymbolNameForMethod(method), nameTransformation, documentation, Builtin.NO_BUILTIN, prologue, epilogue, exceptionHandler, publishAs); }
public static CEntryPointData create(ResolvedJavaMethod method) { return create(method.getAnnotation(CEntryPoint.class), method.getAnnotation(CEntryPointOptions.class), () -> NativeBootImage.globalSymbolNameForMethod(method)); }
@Override LinkerInvocation getLinkerInvocation(Path outputDirectory, Path tempDirectory, String imageName) { String mainSymbolNameStem = NativeBootImage.globalSymbolNameForMethod(mainEntryPoint); // HACK: guess main symbol name using hacked-up knowledge of object file format String mainSymbolAlias = (ObjectFile.getNativeFormat() == ObjectFile.Format.MACH_O) ? "_main" : "main"; String mainSymbolName = (ObjectFile.getNativeFormat() == ObjectFile.Format.MACH_O) ? "_" + mainSymbolNameStem : mainSymbolNameStem; LinkerInvocation inv = super.getLinkerInvocation(outputDirectory, tempDirectory, imageName); inv.addSymbolAlias(mainSymbolAlias, mainSymbolName); return inv; } }
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; }