diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2226,8 +2226,25 @@ 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(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 --- /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