Skip to content

Commit

Permalink
addr2line.c: fix DW_FORM_ref_addr parsing for DWARF 2 (#8146)
Browse files Browse the repository at this point in the history
addr2line.c: fix DW_FORM_ref_addr parsing for DWARF 2

This fixes a crash when retrieving backtrace info with YJIT enabled on
macOS with Rust 1.71.0. Since Rust 1.71.0, the DWARF info generated by
the Rust compiler uses DW_FORM_ref_addr instead of DW_FORM_ref4 for
pointers to other DIEs.
DW_FORM_ref_addr representation in DWARF 2 is different from DWARF 3+,
so we need to handle it separately.
This patch fixes the parsing of DW_FORM_ref_addr for DWARF 2, which is
the default DWARF version Rustc uses on macOS.

See the DWARF 2.0.0 spec, section 7.5.4 Attribute Encodings
https://dwarfstd.org/doc/dwarf-2.0.0.pdf

https://bugs.ruby-lang.org/issues/19789
  • Loading branch information
kateinoigakukun committed Jul 31, 2023
1 parent 36d669b commit 954b7ac
Showing 1 changed file with 26 additions and 14 deletions.
40 changes: 26 additions & 14 deletions addr2line.c
Expand Up @@ -1152,19 +1152,25 @@ resolve_strx(DebugInfoReader *reader, uint64_t idx)
return reader->obj->debug_str.ptr + off;
}

static void
debug_info_reader_read_addr_value(DebugInfoReader *reader, DebugInfoValue *v)
{
if (reader->address_size == 4) {
set_uint_value(v, read_uint32(&reader->p));
} else if (reader->address_size == 8) {
set_uint_value(v, read_uint64(&reader->p));
} else {
fprintf(stderr,"unknown address_size:%d", reader->address_size);
abort();
}
}

static void
debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
{
switch (form) {
case DW_FORM_addr:
if (reader->address_size == 4) {
set_uint_value(v, read_uint32(&reader->p));
} else if (reader->address_size == 8) {
set_uint_value(v, read_uint64(&reader->p));
} else {
fprintf(stderr,"unknown address_size:%d", reader->address_size);
abort();
}
debug_info_reader_read_addr_value(reader, v);
break;
case DW_FORM_block2:
v->size = read_uint16(&reader->p);
Expand Down Expand Up @@ -1216,13 +1222,19 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, read_uleb128(reader));
break;
case DW_FORM_ref_addr:
if (reader->format == 4) {
set_uint_value(v, read_uint32(&reader->p));
} else if (reader->format == 8) {
set_uint_value(v, read_uint64(&reader->p));
if (reader->current_version <= 2) {
// DWARF Version 2 specifies that references have
// the same size as an address on the target system
debug_info_reader_read_addr_value(reader, v);
} else {
fprintf(stderr,"unknown format:%d", reader->format);
abort();
if (reader->format == 4) {
set_uint_value(v, read_uint32(&reader->p));
} else if (reader->format == 8) {
set_uint_value(v, read_uint64(&reader->p));
} else {
fprintf(stderr,"unknown format:%d", reader->format);
abort();
}
}
break;
case DW_FORM_ref1:
Expand Down

0 comments on commit 954b7ac

Please sign in to comment.