Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Collaborator

@smithp35 smithp35 Oct 9, 2025

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)

Copy link
Contributor Author

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?

Copy link
Collaborator

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.

// 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.
Expand Down
25 changes: 25 additions & 0 deletions lld/test/ELF/eh-frame-syms.s
Original file line number Diff line number Diff line change
@@ -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