diff --git a/lld/test/COFF/Inputs/tlssup-32.ll b/lld/test/COFF/Inputs/tlssup-32.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/Inputs/tlssup-32.ll @@ -0,0 +1,31 @@ +; We manually create these here if we're not linking against +; the CRT which would usually provide these. + +target triple = "i686-pc-windows-msvc" + +%IMAGE_TLS_DIRECTORY32 = type { + i32, ; StartAddressOfRawData + i32, ; EndAddressOfRawData + i32, ; AddressOfIndex + i32, ; AddressOfCallBacks + i32, ; SizeOfZeroFill + i32 ; Characteristics +} + +@_tls_start = global i8 zeroinitializer, section ".tls" +@_tls_end = global i8 zeroinitializer, section ".tls$ZZZ" +@_tls_index = global i32 0 + +@_tls_used = global %IMAGE_TLS_DIRECTORY32 { + i32 ptrtoint (i8* @_tls_start to i32), + i32 ptrtoint (i8* @_tls_end to i32), + i32 ptrtoint (i32* @_tls_index to i32), + i32 0, + i32 0, + i32 0 +}, section ".rdata$T" + +; MSVC target uses a direct offset (0x58) for x86-64 but expects +; __tls_array to hold the offset (0x2C) on x86. +module asm ".global __tls_array" +module asm "__tls_array = 44" \ No newline at end of file diff --git a/lld/test/COFF/Inputs/tlssup-64.ll b/lld/test/COFF/Inputs/tlssup-64.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/Inputs/tlssup-64.ll @@ -0,0 +1,26 @@ +; We manually create these here if we're not linking against +; the CRT which would usually provide these. + +target triple = "x86_64-pc-windows-msvc" + +%IMAGE_TLS_DIRECTORY64 = type { + i64, ; StartAddressOfRawData + i64, ; EndAddressOfRawData + i64, ; AddressOfIndex + i64, ; AddressOfCallBacks + i32, ; SizeOfZeroFill + i32 ; Characteristics +} + +@_tls_start = global i8 zeroinitializer, section ".tls" +@_tls_end = global i8 zeroinitializer, section ".tls$ZZZ" +@_tls_index = global i64 0 + +@_tls_used = global %IMAGE_TLS_DIRECTORY64 { + i64 ptrtoint (i8* @_tls_start to i64), + i64 ptrtoint (i8* @_tls_end to i64), + i64 ptrtoint (i64* @_tls_index to i64), + i64 0, + i32 0, + i32 0 +}, section ".rdata$T" \ No newline at end of file diff --git a/lld/test/COFF/tls-alignment-32.ll b/lld/test/COFF/tls-alignment-32.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/tls-alignment-32.ll @@ -0,0 +1,23 @@ +; This test is to make sure that the necessary alignment for thread locals +; gets reflected in the TLS Directory of the generated executable on x86. +; +; aligned_thread_local specifies 'align 32' and so the generated +; exe should reflect that with a value of IMAGE_SCN_ALIGN_32BYTES +; in the Characteristics field of the IMAGE_TLS_DIRECTORY + +; RUN: llc -filetype=obj %S/Inputs/tlssup-32.ll -o %t.tlssup.obj +; RUN: llc -filetype=obj %s -o %t.obj +; RUN: lld-link %t.tlssup.obj %t.obj -entry:main -nodefaultlib -out:%t.exe +; RUN: llvm-readobj --coff-tls-directory %t.exe | FileCheck %s + +; CHECK: TLSDirectory { +; CHECK: Characteristics [ (0x0) + +target triple = "i686-pc-windows-msvc" + +@aligned_thread_local = thread_local global i32 42, align 32 + +define i32 @main() { + %t = load i32, i32* @aligned_thread_local + ret i32 %t +} diff --git a/lld/test/COFF/tls-alignment-64.ll b/lld/test/COFF/tls-alignment-64.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/tls-alignment-64.ll @@ -0,0 +1,23 @@ +; This test is to make sure that the necessary alignment for thread locals +; gets reflected in the TLS Directory of the generated executable on x86-64. +; +; aligned_thread_local specifies 'align 64' and so the generated +; exe should reflect that with a value of IMAGE_SCN_ALIGN_64BYTES +; in the Characteristics field of the IMAGE_TLS_DIRECTORY + +; RUN: llc -filetype=obj %S/Inputs/tlssup-64.ll -o %t.tlssup.obj +; RUN: llc -filetype=obj %s -o %t.obj +; RUN: lld-link %t.tlssup.obj %t.obj -entry:main -nodefaultlib -out:%t.exe +; RUN: llvm-readobj --coff-tls-directory %t.exe | FileCheck %s + +; CHECK: TLSDirectory { +; CHECK: Characteristics [ (0x0) + +target triple = "x86_64-pc-windows-msvc" + +@aligned_thread_local = thread_local global i32 42, align 64 + +define i32 @main() { + %t = load i32, i32* @aligned_thread_local + ret i32 %t +}