diff options
| author | Eric Botcazou <ebotcazou@adacore.com> | 2025-12-08 17:47:56 +0100 |
|---|---|---|
| committer | Eric Botcazou <ebotcazou@adacore.com> | 2025-12-08 17:50:45 +0100 |
| commit | 3777a0b41f9fdcbb5fde4bdfce06031805cebc33 (patch) | |
| tree | 856e6337b8b7089e521a9323c61d870de02cfc1f | |
| parent | 76fc22a292ad652338be21b7ff4a767ddb3d7015 (diff) | |
| download | gcc-3777a0b41f9fdcbb5fde4bdfce06031805cebc33.zip gcc-3777a0b41f9fdcbb5fde4bdfce06031805cebc33.tar.gz gcc-3777a0b41f9fdcbb5fde4bdfce06031805cebc33.tar.bz2 | |
MinGW: Fix native TLS bug with -fdata-sections
The problem comes from a quirk of the GNU PE-COFF linker, which wants
to make sure that .tls$ZZZ is laid out last among the TLS sections,
but first globs all .tls$* sections together. The solution matches
Clang's output.
gcc/
PR target/80881
* config/mingw/winnt.cc (mingw_pe_unique_section): Put two dollar
signs for TLS sections after the prefix.
(mingw_pe_asm_named_section): Deal with all TLS sections uniformly.
gcc/testsuite/
* gcc.dg/tls/data-sections-1.c: New test.
| -rw-r--r-- | gcc/config/mingw/winnt.cc | 10 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/tls/data-sections-1.c | 14 |
2 files changed, 20 insertions, 4 deletions
diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc index b51fd8e..fe2fb4c 100644 --- a/gcc/config/mingw/winnt.cc +++ b/gcc/config/mingw/winnt.cc @@ -446,8 +446,11 @@ mingw_pe_unique_section (tree decl, int reloc) prefix = ".text$"; else if (decl_readonly_section (decl, reloc)) prefix = ".rdata$"; + /* Note that we need two dollar signs for TLS sections + because they need to be ASCII-sorted before .tls$ZZZ + to be properly laid out by the GNU linker. */ else if (DECL_THREAD_LOCAL_P (decl)) - prefix = ".tls$"; + prefix = ".tls$$"; else prefix = ".data$"; len = strlen (name) + strlen (prefix); @@ -522,9 +525,6 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags, *f++ = 'e'; #endif - if (strcmp (name, ".tls$") == 0) - *f++ = 'd'; - if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0) /* readonly data */ { @@ -533,6 +533,8 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags, } else { + if (startswith (name, ".tls$")) + *f++ = 'd'; if (flags & SECTION_CODE) *f++ = 'x'; if (flags & SECTION_WRITE) diff --git a/gcc/testsuite/gcc.dg/tls/data-sections-1.c b/gcc/testsuite/gcc.dg/tls/data-sections-1.c new file mode 100644 index 0000000..c829256 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tls/data-sections-1.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ +/* { dg-require-effective-target tls_runtime } */ +/* { dg-options "-fdata-sections" } */ +/* { dg-add-options tls } */ + +__thread int i = 1; + +int main (void) +{ + if (i != 1) + __builtin_abort (); + + return 0; +} |
