Add "_main" as alias to "Konan_main" via LLVMAddAlias

This commit is contained in:
Sergey Bogolepov
2019-08-28 19:51:57 +07:00
committed by Sergey Bogolepov
parent 8e0e346492
commit 7844dc5228
6 changed files with 29 additions and 132 deletions
@@ -205,7 +205,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
put(FRAMEWORK_IMPORT_HEADERS, arguments.frameworkImportHeaders.toNonNullList())
arguments.emitLazyObjCHeader?.let { put(EMIT_LAZY_OBJC_HEADER_FILE, it) }
put(BITCODE_EMBEDDING_MODE, selectBitcodeEmbeddingMode(this, arguments, outputKind))
put(BITCODE_EMBEDDING_MODE, selectBitcodeEmbeddingMode(this, arguments))
put(DEBUG_INFO_VERSION, arguments.debugInfoFormatVersion.toInt())
put(COVERAGE, arguments.coverage)
put(LIBRARIES_TO_COVER, arguments.coveredLibraries.toNonNullList())
@@ -247,41 +247,21 @@ private fun selectFrameworkType(
private fun selectBitcodeEmbeddingMode(
configuration: CompilerConfiguration,
arguments: K2NativeCompilerArguments,
outputKind: CompilerOutputKind
): BitcodeEmbedding.Mode {
if (outputKind != CompilerOutputKind.FRAMEWORK) {
return BitcodeEmbedding.Mode.NONE.also {
val flag = when {
arguments.embedBitcodeMarker -> EMBED_BITCODE_MARKER_FLAG
arguments.embedBitcode -> EMBED_BITCODE_FLAG
else -> return@also
}
arguments: K2NativeCompilerArguments
): BitcodeEmbedding.Mode = when {
arguments.embedBitcodeMarker -> {
if (arguments.embedBitcode) {
configuration.report(
STRONG_WARNING,
"'$flag' is only supported when producing frameworks, " +
"but the compiler is producing ${outputKind.name.toLowerCase()}"
"'$EMBED_BITCODE_FLAG' is ignored because '$EMBED_BITCODE_MARKER_FLAG' is specified"
)
}
BitcodeEmbedding.Mode.MARKER
}
return when {
arguments.embedBitcodeMarker -> {
if (arguments.embedBitcode) {
configuration.report(
STRONG_WARNING,
"'$EMBED_BITCODE_FLAG' is ignored because '$EMBED_BITCODE_MARKER_FLAG' is specified"
)
}
BitcodeEmbedding.Mode.MARKER
}
arguments.embedBitcode -> {
BitcodeEmbedding.Mode.FULL
}
else -> BitcodeEmbedding.Mode.NONE
arguments.embedBitcode -> {
BitcodeEmbedding.Mode.FULL
}
else -> BitcodeEmbedding.Mode.NONE
}
private fun selectExportedLibraries(
@@ -1,9 +1,5 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.llvm.Int8
import org.jetbrains.kotlin.backend.konan.llvm.Llvm
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
object BitcodeEmbedding {
enum class Mode {
@@ -17,31 +13,10 @@ object BitcodeEmbedding {
}
internal fun getClangOptions(config: KonanConfig): List<String> = when (config.bitcodeEmbeddingMode) {
BitcodeEmbedding.Mode.NONE -> listOf("-fembed-bitcode=off")
BitcodeEmbedding.Mode.MARKER -> listOf("-fembed-bitcode=marker")
BitcodeEmbedding.Mode.FULL -> listOf("-fembed-bitcode=all")
Mode.NONE -> listOf("-fembed-bitcode=off")
Mode.MARKER -> listOf("-fembed-bitcode=marker")
Mode.FULL -> listOf("-fembed-bitcode=all")
}
private val KonanConfig.bitcodeEmbeddingMode get() = configuration.get(KonanConfigKeys.BITCODE_EMBEDDING_MODE)!!.also {
require(it == Mode.NONE || this.produce == CompilerOutputKind.FRAMEWORK) {
"${it.name.toLowerCase()} bitcode embedding mode is not supported when producing ${this.produce.name.toLowerCase()}"
}
}
internal fun processModule(llvm: Llvm) = when (llvm.context.config.bitcodeEmbeddingMode) {
Mode.NONE -> {}
Mode.MARKER -> {
addEmptyMarker(llvm, "konan_llvm_bitcode", "__LLVM,__bitcode")
addEmptyMarker(llvm, "konan_llvm_cmdline", "__LLVM,__cmdline")
}
Mode.FULL -> {
addEmptyMarker(llvm, "konan_llvm_asm", "__LLVM,__asm")
}
}
private fun addEmptyMarker(llvm: Llvm, name: String, section: String) {
val global = llvm.staticData.placeGlobal(name, Int8(0), isExported = false)
global.setSection(section)
llvm.usedGlobals += global.llvmGlobal
}
private val KonanConfig.bitcodeEmbeddingMode get() = configuration.get(KonanConfigKeys.BITCODE_EMBEDDING_MODE)!!
}
@@ -4,9 +4,7 @@
*/
package org.jetbrains.kotlin.backend.konan
import llvm.LLVMLinkModules2
import llvm.LLVMModuleRef
import llvm.LLVMWriteBitcodeToFile
import llvm.*
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.backend.konan.llvm.Llvm
@@ -57,6 +55,16 @@ private fun runLlvmPipeline(context: Context) = when {
else -> {}
}
private fun insertAliasToEntryPoint(context: Context) {
val nomain = context.config.configuration.get(KonanConfigKeys.NOMAIN) ?: false
if (context.config.produce != CompilerOutputKind.PROGRAM || nomain)
return
val module = context.llvmModule
val entryPoint = LLVMGetNamedFunction(module, "Konan_main")
?: error("Module doesn't contain `Konan_main`")
LLVMAddAlias(module, LLVMTypeOf(entryPoint)!!, entryPoint, "main")
}
internal fun produceOutput(context: Context) {
val config = context.config.configuration
@@ -83,6 +91,9 @@ internal fun produceOutput(context: Context) {
}
linkAllDependecies(context, generatedBitcodeFiles)
runLlvmPipeline(context)
// Insert `_main` after pipeline so we won't worry about optimizations
// corrupting entry point.
insertAliasToEntryPoint(context)
LLVMWriteBitcodeToFile(context.llvmModule!!, output)
}
CompilerOutputKind.LIBRARY -> {
@@ -24,22 +24,11 @@ internal class Linker(val context: Context) {
private val platform = context.config.platform
private val config = context.config.configuration
private val linkerOutput = determineLinkerOutput(context)
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
private val linker = platform.linker
private val target = context.config.target
private val optimize = context.shouldOptimize()
private val debug = context.config.debug || context.config.lightDebug
// Ideally we'd want to have
// #pragma weak main = Konan_main
// in the launcher.cpp.
// Unfortunately, anything related to weak linking on MacOS
// only seems to be working with dynamic libraries.
// So we stick to "-alias _main _konan_main" on Mac.
// And just do the same on Linux.
private val entryPointSelector: List<String>
get() = if (nomain || linkerOutput != LinkerOutputKind.EXECUTABLE) emptyList() else platform.entrySelector
fun link(objectFiles: List<ObjectFile>) {
val nativeDependencies = context.llvm.nativeDependenciesToLink
val includedBinaries = nativeDependencies.map { it.includedPaths }.flatten()
@@ -91,8 +80,7 @@ internal class Linker(val context: Context) {
File(executable).delete()
linker.linkCommands(objectFiles = objectFiles, executable = executable,
libraries = linker.linkStaticLibraries(includedBinaries) + context.config.defaultSystemLibraries,
linkerArgs = entryPointSelector +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
linkerArgs = asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
BitcodeEmbedding.getLinkerOptions(context.config) +
libraryProvidedLinkerFlags + frameworkLinkerArgs,
optimize = optimize, debug = debug, kind = linkerOutput,
@@ -308,7 +308,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
if (context.isNativeLibrary) {
appendCAdapters()
}
}
//-------------------------------------------------------------------------//
@@ -2246,47 +2245,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
llvmDebugSelector.setLinkage(LLVMLinkage.LLVMExternalLinkage)
}
//-------------------------------------------------------------------------//
private fun entryPointSelector(entryPoint: LLVMValueRef,
entryPointType: LLVMTypeRef, selectorName: String, argCount: Int): LLVMValueRef {
assert(LLVMCountParams(entryPoint) <= 1)
val selector = LLVMAddFunction(context.llvmModule, selectorName, entryPointType)!!
generateFunction(codegen, selector) {
// Note, that 'parameter' is an object reference, and as such, shall
// be accounted for in the rootset. However, current object management
// scheme for arguments guarantees, that reference is being held in C++
// launcher, so we could optimize out creating slot for 'parameter' in
// this function.
val parameters = if (argCount == 1)
listOf(LLVMGetParam(selector, 0)!!)
else
emptyList()
call(entryPoint, parameters, Lifetime.IRRELEVANT, ExceptionHandler.Caller)
ret(null)
}
return selector
}
//-------------------------------------------------------------------------//
private fun appendEntryPointSelector(function: IrFunction?) {
if (function == null) return
val entryPoint = codegen.llvmFunction(function)
val selectorName = "EntryPointSelector"
val entryPointType = getFunctionType(entryPoint)
val argCount = function.valueParameters.size
assert(argCount <= 1)
val selector = entryPointSelector(entryPoint, entryPointType, selectorName, argCount)
LLVMSetLinkage(selector, LLVMLinkage.LLVMExternalLinkage)
}
//-------------------------------------------------------------------------//
// Create type { i32, void ()*, i8* }
-15
View File
@@ -58,7 +58,6 @@ linkerDynamicFlags.macos_x64 = -dylib
osVersionMinFlagLd.macos_x64 = -macosx_version_min
osVersionMinFlagClang.macos_x64 = -mmacosx-version-min
osVersionMin.macos_x64 = 10.11
entrySelector.macos_x64 = -alias _Konan_main _main
dependencies.macos_x64 = \
libffi-3.2.1-3-darwin-macos \
lldb-1-macos \
@@ -84,7 +83,6 @@ target-sysroot-9-ios_arm32.default = \
remote:internal
arch.ios_arm32 = armv7
entrySelector.ios_arm32 = -alias _Konan_main _main
# Shared with 64-bit version.
targetSysRoot.ios_arm32 = target-sysroot-9-ios_arm64
@@ -111,7 +109,6 @@ target-sysroot-9-ios_arm64.default = \
remote:internal
arch.ios_arm64 = arm64
entrySelector.ios_arm64 = -alias _Konan_main _main
targetSysRoot.ios_arm64 = target-sysroot-9-ios_arm64
clangFlags.ios_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir
@@ -138,7 +135,6 @@ target-sysroot-9-ios_x64.default = \
remote:internal
arch.ios_x64 = x86_64
entrySelector.ios_x64 = -alias _Konan_main _main
targetSysRoot.ios_x64 = target-sysroot-9-ios_x64
clangFlags.ios_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir
@@ -197,7 +193,6 @@ linkerNoDebugFlags.linux_x64 = -S
linkerDynamicFlags.linux_x64 = -shared
pluginOptimizationFlags.linux_x64 = -plugin-opt=target-cpu x86-64 -plugin-opt=O3
dynamicLinker.linux_x64 = /lib64/ld-linux-x86-64.so.2
entrySelector.linux_x64 = --defsym main=Konan_main
# targetSysRoot relative
abiSpecificLibraries.linux_x64 = ../lib64 lib64 usr/lib64
@@ -222,7 +217,6 @@ dependencies.macos_x64-linux_arm32_hfp = \
target-sysroot-2-raspberrypi
quadruple.linux_arm32_hfp = armv6-unknown-linux-gnueabihf
entrySelector.linux_arm32_hfp = --defsym main=Konan_main
linkerNoDebugFlags.linux_arm32_hfp = -S
linkerDynamicFlags.linux_arm32_hfp = -shared
linkerOptimizationFlags.linux_arm32_hfp = --gc-sections
@@ -265,7 +259,6 @@ dependencies.macos_x64-linux_arm64 = \
target-sysroot-1-linux-glibc-arm64
quadruple.linux_arm64 = aarch64-unknown-linux-gnu
entrySelector.linux_arm64 = --defsym main=Konan_main
linkerNoDebugFlags.linux_arm64 = -S
linkerDynamicFlags.linux_arm64 = -shared
linkerOptimizationFlags.linux_arm64 = --gc-sections
@@ -297,7 +290,6 @@ dependencies.linux_x64-linux_mips32 = \
libffi-3.2.1-2-linux-x86-64
quadruple.linux_mips32 = mips-unknown-linux-gnu
entrySelector.linux_mips32 = --defsym main=Konan_main
linkerOptimizationFlags.linux_mips32 = --gc-sections
linkerDynamicFlags.linux_mips32 = -shared
targetSysRoot.linux_mips32 = target-sysroot-2-mips
@@ -324,7 +316,6 @@ dependencies.linux_x64-linux_mipsel32 = \
target-sysroot-2-mipsel \
libffi-3.2.1-2-linux-x86-64
quadruple.linux_mipsel32 = mipsel-unknown-linux-gnu
entrySelector.linux_mipsel32 = --defsym main=Konan_main
linkerOptimizationFlags.linux_mipsel32 = --gc-sections
linkerDynamicFlags.linux_mipsel32 = -shared
targetSysRoot.linux_mipsel32 = target-sysroot-2-mipsel
@@ -363,7 +354,6 @@ dependencies.mingw_x64-android_arm32 = \
libffi-3.2.1-mingw-w64-x86-64
quadruple.android_arm32 = arm-linux-androideabi
entrySelector.android_arm32 = -Wl,--defsym -Wl,main=Konan_main
clangFlags.android_arm32 = -cc1 -target-cpu arm7tdmi -emit-obj -disable-llvm-optzns -x ir -femulated-tls -mrelocation-model pic
clangOptFlags.android_arm32 = -O3 -ffunction-sections
linkerNoDebugFlags.android_arm32 = -Wl,-S
@@ -392,7 +382,6 @@ dependencies.mingw_x64-android_arm64 = \
libffi-3.2.1-mingw-w64-x86-64
quadruple.android_arm64 = aarch64-linux-android
entrySelector.android_arm64 = -Wl,--defsym -Wl,main=Konan_main
clangFlags.android_arm64 = -cc1 -target-cpu cortex-a57 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic
clangOptFlags.android_arm64 = -O3 -ffunction-sections
clangNooptFlags.android_arm64 = -O1
@@ -421,7 +410,6 @@ dependencies.mingw_x64-android_x86 = \
libffi-3.2.1-mingw-w64-x86-64
quadruple.android_x86 = i686-linux-android
entrySelector.android_x86 = -Wl,--defsym -Wl,main=Konan_main
clangFlags.android_x86 = -cc1 -target-cpu i686 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic
clangOptFlags.android_x86 = -O3 -ffunction-sections
clangNooptFlags.android_x86 = -O1
@@ -450,7 +438,6 @@ dependencies.mingw_x64-android_x64 = \
libffi-3.2.1-mingw-w64-x86-64
quadruple.android_x64 = x86_64-linux-android
entrySelector.android_x64 = -Wl,--defsym -Wl,main=Konan_main
clangFlags.android_x64 = -cc1 -target-cpu x86-64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic
clangOptFlags.android_x64 = -O3 -ffunction-sections
clangNooptFlags.android_x64 = -O1
@@ -494,7 +481,6 @@ linkerKonanFlags.mingw_x64 =-static-libgcc -static-libstdc++ \
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \
-Wl,--defsym,__cxa_demangle=Konan_cxa_demangle
linkerOptimizationFlags.mingw_x64 = -Wl,--gc-sections
entrySelector.mingw_x64 = -Wl,--defsym,main=Konan_main
# Windows i686, based on mingw-w64.
targetToolchain.mingw_x64-mingw_x86 = msys2-mingw-w64-i686-gcc-7.4.0-clang-llvm-6.0.1
@@ -532,7 +518,6 @@ linkerKonanFlags.mingw_x86 = -static-libgcc -static-libstdc++ \
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \
-Wl,--defsym,___cxa_demangle=_Konan_cxa_demangle
linkerOptimizationFlags.mingw_x86 = -Wl,--gc-sections
entrySelector.mingw_x86 = -Wl,--defsym,_main=_Konan_main
# WebAssembly 32-bit.
targetToolchain.macos_x64-wasm32 = target-toolchain-3-macos-wasm