Properly handle TLS for -produce dynamic.

In additon, changed konan.properties linkerDebugFlags to linkerNoDebugFlags to reflect reality.
This commit is contained in:
Alexander Gorshenev
2017-12-10 23:10:20 +03:00
committed by alexander-gorshenev
parent 33fb54e7a9
commit bb47a28c15
5 changed files with 102 additions and 48 deletions
@@ -21,6 +21,8 @@ import java.lang.ProcessBuilder.Redirect
import org.jetbrains.kotlin.konan.file.*
import org.jetbrains.kotlin.konan.properties.*
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.backend.konan.util.listConstructor
import org.jetbrains.kotlin.backend.konan.util.If
typealias BitcodeFile = String
typealias ObjectFile = String
@@ -36,7 +38,7 @@ internal abstract class PlatformFlags(val properties: KonanProperties) {
val entrySelector = properties.entrySelector
val linkerOptimizationFlags = properties.linkerOptimizationFlags
val linkerKonanFlags = properties.linkerKonanFlags
val linkerDebugFlags = properties.linkerDebugFlags
val linkerNoDebugFlags = properties.linkerNoDebugFlags
val linkerDynamicFlags = properties.linkerDynamicFlags
val llvmDebugOptFlags = properties.llvmDebugOptFlags
val s2wasmFlags = properties.s2wasmFlags
@@ -89,7 +91,7 @@ internal open class AndroidPlatform(distribution: Distribution)
add("-llog")
addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags)
if (!debug) addAll(linkerNoDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags)
}
@@ -122,7 +124,7 @@ internal open class MacOSBasedPlatform(distribution: Distribution)
addAll(listOf("-syslibroot", targetSysRoot, "-o", executable))
addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags)
if (!debug) addAll(linkerNoDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags)
add("-lSystem")
@@ -134,7 +136,6 @@ internal open class MacOSBasedPlatform(distribution: Distribution)
open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> =
listOf(dsymutil, "-dump-debug-map" ,executable)
}
internal open class LinuxBasedPlatform(val distribution: Distribution)
: PlatformFlags(distribution.targetProperties) {
@@ -149,30 +150,46 @@ internal open class LinuxBasedPlatform(val distribution: Distribution)
= binaries.filter { it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
val isMips = (distribution.target == KonanTarget.LINUX_MIPS32 ||
distribution.target == KonanTarget.LINUX_MIPSEL32)
// TODO: Can we extract more to the konan.properties?
return mutableListOf(linker).apply {
addAll(listOf("--sysroot=${targetSysRoot}",
"-export-dynamic", "-z", "relro",
"--build-id", "--eh-frame-hdr", // "-m", "elf_x86_64",
"-dynamic-linker", propertyTargetString("dynamicLinker"),
"-o", executable,
"${targetSysRoot}/usr/lib64/crt1.o",
"${targetSysRoot}/usr/lib64/crti.o", "${libGcc}/crtbegin.o",
"-L${llvmLib}", "-L${libGcc}"))
if (distribution.target != KonanTarget.LINUX_MIPS32 && distribution.target != KonanTarget.LINUX_MIPSEL32) add("--hash-style=gnu") // MIPS doesn't support hash-style=gnu
addAll(specificLibs)
addAll(listOf("-L${targetSysRoot}/../lib", "-L${targetSysRoot}/lib", "-L${targetSysRoot}/usr/lib"))
if (optimize) addAll(listOf("-plugin", "$llvmLib/LLVMgold.so") + pluginOptimizationFlags)
addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags)
addAll(listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
"${libGcc}/crtend.o",
"${targetSysRoot}/usr/lib64/crtn.o"))
}
return listConstructor(
linker,
"--sysroot=${targetSysRoot}",
"-export-dynamic", "-z", "relro",
"--build-id", "--eh-frame-hdr", // "-m", "elf_x86_64",
"-dynamic-linker", propertyTargetString("dynamicLinker"),
"-o", executable,
If (!dynamic,
"${targetSysRoot}/usr/lib64/crt1.o"),
"${targetSysRoot}/usr/lib64/crti.o",
if (dynamic)
"${libGcc}/crtbeginS.o"
else
"${libGcc}/crtbegin.o",
"-L${llvmLib}", "-L${libGcc}",
If (!isMips, // MIPS doesn't support hash-style=gnu
"--hash-style=gnu"),
specificLibs,
"-L${targetSysRoot}/../lib", "-L${targetSysRoot}/lib", "-L${targetSysRoot}/usr/lib",
If (optimize,
"-plugin", "$llvmLib/LLVMgold.so",
pluginOptimizationFlags,
linkerOptimizationFlags),
If (!debug,
linkerNoDebugFlags),
If (dynamic,
linkerDynamicFlags),
objectFiles,
linkerKonanFlags,
"-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
if (dynamic)
"${libGcc}/crtendS.o"
else
"${libGcc}/crtend.o",
"${targetSysRoot}/usr/lib64/crtn.o"
)
}
}
@@ -187,13 +204,17 @@ internal open class MingwPlatform(distribution: Distribution)
= binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
return mutableListOf(linker).apply {
addAll(listOf("-o", executable))
addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
}
return listConstructor(
linker,
"-o", executable,
objectFiles,
If (optimize,
linkerOptimizationFlags),
If (!debug,
linkerNoDebugFlags),
If (dynamic,
linkerDynamicFlags)
)
}
override fun linkCommandSuffix() = linkerKonanFlags
@@ -48,11 +48,8 @@ class Runtime(bitcodeFile: String) {
// TODO: deduce TLS model from explicit config parameter.
val tlsMode by lazy {
when {
target.indexOf("android") != -1 -> LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
target.indexOf("wasm") != -1 -> LLVMThreadLocalMode.LLVMNotThreadLocal
else -> LLVMThreadLocalMode.LLVMLocalExecTLSModel
}
if (target.indexOf("wasm") != -1) LLVMThreadLocalMode.LLVMNotThreadLocal
else LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
}
val dataLayout = LLVMGetDataLayout(llvmModule)!!.toKString()
@@ -46,3 +46,35 @@ fun String.removeSuffixIfPresent(suffix: String) =
if (this.endsWith(suffix)) this.dropLast(suffix.length) else this
fun <T> Lazy<T>.getValueOrNull(): T? = if (isInitialized()) value else null
// The listConstructor() and If functions are convenient to construct
// command lines having a bunch of elements, lists and conditions.
// Use them like
//
// listConstructor(
// anElement1,
// If (condition1,
// element2),
// aList1,
// If (condition2,
// alist3,
// alist4)
// )
internal fun listConstructor(vararg elements: Any): List<String> {
val result = mutableListOf<String>()
for (element in elements) {
when (element) {
null -> {}
is String -> result.add(element)
is List<*> -> result.addAll(element as List<String>)
else -> error("Unexpected element of listConstructor: $element")
}
}
return result
}
internal fun If (condition: Boolean, vararg elements: Any): List<String> =
if (condition) listConstructor(*elements) else emptyList()
+12 -8
View File
@@ -41,7 +41,7 @@ llvmLtoNooptFlags.osx = -O1
llvmLtoDynamicFlags.osx = -relocation-model=pic
linkerKonanFlags.osx = -lc++ -lobjc -framework Foundation
linkerOptimizationFlags.osx = -dead_strip
linkerDebugFlags.osx = -S
linkerNoDebugFlags.osx = -S
linkerDynamicFlags.osx = -S -dylib
osVersionMinFlagLd.osx = -macosx_version_min
osVersionMinFlagClang.osx = -mmacosx-version-min
@@ -64,7 +64,7 @@ targetSysRoot.ios = target-sysroot-2-darwin-ios
libffiDir.ios = libffi-3.2.1-2-darwin-ios
llvmLtoFlags.ios =
llvmLtoOptFlags.ios = -O3 -function-sections
linkerDebugFlags.ios = -S
linkerNoDebugFlags.ios = -S
linkerDynamicFlags.ios = -S -dylib
llvmLtoNooptFlags.ios = -O1
llvmLtoDynamicFlags.ios = -relocation-model=pic
@@ -91,7 +91,7 @@ llvmLtoNooptFlags.ios_sim = -O1
llvmLtoDynamicFlags.ios_sim = -relocation-model=pic
linkerKonanFlags.ios_sim = -lc++ -lobjc -framework Foundation -sdk_version 10.2
linkerOptimizationFlags.ios_sim = -dead_strip
linkerDebugFlags.ios_sim = -S
linkerNoDebugFlags.ios_sim = -S
linkerDynamicFlags.ios_sim = -S -dylib
osVersionMinFlagLd.ios_sim = -ios_simulator_version_min
osVersionMinFlagClang.ios_sim = -mios-simulator-version-min
@@ -114,7 +114,7 @@ llvmLtoDynamicFlags.linux = -relocation-model=pic
llvmLlcFlags.linux = -march=x86-64
linkerKonanFlags.linux = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread
linkerOptimizationFlags.linux = --gc-sections
linkerDebugFlags.linux = -S
linkerNoDebugFlags.linux = -S
linkerDynamicFlags.linux = -shared
pluginOptimizationFlags.linux = -plugin-opt=mcpu=x86-64 -plugin-opt=O3
dynamicLinker.linux = /lib64/ld-linux-x86-64.so.2
@@ -137,7 +137,8 @@ dependencies.linux-raspberrypi = \
quadruple.raspberrypi = armv6-unknown-linux-gnueabihf
entrySelector.raspberrypi = --defsym main=Konan_main
linkerDebugFlags.raspberrypi = -S
linkerNoDebugFlags.raspberrypi = -S
linkerDynamicFlags.raspberrypi = -shared
linkerOptimizationFlags.raspberrypi = --gc-sections
targetSysRoot.raspberrypi = target-sysroot-1-raspberrypi
# We could reuse host toolchain here.
@@ -166,6 +167,7 @@ dependencies.linux-linux_mips32 = \
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
# We could reuse host toolchain here.
libffiDir.linux_mips32 = libffi-3.2.1-2-linux-mips
@@ -190,6 +192,7 @@ dependencies.linux-linux_mipsel32 = \
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
# We could reuse host toolchain here.
libffiDir.linux_mipsel32 = libffi-3.2.1-2-linux-mipsel
@@ -222,7 +225,7 @@ quadruple.android_arm32 = arm-linux-androideabi
entrySelector.android_arm32 = -Wl,--defsym -Wl,main=Konan_main
llvmLtoFlags.android_arm32 = -emulated-tls -relocation-model=pic
llvmLtoOptFlags.android_arm32 = -O3 -function-sections
linkerDebugFlags.android_arm32 = -Wl,-S
linkerNoDebugFlags.android_arm32 = -Wl,-S
llvmLtoNooptFlags.android_arm32 = -O1
targetSysRoot.android_arm32 = target-sysroot-21-android_arm32
libffiDir.android_arm32 = libffi-3.2.1-2-android_arm32
@@ -249,7 +252,7 @@ llvmLtoFlags.android_arm64 = -emulated-tls -relocation-model=pic
targetSysRoot.android_arm64 = target-sysroot-21-android_arm64
libffiDir.android_arm64 = libffi-3.2.1-2-android_arm64
linkerKonanFlags.android_arm64 = -lm -latomic -lstdc++ -landroid
linkerDebugFlags.android_arm64 = -Wl,-S
linkerNoDebugFlags.android_arm64 = -Wl,-S
# Windows x86-64, based on mingw-w64.
llvmHome.mingw = msys2-mingw-w64-x86_64-gcc-7.2.0-clang-llvm-5.0.0-windows-x86-64
@@ -261,7 +264,8 @@ libffiDir.mingw = libffi-3.2.1-mingw-w64-x86-64
llvmLtoFlags.mingw =
llvmLtoOptFlags.mingw = -O3 -function-sections
llvmLtoNooptFlags.mingw = -O1
linkerDebugFlags.mingw = -Wl,-S
linkerNoDebugFlags.mingw = -Wl,-S
linkerDynamicFlags.mingw = -shared
linkerKonanFlags.mingw =-static-libgcc -static-libstdc++ -Xclang -flto-visibility-public-std -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic
linkerOptimizationFlags.mingw = -Wl,--gc-sections
entrySelector.mingw = -Wl,--defsym,main=Konan_main
@@ -42,7 +42,7 @@ class KonanProperties(val target: KonanTarget, val properties: Properties, val b
val entrySelector get() = targetList("entrySelector")
val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags")
val linkerKonanFlags get() = targetList("linkerKonanFlags")
val linkerDebugFlags get() = targetList("linkerDebugFlags")
val linkerNoDebugFlags get() = targetList("linkerNoDebugFlags")
val linkerDynamicFlags get() = targetList("linkerDynamicFlags")
val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags")
val s2wasmFlags get() = targetList("s2wasmFlags")