-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[LLD] Make lld define __eh_frame_* symbols #162638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Libunwind needs the following symbols for exception handling __eh_frame_start __eh_frame_end __eh_frame_hdr_start __eh_frame_hdr_end Instead of using a linker script just to define these symbols, let the linker define them as standard symbols. Now we can create static executable with libunwind without a linker script. Signed-off-by: Kushal Pal <[email protected]>
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-elf Author: None (quic-k) ChangesThis patch makes LLD explicitly define the following symbols during linking:
These are expected by libunwind for exception handling in baremetal builds I am interested in feedback on this change Full diff: https://github.com/llvm/llvm-project/pull/162638.diff 2 Files Affected:
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 4fa80397cbfa7..145bff5007466 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2269,6 +2269,12 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
define("__preinit_array_start", "__preinit_array_end", ctx.out.preinitArray);
define("__init_array_start", "__init_array_end", ctx.out.initArray);
define("__fini_array_start", "__fini_array_end", ctx.out.finiArray);
+ // Define __eh_frame_* symbols, libunwind needs these symbols.
+ // Define them only if the corresponding output section exists.
+ if (OutputSection *sec = findSection(ctx, ".eh_frame"))
+ define("__eh_frame_start", "__eh_frame_end", sec);
+ if (OutputSection *sec = findSection(ctx, ".eh_frame_hdr"))
+ define("__eh_frame_hdr_start", "__eh_frame_hdr_end", sec);
// As a special case, don't unnecessarily retain .ARM.exidx, which would
// create an empty PT_ARM_EXIDX.
diff --git a/lld/test/ELF/eh-frame-syms.s b/lld/test/ELF/eh-frame-syms.s
new file mode 100644
index 0000000000000..074221ade4fb6
--- /dev/null
+++ b/lld/test/ELF/eh-frame-syms.s
@@ -0,0 +1,25 @@
+## Verify that lld defines __eh_frame_start/end and __eh_frame_hdr_start/end symbols
+
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -eh-frame-hdr -o %t
+# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYM
+
+# SYM: __eh_frame_start
+# SYM: __eh_frame_end
+# SYM: __eh_frame_hdr_start
+# SYM: __eh_frame_hdr_end
+
+.text
+.globl _start
+.type _start, @function
+_start:
+ nop
+
+# Emit references so the link will fail if these are not defined
+check_symbol:
+ .quad __eh_frame_start
+ .quad __eh_frame_end
+ .quad __eh_frame_hdr_start
+ .quad __eh_frame_hdr_end
|
define("__preinit_array_start", "__preinit_array_end", ctx.out.preinitArray); | ||
define("__init_array_start", "__init_array_end", ctx.out.initArray); | ||
define("__fini_array_start", "__fini_array_end", ctx.out.finiArray); | ||
// Define __eh_frame_* symbols, libunwind needs these symbols. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The __eh_frame_*
symbols are equivalent to __exidx_start
and __exidx_end
so this seems reasonable to me.
llvm libunwind reference with suggested linker script fragment (https://github.com/llvm/llvm-project/blob/main/libunwind/src/AddressSpace.hpp#L75)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, with this patch we won't have to use that fragment just to provide these symbols
IIUC __exidx_start/end are ARM's version of __eh_frame_start/end, right?
does lld define them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, just below on line 2281. I think I added that before we had good linker script support, could also be that some unwinders even on Linux might use those symbols.
These symbols not even in GNU ld's internal linker script. I think you should explicitly define them in linker scripts:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
This patch makes LLD explicitly define the following symbols during linking:
__eh_frame_start
__eh_frame_end
__eh_frame_hdr_start
__eh_frame_hdr_end
These are expected by libunwind for exception handling in baremetal builds
Right now, these symbols need to be explicitly defined by the linker script.
I think its better that the linker defines them implicitly, so we don't have to create a linker script only because we needed to provide these symbols
I am interested in feedback on this change