ref_addr size changed between v2 and v3 - take 2 (#273)
authorSeva Alekseyev <sevaa@yarxi.ru>
Sat, 7 Mar 2020 13:34:29 +0000 (08:34 -0500)
committerGitHub <noreply@github.com>
Sat, 7 Mar 2020 13:34:29 +0000 (05:34 -0800)
commit4ff90bf696330b5ab2839f3c90cd6386ab499fa9
tree3507c0f1a2264f445ca3819f86a896323712a6fe
parent934345e26369527e8936e716b77f1739d78c1ea2
ref_addr size changed between v2 and v3 - take 2 (#273)

In DWARF 2, the DW_FORM_ref_addr format matches the target address size, while in DWARF3+ it matches the bitness of the CU record. Here are the relevant fragments from the spec, part 7:

v2:

    The second type of reference is the address of any debugging information entry within the same executable or shared object; it may refer to an entry in a different compilation unit from the unit containing the reference. This type of reference (DW_FORM_ref_addr) is the size of an address on the target architecture; it is relocatable in a relocatable object file and relocated in an executable file or shared object.

v3:

    The second type of reference can identify any debugging information entry within a program; in particular, it may refer to an entry in a different compilation unit from the unit containing the reference, and may refer to an entry in a different shared object. This type of reference (DW_FORM_ref_addr) is an offset from the beginning of the .debug_info section of the target executable or shared object; it is relocatable in a relocatable object file and frequently relocated in an executable file or shared object. For references from one shared object or static executable file to another, the relocation and identification of the target object must be performed by the consumer. In the 32-bit DWARF format, this offset is a 4-byte unsigned value; in the 64-bit DWARF format, it is an 8-byte unsigned value (see Section 7.4).

If elftools encounters 32-bit DWARF v2 targeting a 64-bit architecture, it will misparse DW_FORM_ref_addr and crash downstream.

I encountered this in an iOS binary from 2017, built with Xcode several versions ago for ARM64. This probably never came up before because by the time 64 bit code became relevant, most toolchains would generate DWARF 3 or newer.

Co-authored-by: Seva Alekseyev <sevaa@nih.gov>
elftools/dwarf/dwarfinfo.py
elftools/dwarf/structs.py
test/test_refaddr_bitness.py [new file with mode: 0644]
test/testfiles_for_unittests/arm64_on_dwarfv2.abbrev.dat [new file with mode: 0644]
test/testfiles_for_unittests/arm64_on_dwarfv2.info.dat [new file with mode: 0644]
test/testfiles_for_unittests/arm64_on_dwarfv2.str.dat [new file with mode: 0644]