diff options
author | Shoaib Meenai <smeenai@fb.com> | 2022-08-22 22:55:41 +0300 |
---|---|---|
committer | Tobias Hieta <tobias@hieta.se> | 2022-09-14 08:14:57 +0200 |
commit | a5ae700c67ec3d814249b1edfb40e6ca39b94eac (patch) | |
tree | a05993d365d6fa7324c730bd33edcc5a5f65d98f | |
parent | c51a59d8a9470bb06edc9305135c59c19de96011 (diff) | |
download | llvm-a5ae700c67ec3d814249b1edfb40e6ca39b94eac.tar.gz |
[MachO] Fix dead-stripping __eh_frame
This section is marked S_ATTR_LIVE_SUPPORT in input files, which meant
that on arm64, we were unnecessarily preserving FDEs if we e.g. had
multiple weak definitions for a function. Worse, we would actually
produce an invalid `__eh_frame` section in that case, because the CIE
associated with the unnecessary FDE would still get dead-stripped and
we'd end up with a dangling FDE. We set up associations from functions
to their FDEs, so dead-stripping will just work naturally, and we can
clear S_ATTR_LIVE_SUPPORT from our input `__eh_frame` sections to fix
dead-stripping.
Reviewed By: #lld-macho, int3
Differential Revision: https://reviews.llvm.org/D132489
(cherry picked from commit a745e47900dde15c180d5caea7a1d292ca809eb1)
-rw-r--r-- | lld/MachO/InputFiles.cpp | 9 | ||||
-rw-r--r-- | lld/test/MachO/eh-frame-dead-strip.s | 46 |
2 files changed, 55 insertions, 0 deletions
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index fd0e4ec8834c..87034d41e87d 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -1587,6 +1587,15 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) { 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 created a dependency from a symbol to its FDE, so + // dead-stripping will just work as usual, and S_ATTR_LIVE_SUPPORT will only + // serve to incorrectly prevent us from dead-stripping duplicate FDEs for a + // live symbol (e.g. if there were multiple weak copies). Remove this flag to + // let dead-stripping proceed correctly. + 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 index 000000000000..c9eb8c167720 --- /dev/null +++ b/lld/test/MachO/eh-frame-dead-strip.s @@ -0,0 +1,46 @@ +# REQUIRES: x86, aarch64 + +# RUN: rm -rf %t; split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 %t/strong.s -o %t/strong_x86_64.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 %t/weak.s -o %t/weak_x86_64.o +# RUN: %lld -dylib -dead_strip %t/strong_x86_64.o %t/weak_x86_64.o -o %t/libstrongweak_x86_64.dylib +# RUN: llvm-dwarfdump --eh-frame %t/libstrongweak_x86_64.dylib | FileCheck --check-prefixes CHECK,X86_64 %s +# RUN: %lld -dylib -dead_strip %t/weak_x86_64.o %t/strong_x86_64.o -o %t/libweakstrong_x86_64.dylib +# RUN: llvm-dwarfdump --eh-frame %t/libweakstrong_x86_64.dylib | FileCheck --check-prefixes CHECK,X86_64 %s + +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11.0 %t/strong.s -o %t/strong_arm64.o +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11.0 %t/weak.s -o %t/weak_arm64.o +# RUN: %lld -arch arm64 -dylib -dead_strip %t/strong_arm64.o %t/weak_arm64.o -o %t/libstrongweak_arm64.dylib +# RUN: llvm-dwarfdump --eh-frame %t/libstrongweak_arm64.dylib | FileCheck --check-prefixes CHECK,ARM64 %s +# RUN: %lld -arch arm64 -dylib -dead_strip %t/weak_arm64.o %t/strong_arm64.o -o %t/libweakstrong_arm64.dylib +# RUN: llvm-dwarfdump --eh-frame %t/libweakstrong_arm64.dylib | FileCheck --check-prefixes CHECK,ARM64 %s + +## Verify that unneeded FDEs (and their CIEs) are dead-stripped even if they +## point to a live symbol (e.g. because we had multiple weak definitions). + +# CHECK: .eh_frame contents: +# X86_64: 00000000 00000014 00000000 CIE +# X86_64: 00000018 0000001c 0000001c FDE cie=00000000 +# ARM64: 00000000 00000010 00000000 CIE +# ARM64: 00000014 00000018 00000018 FDE cie=00000000 +# CHECK-NOT: CIE +# CHECK-NOT: FDE + +#--- strong.s +.globl _fun +_fun: + .cfi_startproc + ## cfi_escape cannot be encoded in compact unwind + .cfi_escape 0 + ret + .cfi_endproc + +#--- weak.s +.globl _fun +.weak_definition _fun +_fun: + .cfi_startproc + ## cfi_escape cannot be encoded in compact unwind + .cfi_escape 0 + ret + .cfi_endproc |