Fangrui Song 96448ef34a
[llvm-readelf] --unwind: Support DW_EH_PE_sdata8 encoding (#179152)
... for both eh_frame_ptr_enc and table_enc fields when parsing the
PT_GNU_EH_FRAME program header (which contains .eh_frame_hdr) . This is
needed for large binaries where offsets exceed the 32-bit range,

The sdata8 encoding has been tested on an executable
generated by lld patched with
https://github.com/llvm/llvm-project/pull/179089

```
 % cat a.cc
  #include <stdio.h>
int main() { try { throw 1; } catch (...) { puts("a"); } }
% cat a.lds
SECTIONS
{
  . = SIZEOF_HEADERS;

  .eh_frame : {}
  .rodata.cst4 : {}
  .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 (.);

  .eh_frame_hdr 0x200000000 : {}
}
% /tmp/Rel/bin/clang++ -mcmodel=large a.cc -o a -fuse-ld=lld -Wl,a.lds
% ./a
```

The executable uses C++ exceptions. At runtime the libstdc++/libgcc
runtime
decodes the PT_GNU_EH_FRAME segment. A malformed .eh_frame_hdr would
lead to crash.

Previously, llvm-readelf would report "unexpected encoding
eh_frame_ptr_enc"
or "unexpected encoding table_enc" for .eh_frame_hdr sections using
sdata8.
2026-02-04 09:26:04 -08:00
..