* the use in dwarf_ranges is iffy, there's a functionality mismatch.
Need to find some better way
+2009-05-05 Petr Machata <pmachata@redhat.com>
+
+ * libdwP.h (__libdw_read_udata_addr): Declare new function.
+ * dwarf_formudata.c: Implement it here.
+ * dwarf_getlocation.c (dwarf_getlocation_addr):
+ Call it instead of hand-rolled offset handling code.
+ * dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+ * dwarf_ranges.c (dwarf_ranges): Likewise.
+
2009-05-04 Petr Machata <pmachata@redhat.com>
* libdwP.h (__libdw_read_begin_end_pair_inc): Declare new function.
#include <dwarf.h>
#include "libdwP.h"
+internal_function unsigned char *
+__libdw_read_udata_addr (Dwarf_Attribute *attr, int sec_index,
+ int err_nodata, unsigned char **endpp)
+{
+ if (attr == NULL)
+ return NULL;
+
+ Dwarf_Word offset;
+ switch (attr->form)
+ {
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp,
+ attr->form == DW_FORM_data4 ? 4 : 8,
+ &offset))
+ return NULL;
+ break;
+
+ default:
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return NULL;
+ };
+
+ const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
+ if (unlikely (d == NULL))
+ {
+ invalid:
+ __libdw_seterrno (err_nodata);
+ return NULL;
+ }
+
+ unsigned char *readp = d->d_buf + offset;
+ unsigned char *endp = d->d_buf + d->d_size;
+ if (readp >= endp)
+ goto invalid;
+
+ *endpp = endp;
+ return readp;
+}
int
dwarf_formudata (attr, return_uval)
break;
case DW_FORM_data4:
+ *return_uval = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
case DW_FORM_data8:
- if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp,
- attr->form == DW_FORM_data4 ? 4 : 8,
- return_uval))
- return -1;
+ *return_uval = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
break;
case DW_FORM_sdata:
return -1;
}
- /* Must have the form data4 or data8 which act as an offset. */
- Dwarf_Word offset;
- if (unlikely (INTUSE(dwarf_formudata) (attr, &offset) != 0))
+ unsigned char *endp, *readp
+ = __libdw_read_udata_addr (attr, IDX_debug_loc,
+ DWARF_E_NO_LOCLIST, &endp);
+ if (readp == NULL)
return -1;
- const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
- if (unlikely (d == NULL))
- {
- __libdw_seterrno (DWARF_E_NO_LOCLIST);
- return -1;
- }
-
Dwarf_Addr base = (Dwarf_Addr) -1;
- unsigned char *readp = d->d_buf + offset;
size_t got = 0;
while (got < maxlocs)
{
- if ((unsigned char *) d->d_buf + d->d_size - readp
- < attr->cu->address_size * 2)
+ if (endp - readp < attr->cu->address_size * 2)
{
invalid:
__libdw_seterrno (DWARF_E_INVALID_DWARF);
else if (status < 0)
return status;
- if ((unsigned char *) d->d_buf + d->d_size - readp < 2)
+ if (endp - readp < 2)
goto invalid;
/* We have a location expression. */
block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
block.data = readp;
- if ((unsigned char *) d->d_buf + d->d_size - readp
- < (ptrdiff_t) block.length)
+ if (endp - readp < (ptrdiff_t) block.length)
goto invalid;
readp += block.length;
/* Get the offset into the .debug_line section. NB: this call
also checks whether the previous dwarf_attr call failed. */
- Dwarf_Word offset;
- if (INTUSE(dwarf_formudata) (stmt_list, &offset) != 0)
+ const unsigned char *lineendp, *linep
+ = __libdw_read_udata_addr (stmt_list, IDX_debug_line,
+ DWARF_E_NO_DEBUG_LINE,
+ (unsigned char **) &lineendp);
+ if (linep == NULL)
goto out;
- Dwarf *dbg = cu->dbg;
- if (dbg->sectiondata[IDX_debug_line] == NULL)
- {
- __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
- goto out;
- }
- const uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset;
- const uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf
- + dbg->sectiondata[IDX_debug_line]->d_size);
-
/* Get the compilation directory. */
Dwarf_Attribute compdir_attr_mem;
Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
__libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
goto out;
}
+
+ Dwarf *dbg = cu->dbg;
Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
unsigned int length = 4;
if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges];
if (d == NULL && offset != 0)
{
- no_ranges:
__libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
return -1;
}
+ unsigned char *readp, *readendp;
if (offset == 0)
{
Dwarf_Attribute attr_mem;
/* No PC attributes in this DIE at all, so an empty range list. */
return 0;
- /* Must have the form data4 or data8 which act as an offset. */
- Dwarf_Word start_offset;
- if (INTUSE(dwarf_formudata) (attr, &start_offset) != 0)
+ if ((readp = __libdw_read_udata_addr (attr, IDX_debug_ranges,
+ DWARF_E_NO_DEBUG_RANGES,
+ &readendp)) == NULL)
return -1;
- if (d == NULL)
- goto no_ranges;
+ Dwarf_Word start_offset = (void *) readp - d->d_buf;
offset = start_offset;
assert ((Dwarf_Word) offset == start_offset);
return -1;
}
}
- else if (offset < 0 || (size_t) offset >= d->d_size)
+ else
{
- __libdw_seterrno (DWARF_E_INVALID_OFFSET);
- return -1l;
- }
+ if (offset < 0 || (size_t) offset >= d->d_size)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+ return -1l;
+ }
- unsigned char *readp = d->d_buf + offset;
+ readp = d->d_buf + offset;
+ readendp = d->d_buf + d->d_size;
+ }
next:
- if ((unsigned char *) d->d_buf + d->d_size - readp
- < die->cu->address_size * 2)
+ if (readendp - readp < die->cu->address_size * 2)
goto invalid;
Dwarf_Addr begin;
Dwarf_Addr *basep)
internal_function;
+unsigned char *
+__libdw_read_udata_addr (Dwarf_Attribute *attr, int sec_index,
+ int err_nodata, unsigned char **endpp)
+ internal_function;
+
static inline int
__libdw_read_address (Dwarf *dbg,
int sec_index, const unsigned char *addr,