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.file.*
import org.jetbrains.kotlin.konan.properties.* import org.jetbrains.kotlin.konan.properties.*
import org.jetbrains.kotlin.konan.target.* 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 BitcodeFile = String
typealias ObjectFile = String typealias ObjectFile = String
@@ -36,7 +38,7 @@ internal abstract class PlatformFlags(val properties: KonanProperties) {
val entrySelector = properties.entrySelector val entrySelector = properties.entrySelector
val linkerOptimizationFlags = properties.linkerOptimizationFlags val linkerOptimizationFlags = properties.linkerOptimizationFlags
val linkerKonanFlags = properties.linkerKonanFlags val linkerKonanFlags = properties.linkerKonanFlags
val linkerDebugFlags = properties.linkerDebugFlags val linkerNoDebugFlags = properties.linkerNoDebugFlags
val linkerDynamicFlags = properties.linkerDynamicFlags val linkerDynamicFlags = properties.linkerDynamicFlags
val llvmDebugOptFlags = properties.llvmDebugOptFlags val llvmDebugOptFlags = properties.llvmDebugOptFlags
val s2wasmFlags = properties.s2wasmFlags val s2wasmFlags = properties.s2wasmFlags
@@ -89,7 +91,7 @@ internal open class AndroidPlatform(distribution: Distribution)
add("-llog") add("-llog")
addAll(objectFiles) addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags) if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags) if (!debug) addAll(linkerNoDebugFlags)
if (dynamic) addAll(linkerDynamicFlags) if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags) addAll(linkerKonanFlags)
} }
@@ -122,7 +124,7 @@ internal open class MacOSBasedPlatform(distribution: Distribution)
addAll(listOf("-syslibroot", targetSysRoot, "-o", executable)) addAll(listOf("-syslibroot", targetSysRoot, "-o", executable))
addAll(objectFiles) addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags) if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags) if (!debug) addAll(linkerNoDebugFlags)
if (dynamic) addAll(linkerDynamicFlags) if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags) addAll(linkerKonanFlags)
add("-lSystem") add("-lSystem")
@@ -134,7 +136,6 @@ internal open class MacOSBasedPlatform(distribution: Distribution)
open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> = open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> =
listOf(dsymutil, "-dump-debug-map" ,executable) listOf(dsymutil, "-dump-debug-map" ,executable)
} }
internal open class LinuxBasedPlatform(val distribution: Distribution) internal open class LinuxBasedPlatform(val distribution: Distribution)
: PlatformFlags(distribution.targetProperties) { : PlatformFlags(distribution.targetProperties) {
@@ -149,30 +150,46 @@ internal open class LinuxBasedPlatform(val distribution: Distribution)
= binaries.filter { it.isUnixStaticLib } = binaries.filter { it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> { 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? // TODO: Can we extract more to the konan.properties?
return mutableListOf(linker).apply { return listConstructor(
addAll(listOf("--sysroot=${targetSysRoot}", linker,
"-export-dynamic", "-z", "relro", "--sysroot=${targetSysRoot}",
"--build-id", "--eh-frame-hdr", // "-m", "elf_x86_64", "-export-dynamic", "-z", "relro",
"-dynamic-linker", propertyTargetString("dynamicLinker"), "--build-id", "--eh-frame-hdr", // "-m", "elf_x86_64",
"-o", executable, "-dynamic-linker", propertyTargetString("dynamicLinker"),
"${targetSysRoot}/usr/lib64/crt1.o", "-o", executable,
"${targetSysRoot}/usr/lib64/crti.o", "${libGcc}/crtbegin.o", If (!dynamic,
"-L${llvmLib}", "-L${libGcc}")) "${targetSysRoot}/usr/lib64/crt1.o"),
if (distribution.target != KonanTarget.LINUX_MIPS32 && distribution.target != KonanTarget.LINUX_MIPSEL32) add("--hash-style=gnu") // MIPS doesn't support hash-style=gnu "${targetSysRoot}/usr/lib64/crti.o",
addAll(specificLibs) if (dynamic)
addAll(listOf("-L${targetSysRoot}/../lib", "-L${targetSysRoot}/lib", "-L${targetSysRoot}/usr/lib")) "${libGcc}/crtbeginS.o"
if (optimize) addAll(listOf("-plugin", "$llvmLib/LLVMgold.so") + pluginOptimizationFlags) else
addAll(objectFiles) "${libGcc}/crtbegin.o",
if (optimize) addAll(linkerOptimizationFlags) "-L${llvmLib}", "-L${libGcc}",
if (!debug) addAll(linkerDebugFlags) If (!isMips, // MIPS doesn't support hash-style=gnu
if (dynamic) addAll(linkerDynamicFlags) "--hash-style=gnu"),
addAll(linkerKonanFlags) specificLibs,
addAll(listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-L${targetSysRoot}/../lib", "-L${targetSysRoot}/lib", "-L${targetSysRoot}/usr/lib",
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", If (optimize,
"${libGcc}/crtend.o", "-plugin", "$llvmLib/LLVMgold.so",
"${targetSysRoot}/usr/lib64/crtn.o")) 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 } = binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> { override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
return mutableListOf(linker).apply { return listConstructor(
addAll(listOf("-o", executable)) linker,
addAll(objectFiles) "-o", executable,
if (optimize) addAll(linkerOptimizationFlags) objectFiles,
if (!debug) addAll(linkerDebugFlags) If (optimize,
if (dynamic) addAll(linkerDynamicFlags) linkerOptimizationFlags),
} If (!debug,
linkerNoDebugFlags),
If (dynamic,
linkerDynamicFlags)
)
} }
override fun linkCommandSuffix() = linkerKonanFlags override fun linkCommandSuffix() = linkerKonanFlags
@@ -48,11 +48,8 @@ class Runtime(bitcodeFile: String) {
// TODO: deduce TLS model from explicit config parameter. // TODO: deduce TLS model from explicit config parameter.
val tlsMode by lazy { val tlsMode by lazy {
when { if (target.indexOf("wasm") != -1) LLVMThreadLocalMode.LLVMNotThreadLocal
target.indexOf("android") != -1 -> LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel else LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
target.indexOf("wasm") != -1 -> LLVMThreadLocalMode.LLVMNotThreadLocal
else -> LLVMThreadLocalMode.LLVMLocalExecTLSModel
}
} }
val dataLayout = LLVMGetDataLayout(llvmModule)!!.toKString() val dataLayout = LLVMGetDataLayout(llvmModule)!!.toKString()
@@ -46,3 +46,35 @@ fun String.removeSuffixIfPresent(suffix: String) =
if (this.endsWith(suffix)) this.dropLast(suffix.length) else this if (this.endsWith(suffix)) this.dropLast(suffix.length) else this
fun <T> Lazy<T>.getValueOrNull(): T? = if (isInitialized()) value else null 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 llvmLtoDynamicFlags.osx = -relocation-model=pic
linkerKonanFlags.osx = -lc++ -lobjc -framework Foundation linkerKonanFlags.osx = -lc++ -lobjc -framework Foundation
linkerOptimizationFlags.osx = -dead_strip linkerOptimizationFlags.osx = -dead_strip
linkerDebugFlags.osx = -S linkerNoDebugFlags.osx = -S
linkerDynamicFlags.osx = -S -dylib linkerDynamicFlags.osx = -S -dylib
osVersionMinFlagLd.osx = -macosx_version_min osVersionMinFlagLd.osx = -macosx_version_min
osVersionMinFlagClang.osx = -mmacosx-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 libffiDir.ios = libffi-3.2.1-2-darwin-ios
llvmLtoFlags.ios = llvmLtoFlags.ios =
llvmLtoOptFlags.ios = -O3 -function-sections llvmLtoOptFlags.ios = -O3 -function-sections
linkerDebugFlags.ios = -S linkerNoDebugFlags.ios = -S
linkerDynamicFlags.ios = -S -dylib linkerDynamicFlags.ios = -S -dylib
llvmLtoNooptFlags.ios = -O1 llvmLtoNooptFlags.ios = -O1
llvmLtoDynamicFlags.ios = -relocation-model=pic llvmLtoDynamicFlags.ios = -relocation-model=pic
@@ -91,7 +91,7 @@ llvmLtoNooptFlags.ios_sim = -O1
llvmLtoDynamicFlags.ios_sim = -relocation-model=pic llvmLtoDynamicFlags.ios_sim = -relocation-model=pic
linkerKonanFlags.ios_sim = -lc++ -lobjc -framework Foundation -sdk_version 10.2 linkerKonanFlags.ios_sim = -lc++ -lobjc -framework Foundation -sdk_version 10.2
linkerOptimizationFlags.ios_sim = -dead_strip linkerOptimizationFlags.ios_sim = -dead_strip
linkerDebugFlags.ios_sim = -S linkerNoDebugFlags.ios_sim = -S
linkerDynamicFlags.ios_sim = -S -dylib linkerDynamicFlags.ios_sim = -S -dylib
osVersionMinFlagLd.ios_sim = -ios_simulator_version_min osVersionMinFlagLd.ios_sim = -ios_simulator_version_min
osVersionMinFlagClang.ios_sim = -mios-simulator-version-min osVersionMinFlagClang.ios_sim = -mios-simulator-version-min
@@ -114,7 +114,7 @@ llvmLtoDynamicFlags.linux = -relocation-model=pic
llvmLlcFlags.linux = -march=x86-64 llvmLlcFlags.linux = -march=x86-64
linkerKonanFlags.linux = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread linkerKonanFlags.linux = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread
linkerOptimizationFlags.linux = --gc-sections linkerOptimizationFlags.linux = --gc-sections
linkerDebugFlags.linux = -S linkerNoDebugFlags.linux = -S
linkerDynamicFlags.linux = -shared linkerDynamicFlags.linux = -shared
pluginOptimizationFlags.linux = -plugin-opt=mcpu=x86-64 -plugin-opt=O3 pluginOptimizationFlags.linux = -plugin-opt=mcpu=x86-64 -plugin-opt=O3
dynamicLinker.linux = /lib64/ld-linux-x86-64.so.2 dynamicLinker.linux = /lib64/ld-linux-x86-64.so.2
@@ -137,7 +137,8 @@ dependencies.linux-raspberrypi = \
quadruple.raspberrypi = armv6-unknown-linux-gnueabihf quadruple.raspberrypi = armv6-unknown-linux-gnueabihf
entrySelector.raspberrypi = --defsym main=Konan_main entrySelector.raspberrypi = --defsym main=Konan_main
linkerDebugFlags.raspberrypi = -S linkerNoDebugFlags.raspberrypi = -S
linkerDynamicFlags.raspberrypi = -shared
linkerOptimizationFlags.raspberrypi = --gc-sections linkerOptimizationFlags.raspberrypi = --gc-sections
targetSysRoot.raspberrypi = target-sysroot-1-raspberrypi targetSysRoot.raspberrypi = target-sysroot-1-raspberrypi
# We could reuse host toolchain here. # We could reuse host toolchain here.
@@ -166,6 +167,7 @@ dependencies.linux-linux_mips32 = \
quadruple.linux_mips32 = mips-unknown-linux-gnu quadruple.linux_mips32 = mips-unknown-linux-gnu
entrySelector.linux_mips32 = --defsym main=Konan_main entrySelector.linux_mips32 = --defsym main=Konan_main
linkerOptimizationFlags.linux_mips32 = --gc-sections linkerOptimizationFlags.linux_mips32 = --gc-sections
linkerDynamicFlags.linux_mips32 = -shared
targetSysRoot.linux_mips32 = target-sysroot-2-mips targetSysRoot.linux_mips32 = target-sysroot-2-mips
# We could reuse host toolchain here. # We could reuse host toolchain here.
libffiDir.linux_mips32 = libffi-3.2.1-2-linux-mips 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 quadruple.linux_mipsel32 = mipsel-unknown-linux-gnu
entrySelector.linux_mipsel32 = --defsym main=Konan_main entrySelector.linux_mipsel32 = --defsym main=Konan_main
linkerOptimizationFlags.linux_mipsel32 = --gc-sections linkerOptimizationFlags.linux_mipsel32 = --gc-sections
linkerDynamicFlags.linux_mipsel32 = -shared
targetSysRoot.linux_mipsel32 = target-sysroot-2-mipsel targetSysRoot.linux_mipsel32 = target-sysroot-2-mipsel
# We could reuse host toolchain here. # We could reuse host toolchain here.
libffiDir.linux_mipsel32 = libffi-3.2.1-2-linux-mipsel 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 entrySelector.android_arm32 = -Wl,--defsym -Wl,main=Konan_main
llvmLtoFlags.android_arm32 = -emulated-tls -relocation-model=pic llvmLtoFlags.android_arm32 = -emulated-tls -relocation-model=pic
llvmLtoOptFlags.android_arm32 = -O3 -function-sections llvmLtoOptFlags.android_arm32 = -O3 -function-sections
linkerDebugFlags.android_arm32 = -Wl,-S linkerNoDebugFlags.android_arm32 = -Wl,-S
llvmLtoNooptFlags.android_arm32 = -O1 llvmLtoNooptFlags.android_arm32 = -O1
targetSysRoot.android_arm32 = target-sysroot-21-android_arm32 targetSysRoot.android_arm32 = target-sysroot-21-android_arm32
libffiDir.android_arm32 = libffi-3.2.1-2-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 targetSysRoot.android_arm64 = target-sysroot-21-android_arm64
libffiDir.android_arm64 = libffi-3.2.1-2-android_arm64 libffiDir.android_arm64 = libffi-3.2.1-2-android_arm64
linkerKonanFlags.android_arm64 = -lm -latomic -lstdc++ -landroid linkerKonanFlags.android_arm64 = -lm -latomic -lstdc++ -landroid
linkerDebugFlags.android_arm64 = -Wl,-S linkerNoDebugFlags.android_arm64 = -Wl,-S
# Windows x86-64, based on mingw-w64. # 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 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 = llvmLtoFlags.mingw =
llvmLtoOptFlags.mingw = -O3 -function-sections llvmLtoOptFlags.mingw = -O3 -function-sections
llvmLtoNooptFlags.mingw = -O1 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 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 linkerOptimizationFlags.mingw = -Wl,--gc-sections
entrySelector.mingw = -Wl,--defsym,main=Konan_main 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 entrySelector get() = targetList("entrySelector")
val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags") val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags")
val linkerKonanFlags get() = targetList("linkerKonanFlags") val linkerKonanFlags get() = targetList("linkerKonanFlags")
val linkerDebugFlags get() = targetList("linkerDebugFlags") val linkerNoDebugFlags get() = targetList("linkerNoDebugFlags")
val linkerDynamicFlags get() = targetList("linkerDynamicFlags") val linkerDynamicFlags get() = targetList("linkerDynamicFlags")
val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags") val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags")
val s2wasmFlags get() = targetList("s2wasmFlags") val s2wasmFlags get() = targetList("s2wasmFlags")