[PATCH] D65018: [LLD] [COFF] Unbreak sorting of mingw comdat .tls sections after SVN r363457

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 19 14:05:26 PDT 2019


mstorsjo created this revision.
mstorsjo added reviewers: rnk, ruiu, hans.
Herald added a project: LLVM.

Code built for mingw with -fdata-sections will store each TLS variable in a comdat section, named .tls$$<varname>. Normal TLS variables are stored in sections named .tls$ with a trailing dollar, which are sorted before a starter marker (in a later linked object file) in a section named ".tls" (with no dollar suffix), before an ending marker in a section named ".tls$ZZZ".

The mingw comdat section suffix stripping introduced in SVN r363457 broke sorting of such tls sections, ending up sorting the stripped .tls$$<varname> sections (stripped to ".tls") before the start marker in the section named ".tls".

We could either add exceptions to the section name suffix stripping for .tls (and .CRT, where suffixes always should be honored), but the more conservative option is probably the reverse; to only apply the stripping for the one so far known case, .eh_frame$<symbol>.

@hans This is a fix for a regression from June, that needs to go to the 9 branch once we settle upon how to handle it.

The comment grows rather large (making it way too large for this context IMO), any suggestions? Should we split the logic to a helper function to ease adding lots of explanations to it, without disturbing the rest of the enclosing method?


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D65018

Files:
  COFF/Writer.cpp
  test/COFF/tls_suffix_sorting.s


Index: test/COFF/tls_suffix_sorting.s
===================================================================
--- /dev/null
+++ test/COFF/tls_suffix_sorting.s
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+
+# RUN: echo -e ".section .tls,\"dw\"\n .byte 0xaa\n .section .tls\$ZZZ,\"dw\"\n .byte 0xff\n .globl _tls_index\n .data\n _tls_index:\n .int 0" > %t.tlssup.s
+# RUN: llvm-mc -triple=x86_64-windows-gnu %t.tlssup.s -filetype=obj -o %t.tlssup.o
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.main.o
+
+# RUN: lld-link -lldmingw -entry:main %t.main.o %t.tlssup.o -out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+
+# Check that .tls$$foo is sorted after the start marker (aa) and before the
+# end marker (ff).
+
+# CHECK: Contents of section .tls:
+# CHECK:  140004000 aabbff
+
+        .text
+        .globl          main
+main:
+        movl            _tls_index(%rip), %eax
+        movq            %gs:88, %rcx
+        movq            (%rcx,%rax,8), %rax
+        movb            foo at SECREL32(%rax), %al
+        ret
+
+        .section        .tls$$foo,"dw"
+        .linkonce       discard
+foo:
+        .byte           0xbb
Index: COFF/Writer.cpp
===================================================================
--- COFF/Writer.cpp
+++ COFF/Writer.cpp
@@ -822,9 +822,15 @@
     }
     StringRef name = c->getSectionName();
     // On MinGW, comdat groups are formed by putting the comdat group name
-    // after the '$' in the section name. Such a section name suffix shouldn't
-    // imply separate alphabetical sorting of those section chunks though.
-    if (config->mingw && sc && sc->isCOMDAT())
+    // after the '$' in the section name. For .eh_frame$<symbol>, that must
+    // still be sorted before the .eh_frame trailer from crtend.o, thus just
+    // strip the section name trailer. For other sections, such as
+    // .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
+    // ".tls$"), they must be strictly sorted after .tls. And for the
+    // hypothetical case of comdat .CRT$XCU, we definitely need to keep the
+    // suffix for sorting. Thus, to play it safe, only strip the suffix for
+    // .eh_frame.
+    if (config->mingw && sc && sc->isCOMDAT() && name.startswith(".eh_frame$"))
       name = name.split('$').first;
     PartialSection *pSec = createPartialSection(name,
                                                 c->getOutputCharacteristics());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65018.210892.patch
Type: text/x-patch
Size: 2431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190719/1aefca49/attachment.bin>


More information about the llvm-commits mailing list