summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_haspc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdw/dwarf_haspc.c')
-rw-r--r--libdw/dwarf_haspc.c78
1 files changed, 6 insertions, 72 deletions
diff --git a/libdw/dwarf_haspc.c b/libdw/dwarf_haspc.c
index 7f29296d..d2e737a5 100644
--- a/libdw/dwarf_haspc.c
+++ b/libdw/dwarf_haspc.c
@@ -25,81 +25,15 @@ dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc)
if (die == NULL)
return -1;
- /* Usually there is a single contiguous range. */
- Dwarf_Addr lowpc, highpc;
- if (INTUSE(dwarf_highpc) (die, &highpc) == 0
- && INTUSE(dwarf_lowpc) (die, &lowpc) == 0)
- return pc >= lowpc && pc < highpc;
-
- /* We have to look for a noncontiguous range. */
- Dwarf_Attribute attr_mem;
- Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges, &attr_mem);
- if (attr == NULL)
- return -1;
-
- /* Must have the form data4 or data8 which act as an offset. */
- Dwarf_Word offset;
- if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
- return -1;
-
- const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_ranges];
- if (d == NULL)
- {
- __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
- return -1;
- }
-
- /* Fetch the CU's base address. */
Dwarf_Addr base;
- Dwarf_Die cudie =
- {
- .cu = attr->cu,
- .addr = ((char *) attr->cu->dbg->sectiondata[IDX_debug_info]->d_buf
- + attr->cu->start + 3 * attr->cu->offset_size - 4 + 3),
- };
- if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
- return -1;
-
- unsigned char *readp = d->d_buf + offset;
Dwarf_Addr begin;
Dwarf_Addr end;
- do
- {
- next:
- if ((unsigned char *) d->d_buf + d->d_size - readp
- < attr->cu->address_size * 2)
- {
- __libdw_seterrno (DWARF_E_INVALID_DWARF);
- return -1;
- }
-
- if (attr->cu->address_size == 8)
- {
- begin = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
- end = read_8ubyte_unaligned_inc (attr->cu->dbg, readp);
- }
- else
- {
- begin = (Dwarf_Sword) read_4sbyte_unaligned_inc (attr->cu->dbg,
- readp);
- end = read_4ubyte_unaligned_inc (attr->cu->dbg, readp);
- }
-
- if (begin == (Dwarf_Addr) -1l) /* Base address entry. */
- {
- base = end;
- goto next;
- }
-
- if (begin == 0 && end == 0) /* End of list entry. */
- /* This is not the droid you are looking for. */
- return 0;
-
- /* We have an address range entry. */
- }
- while (pc < base + begin || pc >= base + end);
+ ptrdiff_t offset = 0;
+ while ((offset = INTUSE(dwarf_ranges) (die, offset, &base,
+ &begin, &end)) > 0)
+ if (pc >= begin && pc < end)
+ return 1;
- /* This one matches the address. */
- return 1;
+ return offset;
}
INTDEF (dwarf_haspc)