summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2022-03-02 12:33:31 +0200
committerTom Stellard <tstellar@redhat.com>2022-03-07 14:38:09 -0800
commit43b4544023b73d334b5f60edaf7e1dcce4c75d3f (patch)
treeb5f9807b27ce4bc15d09c38a15cc75f06d7c986a
parente6d2aa9b0f131a141166d1d90560f1a2d1d9ec5c (diff)
[LLD] [COFF] Order .debug_* sections at the end, to avoid leaving gaps if stripped
So far, we sort all discardable sections at the end, with only some extra logic to make sure that the .reloc section is at the start of that group of sections. But if there are other discardable sections, other than .reloc, they must also be ordered before .debug_* sections, to avoid leaving gaps if the executable is stripped. (Stripping executables doesn't remove all discardable sections, only the ones named .debug_*). Rust binaries seem to include a .rmeta section, which is marked discardable. This fixes stripping such binaries if built with dwarf debug info included. This fixes issues observed in MSYS2 in https://github.com/msys2/MINGW-packages/pull/10555. Differential Revision: https://reviews.llvm.org/D120805 (cherry picked from commit 4c3b74b7f5d6192d1731c88f1aeb396bc51d4949)
-rw-r--r--lld/COFF/Writer.cpp8
-rw-r--r--lld/test/COFF/sort-debug.test6
2 files changed, 13 insertions, 1 deletions
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 12db942f1db5..1ed2327ea630 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -926,8 +926,14 @@ void Writer::createSections() {
// Move DISCARDABLE (or non-memory-mapped) sections to the end of file
// because the loader cannot handle holes. Stripping can remove other
// discardable ones than .reloc, which is first of them (created early).
- if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
+ if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) {
+ // Move discardable sections named .debug_ to the end, after other
+ // discardable sections. Stripping only removes the sections named
+ // .debug_* - thus try to avoid leaving holes after stripping.
+ if (s->name.startswith(".debug_"))
+ return 3;
return 2;
+ }
// .rsrc should come at the end of the non-discardable sections because its
// size may change by the Win32 UpdateResources() function, causing
// subsequent sections to move (see https://crbug.com/827082).
diff --git a/lld/test/COFF/sort-debug.test b/lld/test/COFF/sort-debug.test
index d8fd7ae60564..bbe2ecd0efd8 100644
--- a/lld/test/COFF/sort-debug.test
+++ b/lld/test/COFF/sort-debug.test
@@ -10,6 +10,7 @@
# CHECK: Name: .text
# CHECK: Name: .reloc
+# CHECK: Name: .rmeta
# CHECK: Name: .debug_abbrev
# CHECK: Name: .debug_info
# CHECK: Name: .debug_line
@@ -18,6 +19,7 @@
# NODEBUG: Name: .text
# NODEBUG: Name: .reloc
+# NODEBUG: Name: .rmeta
# NODEBUG-NOT: Name: .debug_abbrev
# NODEBUG-NOT: Name: .debug_info
# NODEBUG-NOT: Name: .debug_line
@@ -183,6 +185,10 @@ sections:
- VirtualAddress: 43
SymbolName: .text
Type: IMAGE_REL_I386_DIR32
+ - Name: .rmeta
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ SectionData: 00112233
symbols:
- Name: .text
Value: 0