diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -960,6 +960,12 @@ segname == segment_names::text) osec->align = target->wordSize; + // MC keeps the default 1-byte alignment for __thread_vars, even though it + // contains pointers that are fixed up by dyld, which requires proper + // alignment. + if (isThreadLocalVariables(osec->flags)) + osec->align = std::max(osec->align, target->wordSize); + getOrCreateOutputSegment(segname)->addOutputSection(osec); } } 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 @@ -43,7 +43,7 @@ # FLAGS-NEXT: addr # FLAGS-NEXT: size 0x0000000000000030 # FLAGS-NEXT: offset -# FLAGS-NEXT: align +# FLAGS-NEXT: align 2^3 (8) # FLAGS-NEXT: reloff 0 # FLAGS-NEXT: nreloc 0 # FLAGS-NEXT: type S_THREAD_LOCAL_VARIABLES