diff options
| author | Roland McGrath <[email protected]> | 2005-12-12 08:35:55 +0000 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2005-12-12 08:35:55 +0000 |
| commit | dec3a24331194d06145b28011336d121c3440ac7 (patch) | |
| tree | 0b2687a09281926da06218e142c1059752ea881c /libdw/dwarf_ranges.c | |
| parent | ba72ab102a8ca35371072311379d2474f8ec674f (diff) | |
2005-12-12 Roland McGrath <[email protected]>
* dwarf_ranges.c: Copy CU base address-finding code from
dwarf_getlocation.
Diffstat (limited to 'libdw/dwarf_ranges.c')
| -rw-r--r-- | libdw/dwarf_ranges.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c index 5d6710a0..007ffc8f 100644 --- a/libdw/dwarf_ranges.c +++ b/libdw/dwarf_ranges.c @@ -65,8 +65,26 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, assert ((Dwarf_Word) offset == start_offset); /* Fetch the CU's base address. */ - if (INTUSE(dwarf_lowpc) (&CUDIE (attr->cu), basep) != 0) - return -1; + Dwarf_Die cudie = CUDIE (attr->cu); + + /* Find the base address of the compilation unit. It will + normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, + the base address could be overridden by DW_AT_entry_pc. It's + been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc + for compilation units with discontinuous ranges. */ + if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0) + && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, + DW_AT_entry_pc, + &attr_mem), + basep) != 0) + { + if (INTUSE(dwarf_errno) () == 0) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + } + return -1; + } } else if (offset < 0 || (size_t) offset >= d->d_size) { @@ -79,10 +97,7 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, next: if ((unsigned char *) d->d_buf + d->d_size - readp < die->cu->address_size * 2) - { - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return -1; - } + goto invalid; Dwarf_Addr begin; Dwarf_Addr end; |
