Skip to content

Commit 341a68c

Browse files
committed
[COFF] Unbreak sorting of mingw comdat .tls sections after SVN r363457
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 after 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 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 normal sections where sorting shouldn't have any effect. Differential Revision: https://reviews.llvm.org/D65018 llvm-svn: 366780
1 parent a658cb0 commit 341a68c

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

lld/COFF/Writer.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,28 @@ void Writer::locateImportTables() {
762762
}
763763
}
764764

765+
// Return whether a SectionChunk's suffix (the dollar and any trailing
766+
// suffix) should be removed and sorted into the main suffixless
767+
// PartialSection.
768+
static bool shouldStripSectionSuffix(SectionChunk *sc, StringRef name) {
769+
// On MinGW, comdat groups are formed by putting the comdat group name
770+
// after the '$' in the section name. For .eh_frame$<symbol>, that must
771+
// still be sorted before the .eh_frame trailer from crtend.o, thus just
772+
// strip the section name trailer. For other sections, such as
773+
// .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
774+
// ".tls$"), they must be strictly sorted after .tls. And for the
775+
// hypothetical case of comdat .CRT$XCU, we definitely need to keep the
776+
// suffix for sorting. Thus, to play it safe, only strip the suffix for
777+
// the standard sections.
778+
if (!config->mingw)
779+
return false;
780+
if (!sc || !sc->isCOMDAT())
781+
return false;
782+
return name.startswith(".text$") || name.startswith(".data$") ||
783+
name.startswith(".rdata$") || name.startswith(".pdata$") ||
784+
name.startswith(".xdata$") || name.startswith(".eh_frame$");
785+
}
786+
765787
// Create output section objects and add them to OutputSections.
766788
void Writer::createSections() {
767789
// First, create the builtin sections.
@@ -807,10 +829,7 @@ void Writer::createSections() {
807829
continue;
808830
}
809831
StringRef name = c->getSectionName();
810-
// On MinGW, comdat groups are formed by putting the comdat group name
811-
// after the '$' in the section name. Such a section name suffix shouldn't
812-
// imply separate alphabetical sorting of those section chunks though.
813-
if (config->mingw && sc && sc->isCOMDAT())
832+
if (shouldStripSectionSuffix(sc, name))
814833
name = name.split('$').first;
815834
PartialSection *pSec = createPartialSection(name,
816835
c->getOutputCharacteristics());

lld/test/COFF/tls_suffix_sorting.s

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# REQUIRES: x86
2+
3+
# 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
4+
# RUN: llvm-mc -triple=x86_64-windows-gnu %t.tlssup.s -filetype=obj -o %t.tlssup.o
5+
# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t.main.o
6+
7+
# RUN: lld-link -lldmingw -entry:main %t.main.o %t.tlssup.o -out:%t.exe
8+
# RUN: llvm-objdump -s %t.exe | FileCheck %s
9+
10+
# Check that .tls$$foo is sorted after the start marker (aa) and before the
11+
# end marker (ff).
12+
13+
# CHECK: Contents of section .tls:
14+
# CHECK: 140004000 aabbff
15+
16+
.text
17+
.globl main
18+
main:
19+
movl _tls_index(%rip), %eax
20+
movq %gs:88, %rcx
21+
movq (%rcx,%rax,8), %rax
22+
movb foo@SECREL32(%rax), %al
23+
ret
24+
25+
.section .tls$$foo,"dw"
26+
.linkonce discard
27+
foo:
28+
.byte 0xbb

0 commit comments

Comments
 (0)