https://sourceware.org/bugzilla/show_bug.cgi?id=33864
Bug ID: 33864
Summary: ld --eh-frame-hdr: Support DW_EH_PE_sdata8 encoding
Product: binutils
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: i at maskray dot me
Target Milestone: ---
When generating the .eh_frame_hdr section, GNU ld currently hardcodes
`DW_EH_PE_pcrel | DW_EH_PE_sdata4` for the `eh_frame_ptr_enc` field and
`DW_EH_PE_datarel | DW_EH_PE_sdata4` for the table_enc field.
This limits all offsets in the binary search table (and the eh_frame pointer)
to the signed 32-bit range (±2 GiB).
When linking executables that use the medium or large code model (e.g.,
-mcmodel=large on x86-64), the distance between .eh_frame_hdr and .text (or
.eh_frame) can easily exceed this 32-bit range.
The following linker script (which works with both GNU ld and LLVM linker) can
be utilized to move .eh_frame_hdr far away .text to simulate a large executable
without actually creating a large file.
% /tmp/Rel/bin/clang++ -mcmodel=large a.cc -o a -fuse-ld=bfd -Wl,-T,a.lds
/usr/bin/ld.bfd: .eh_frame_hdr entry overflow
/usr/bin/ld.bfd: final link failed: bad value
clang++: error: linker command failed with exit code 1 (use -v to see
invocation)
% cat a.cc
#include <stdio.h>
int main() { try { throw 1; } catch (...) { puts("a"); } }
% cat a.lds
SECTIONS
{
. = SIZEOF_HEADERS;
.eh_frame : { *(.eh_frame) }
.rodata.cst4 : {}
.text : { *(.text .text.*) }
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)))
KEEP (*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
KEEP (*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
}
. = DATA_SEGMENT_RELRO_END (0, .);
.data : { *(.data .data.*) }
. = .;
.bss : { *(.bss .bss.*) *(COMMON) }
. = DATA_SEGMENT_END (.);
/// Comment out the following line to avoid the error
.eh_frame_hdr 0x200000000 : {}
}
Adopting the DW_EH_PE_sdata8 encoding would fix the linker error.
I've tested that libgcc has a working DW_EH_PE_sdata8 decoder support.
--
You are receiving this mail because:
You are on the CC list for the bug.