summaryrefslogtreecommitdiff
path: root/libdw
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2005-12-12 08:35:55 +0000
committerRoland McGrath <roland@redhat.com>2005-12-12 08:35:55 +0000
commitdec3a24331194d06145b28011336d121c3440ac7 (patch)
tree0b2687a09281926da06218e142c1059752ea881c /libdw
parentba72ab102a8ca35371072311379d2474f8ec674f (diff)
downloadelfutils-dec3a24331194d06145b28011336d121c3440ac7.tar.gz
2005-12-12 Roland McGrath <roland@redhat.com>
* dwarf_ranges.c: Copy CU base address-finding code from dwarf_getlocation.
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/dwarf_ranges.c27
2 files changed, 26 insertions, 6 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 77c18ce4..a4e770de 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2005-12-12 Roland McGrath <roland@redhat.com>
+
+ * dwarf_ranges.c: Copy CU base address-finding code from
+ dwarf_getlocation.
+
2005-12-09 Roland McGrath <roland@redhat.com>
* dwarf_getlocation.c (dwarf_getlocation_addr): Add some unlikelys.
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;