https://sourceware.org/bugzilla/show_bug.cgi?id=34884

            Bug ID: 34884
           Summary: objdump --dwarf=frames: FDE PC Begin and PC Range with
                    DW_EH_PE_uleb128 or DW_EH_PE_sleb128 encoding read as
                    eh_addr_size bytes
           Product: binutils
           Version: 2.47
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: i at mi11ion dot io
  Target Milestone: ---
              Host: aarch64-apple-darwin

Created attachment 17202
  --> https://sourceware.org/bugzilla/attachment.cgi?id=17202&action=edit
uleb.o, sleb.o, udata8.o (+ .s): Mach-O objects with an __eh_frame FDE in
uleb128/sleb128/udata8 encoding.

Environment: GNU objdump (GNU Binutils) 2.47.20260726, Homebrew binutils 2.47
on macOS 27.0 (arm64). The code is unchanged on master at 1c79f853160d.

Reproducer: the attached eh-frame-leb128.tar.gz holds uleb.o and sleb.o (480
bytes each, Mach-O arm64 objects, assembled from uleb.s / sleb.s with "as -arch
arm64"). Each holds one __eh_frame section of 36 bytes: a "zR" CIE whose 'R'
byte is 0x01 (uleb.o) or 0x09 (sleb.o), and one FDE whose PC Begin is the
LEB128 "80 20" (0x1000) and PC Range is "20" (0x20). The section of uleb.o:

10 00 00 00  00 00 00 00  01 7a 52 00  01 78 1e 01
01 0c 1f 00  0c 00 00 00  18 00 00 00  80 20 20 00
44 0e 10 00

udata8.o (496 bytes, from udata8.s) is a control with the same FDE in
DW_EH_PE_udata8 (0x04), which objdump prints as expected below.

Command: objdump --dwarf=frames uleb.o

Actual:

00000014 000000000000000c 00000018 FDE cie=00000000
pc=00100e4400202080..00100e4400202080

preceded by "objdump: Error: end of data encountered whilst reading LEB", and
no CFI instructions for the FDE. --dwarf=frames-interp prints the same FDE line
and no rows.

Expected:

00000014 000000000000000c 00000018 FDE cie=00000000
pc=0000000000001000..0000000000001020
  DW_CFA_advance_loc: 4 to 0000000000001004
  DW_CFA_def_cfa_offset: 16
  DW_CFA_nop

llvm-dwarfdump --eh-frame prints pc=00001000...00001020 and the three
instructions for both files.

Analysis: LSB Core 5.0 Table 10-5 defines DW_EH_PE_uleb128 (0x01) and
DW_EH_PE_sleb128 (0x09) as LEB128-encoded values. size_of_encoded_value
(binutils/dwarf.c:203) switches on encoding & 0x7 and returns eh_addr_size for
the unlisted format 1 (default: /* ??? */). display_debug_frames uses it for PC
Begin through get_encoded_value (dwarf.c:11086) and for PC Range through
SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size, block_end)
(dwarf.c:11093), so both fields are read as 8-byte integers: PC Begin takes the
8 bytes "80 20 20 00 44 0e 10 00", PC Range finds no bytes left and is 0, and
the augmentation length read fails at the end of the FDE. read_cie skips a 'P'
personality pointer with q += 1 + size_of_encoded_value (*q) (dwarf.c:10492),
so a 'P' encoding of 0x01 or 0x09 skips past the augmentation data and the 'L'
and 'R' bytes after it are not read.

The FDE fields and the CIE's 'P' argument need to be decoded as LEB128 when the
encoding's format is uleb128 or sleb128, rather than read with the fixed size
from size_of_encoded_value.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to