[lld] 7e07683 - [LLD] [COFF] Fix including the personality function for DWARF EH when linking with --gc-sections
Martin Storsjö via llvm-commits
llvm-commits at lists.llvm.org
Wed May 12 12:23:25 PDT 2021
Author: Martin Storsjö
Date: 2021-05-12T22:23:01+03:00
New Revision: 7e0768329ca347e37c7bdb0da16b51cb3e7b7d8b
URL: https://github.com/llvm/llvm-project/commit/7e0768329ca347e37c7bdb0da16b51cb3e7b7d8b
DIFF: https://github.com/llvm/llvm-project/commit/7e0768329ca347e37c7bdb0da16b51cb3e7b7d8b.diff
LOG: [LLD] [COFF] Fix including the personality function for DWARF EH when linking with --gc-sections
Since c579a5b1d92a9bc2046d00ee2d427832e0f5ddec we don't traverse
.eh_frame when doing GC. But the exception handling personality
function needs to be included, and is only referenced from within
.eh_frame.
Differential Revision: https://reviews.llvm.org/D102138
Added:
lld/test/COFF/gc-dwarf-eh.s
Modified:
lld/COFF/Driver.cpp
Removed:
################################################################################
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index e2374b52b4f9f..029148c4722bb 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2226,8 +2226,25 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->printSymbolOrder = arg->getValue();
// Identify unreferenced COMDAT sections.
- if (config->doGC)
+ if (config->doGC) {
+ if (config->mingw) {
+ // markLive doesn't traverse .eh_frame, but the personality function is
+ // only reached that way. The proper solution would be to parse and
+ // traverse the .eh_frame section, like the ELF linker does.
+ // For now, just manually try to retain the known possible personality
+ // functions. This doesn't bring in more object files, but only marks
+ // functions that already have been included to be retained.
+ for (const char *n : {"__gxx_personality_v0", "__gcc_personality_v0"}) {
+ Defined *d = dyn_cast_or_null<Defined>(symtab->findUnderscore(n));
+ if (d && !d->isGCRoot) {
+ d->isGCRoot = true;
+ config->gcroot.push_back(d);
+ }
+ }
+ }
+
markLive(symtab->getChunks());
+ }
// Needs to happen after the last call to addFile().
convertResources();
diff --git a/lld/test/COFF/gc-dwarf-eh.s b/lld/test/COFF/gc-dwarf-eh.s
new file mode 100644
index 0000000000000..757aa671c7693
--- /dev/null
+++ b/lld/test/COFF/gc-dwarf-eh.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -triple=i686-windows-gnu %s -filetype=obj -o %t.obj
+# RUN: lld-link -lldmingw -lldmap:%t.map -out:%t.exe -opt:ref -entry:main %t.obj -verbose 2>&1 | FileCheck %s
+# RUN: FileCheck %s --check-prefix=MAP --input-file=%t.map
+
+# CHECK: Discarded _unused
+
+# MAP: In Symbol
+# MAP: gc-dwarf-eh.s.tmp.obj:(.text)
+# MAP: {{ ___gxx_personality_v0$}}
+
+ .def _main; .scl 2; .type 32; .endef
+ .section .text,"xr",one_only,_main
+ .globl _main
+ .cfi_startproc
+ .cfi_personality 0, ___gxx_personality_v0
+_main:
+ xorl %eax, %eax
+ ret
+ .cfi_endproc
+
+ .def ___gxx_personality_v0; .scl 2; .type 32; .endef
+ .section .text,"xr",one_only,___gxx_personality_v0
+ .globl ___gxx_personality_v0
+___gxx_personality_v0:
+ ret
+
+ .def _unused; .scl 2; .type 32; .endef
+ .section .text,"xr",one_only,_unused
+ .globl _unused
+ .cfi_startproc
+ .cfi_personality 0, ___gxx_personality_v0
+_unused:
+ ret
+ .cfi_endproc
More information about the llvm-commits
mailing list