package com.oracle.svm.hosted.image;
import java.nio.file.Path;
import java.util.List;
import org.graalvm.compiler.debug.DebugContext;
import com.oracle.objectfile.ObjectFile;
import com.oracle.svm.core.LinkerInvocation;
import com.oracle.svm.hosted.FeatureImpl.BeforeImageWriteAccessImpl;
import com.oracle.svm.hosted.c.NativeLibraries;
import com.oracle.svm.hosted.meta.HostedMetaAccess;
import com.oracle.svm.hosted.meta.HostedMethod;
import com.oracle.svm.hosted.meta.HostedUniverse;
public abstract class AbstractBootImage {
protected final HostedMetaAccess metaAccess;
protected final HostedUniverse universe;
protected final NativeLibraries nativeLibs;
protected final NativeImageHeap heap;
protected final ClassLoader imageClassLoader;
protected final NativeImageCodeCache codeCache;
protected final List<HostedMethod> entryPoints;
protected int resultingImageSize;
public enum NativeImageKind {
SHARED_LIBRARY(false) {
@Override
public String getFilenameSuffix() {
switch (ObjectFile.getNativeFormat()) {
case ELF:
return ".so";
case MACH_O:
return ".dylib";
case PECOFF:
return ".dll";
default:
throw new AssertionError("unreachable");
}
}
@Override
public String getFilenamePrefix() {
return ObjectFile.getNativeFormat() == ObjectFile.Format.PECOFF ? "" : "lib";
}
},
EXECUTABLE(true),
STATIC_EXECUTABLE(true);
public final boolean isExecutable;
public final String mainEntryPointName;
NativeImageKind(boolean executable) {
isExecutable = executable;
mainEntryPointName = executable ? "main" : "run_main";
}
public String getFilenameSuffix() {
return ObjectFile.getNativeFormat() == ObjectFile.Format.PECOFF ? ".exe" : "";
}
public String getFilenamePrefix() {
return "";
}
public String getFilename(String basename) {
return getFilenamePrefix() + basename + getFilenameSuffix();
}
}
protected final NativeImageKind kind;
protected AbstractBootImage(NativeImageKind k, HostedUniverse universe, HostedMetaAccess metaAccess, NativeLibraries nativeLibs, NativeImageHeap heap, NativeImageCodeCache codeCache,
List<HostedMethod> entryPoints, ClassLoader imageClassLoader) {
this.kind = k;
this.universe = universe;
this.metaAccess = metaAccess;
this.nativeLibs = nativeLibs;
this.heap = heap;
this.codeCache = codeCache;
this.entryPoints = entryPoints;
this.imageClassLoader = imageClassLoader;
}
public NativeImageKind getBootImageKind() {
return kind;
}
public int getImageSize() {
return resultingImageSize;
}
public NativeLibraries getNativeLibs() {
return nativeLibs;
}
public abstract void build(DebugContext debug);
public abstract LinkerInvocation write(DebugContext debug, Path outputDirectory, Path tempDirectory, String imageName, BeforeImageWriteAccessImpl config);
public abstract ObjectFile.Section getTextSection();
public static AbstractBootImage create(NativeImageKind k, HostedUniverse universe, HostedMetaAccess metaAccess, NativeLibraries nativeLibs, NativeImageHeap heap,
NativeImageCodeCache codeCache, List<HostedMethod> entryPoints, ClassLoader classLoader) {
switch (k) {
case SHARED_LIBRARY:
return new SharedLibraryViaCCBootImage(universe, metaAccess, nativeLibs, heap, codeCache, entryPoints, classLoader);
default:
return new ExecutableViaCCBootImage(k, universe, metaAccess, nativeLibs, heap, codeCache, entryPoints, classLoader);
}
}
public abstract String[] makeLaunchCommand(AbstractBootImage.NativeImageKind k, String imageName, Path binPath, Path workPath, java.lang.reflect.Method method);
public NativeImageCodeCache getCodeCache() {
return codeCache;
}
public NativeImageHeap getHeap() {
return heap;
}
public abstract ObjectFile getOrCreateDebugObjectFile();
public boolean requiresCustomDebugRelocation() {
return false;
}
public AbstractBootImage.NativeImageKind getKind() {
return kind;
}
}