diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp --- a/lld/MachO/OutputSegment.cpp +++ b/lld/MachO/OutputSegment.cpp @@ -100,6 +100,8 @@ // sections can be zerofills, we end up putting all TLV data sections at the // end of the segment. switch (sectionType(osec->flags)) { + case S_THREAD_LOCAL_VARIABLE_POINTERS: + return std::numeric_limits::max() - 3; case S_THREAD_LOCAL_REGULAR: return std::numeric_limits::max() - 2; case S_THREAD_LOCAL_ZEROFILL: diff --git a/lld/test/MachO/tlv-dylib.s b/lld/test/MachO/tlv-dylib.s --- a/lld/test/MachO/tlv-dylib.s +++ b/lld/test/MachO/tlv-dylib.s @@ -26,6 +26,8 @@ # CHECK-DAG: __DATA __thread_ptrs 0x{{0*}}[[#%x, BAR]] pointer 0 libtlv _bar # CHECK-DAG: __DATA_CONST __got 0x{{0*}}[[#%x, BAZ]] pointer 0 libtlv _baz +## Check `type` on the various TLV sections, and check that +## nothing's after S_THREAD_LOCAL_ZEROFILL. # RUN: llvm-otool -lv %t/test | FileCheck --check-prefix=FLAGS %s # FLAGS: sectname __got # FLAGS-NEXT: segname __DATA_CONST @@ -36,6 +38,15 @@ # FLAGS-NEXT: reloff 0 # FLAGS-NEXT: nreloc 0 # FLAGS-NEXT: type S_NON_LAZY_SYMBOL_POINTERS +# FLAGS: sectname __thread_vars +# FLAGS-NEXT: segname __DATA +# FLAGS-NEXT: addr +# FLAGS-NEXT: size 0x0000000000000030 +# FLAGS-NEXT: offset +# FLAGS-NEXT: align +# FLAGS-NEXT: reloff 0 +# FLAGS-NEXT: nreloc 0 +# FLAGS-NEXT: type S_THREAD_LOCAL_VARIABLES # FLAGS: sectname __thread_ptrs # FLAGS-NEXT: segname __DATA # FLAGS-NEXT: addr @@ -45,6 +56,24 @@ # FLAGS-NEXT: reloff 0 # FLAGS-NEXT: nreloc 0 # FLAGS-NEXT: type S_THREAD_LOCAL_VARIABLE_POINTERS +# FLAGS: sectname __thread_data +# FLAGS-NEXT: segname __DATA +# FLAGS-NEXT: addr +# FLAGS-NEXT: size 0x0000000000000008 +# FLAGS-NEXT: offset +# FLAGS-NEXT: align +# FLAGS-NEXT: reloff 0 +# FLAGS-NEXT: nreloc 0 +# FLAGS-NEXT: type S_THREAD_LOCAL_REGULAR +# FLAGS: sectname __thread_bss +# FLAGS-NEXT: segname __DATA +# FLAGS-NEXT: addr +# FLAGS-NEXT: size 0x0000000000000008 +# FLAGS-NEXT: offset +# FLAGS-NEXT: align 2^3 (8) +# FLAGS-NEXT: reloff 0 +# FLAGS-NEXT: nreloc 0 +# FLAGS-NEXT: type S_THREAD_LOCAL_ZEROFILL #--- libtlv.s .section __DATA,__thread_vars,thread_local_variables @@ -63,3 +92,22 @@ ## Add a GOT entry to make sure we don't mix it up with TLVs mov _baz@GOTPCREL(%rip), %rax ret + +## Add some TLVs to test too, so that we can test the ordering +## of __thread_ptrs, __thread_data, and __thread_bss. +.section __DATA,__thread_data,thread_local_regular +_tfoo$tlv$init: + .quad 123 + +.tbss _tbaz$tlv$init, 8, 3 + +.section __DATA,__thread_vars,thread_local_variables +.globl _tfoo, _tbar +_tfoo: + .quad __tlv_bootstrap + .quad 0 + .quad _tfoo$tlv$init +_tbaz: + .quad __tlv_bootstrap + .quad 0 + .quad _tbaz$tlv$init