diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -1593,6 +1593,15 @@ funcSym->unwindEntry = isec; ehRelocator.commit(); } + + // __eh_frame is marked as S_ATTR_LIVE_SUPPORT in input files, because FDEs + // are normally required to be kept alive if they reference a live symbol. + // However, we've explicitly marked a dependency from a symbol to its FDE, so + // dead-stripping will just work as usual, and S_ATTR_LIVE_SUPPORT will just + // incorrectly prevent us from dead-stripping duplicate FDEs for a live symbol + // (e.g. if there were multiple weak copies). Remove this flag and just let + // dead-stripping proceed as normal. + ehFrameSection.flags &= ~S_ATTR_LIVE_SUPPORT; } std::string ObjFile::sourceFile() const { diff --git a/lld/test/MachO/eh-frame-dead-strip.s b/lld/test/MachO/eh-frame-dead-strip.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/eh-frame-dead-strip.s @@ -0,0 +1,37 @@ +# REQUIRES: aarch64 +# RUN: rm -rf %t; split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11.0 %t/strong.s -o %t/strong.o +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11.0 %t/weak.s -o %t/weak.o +# RUN: %lld -arch arm64 -dylib -dead_strip %t/strong.o %t/weak.o -o %t/libstrongweak.dylib +# RUN: llvm-dwarfdump --eh-frame %t/libstrongweak.dylib | FileCheck %s + +## Verify that unneeded FDEs (and their CIEs) are dead-stripped even if they +## point to a live symbol. This requires arm64 because x86_64 doesn't emit +## a relocation for the function symbol in an FDE. + +# CHECK: .eh_frame contents: +# CHECK: 00000000 00000010 00000000 CIE +# CHECK: 00000014 00000020 00000018 FDE cie=00000000 +# CHECK-NOT: CIE +# CHECK-NOT: FDE + +#--- strong.s +.globl _fun +_fun: + .cfi_startproc + .cfi_def_cfa_offset 0 + ## cfi_escape cannot be encoded in compact unwind + .cfi_escape 0x2e, 0x10 + ret + .cfi_endproc + +#--- weak.s +.globl _fun +.weak_definition _fun +_fun: + .cfi_startproc + .cfi_def_cfa_offset 0 + ## cfi_escape cannot be encoded in compact unwind + .cfi_escape 0x2e, 0x10 + ret + .cfi_endproc