dwarf_func_inline.c dwarf_getsrc_file.c \
libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c \
libdw_visit_scopes.c \
- dwarf_entry_breakpoints.c dwarf_readhooks.c
+ dwarf_entry_breakpoints.c libdw_readhooks.c
if MAINTAINER_MODE
BUILT_SOURCES = $(srcdir)/known-dwarf.h
return -1;
}
- if (__libdw_read_addr (attr->cu->dbg, return_addr, attr->valp,
- attr->cu->address_size == 8))
- return -1l;
+ if (__libdw_read_address (attr->cu->dbg,
+ IDX_debug_info, attr->valp,
+ attr->cu->address_size, return_addr))
+ return -1;
return 0;
}
? attr->cu->address_size
: attr->cu->offset_size);
- if (__libdw_read_addr (attr->cu->dbg, &offset,
- attr->valp, ref_size == 8))
+ if (__libdw_read_address (attr->cu->dbg,
+ IDX_debug_info, attr->valp,
+ ref_size, &offset))
return NULL;
}
else
Dwarf_Addr begin;
Dwarf_Addr end;
- bool addr64 = attr->cu->address_size == 8;
- Dwarf_Addr escape = addr64 ? (Elf64_Addr)-1 : (Elf64_Addr)(Elf32_Addr)-1;
-
- if (__libdw_read_addr_inc (attr->cu->dbg, &begin, &readp, addr64)
- || __libdw_read_addr_inc (attr->cu->dbg, &end, &readp, addr64))
+ Dwarf_Addr escape = ADDR_ESCAPE (attr->cu->address_size);
+
+ if (__libdw_read_address_inc (attr->cu->dbg,
+ IDX_debug_line, &readp,
+ attr->cu->address_size, &begin)
+ || __libdw_read_address_inc (attr->cu->dbg,
+ IDX_debug_line, &readp,
+ attr->cu->address_size, &end))
goto invalid;
if (begin == escape)
}
/* Get the CU offset. */
- if (__libdw_read_addr (dbg, &mem[cnt].cu_offset,
- readp + 2, len_bytes == 8))
+ if (__libdw_read_address (dbg, IDX_debug_pubnames, readp + 2, len_bytes,
+ &mem[cnt].cu_offset))
/* Error has been already set in reader. */
goto err_return;
while (1)
{
/* READP points to the next offset/name pair. */
- if (__libdw_read_addr_inc (dbg, &gl.die_offset, &readp,
- dbg->pubnames_sets[cnt].address_len == 8))
+ if (__libdw_read_address_inc (dbg, IDX_debug_pubnames, &readp,
+ dbg->pubnames_sets[cnt].address_len,
+ &gl.die_offset))
return -1l;
/* If the offset is zero we reached the end of the set. */
#include <libintl.h>
#include <stdbool.h>
+#include <assert.h>
#include <libdw.h>
/* Reader hooks. */
+static inline int
+__libdw_in_section (Dwarf *dbg, int sec_index,
+ unsigned char *addr, int width)
+{
+ Elf_Data *data = dbg->sectiondata[sec_index];
-int __libdw_read_addr_inc (Dwarf *dbg, Dwarf_Word *ret,
- unsigned char **addr,
- bool addr64)
- internal_function;
+ if ((void *)addr < data->d_buf
+ || (void *)addr + width > data->d_buf + data->d_size)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+ return 1;
+ }
-int __libdw_read_off_inc (Dwarf *dbg, Dwarf_Word *ret,
- int sec_index, Dwarf_Word *offset,
- bool addr64)
- internal_function;
+ return 0;
+}
-int __libdw_read_addr (Dwarf *dbg, Dwarf_Word *ret,
- unsigned char *addr,
- bool addr64)
+int __libdw_relocate_address (Dwarf *dbg,
+ int sec_index, uintptr_t addr,
+ int width, Dwarf_Addr *val)
internal_function;
-int __libdw_read_off (Dwarf *dbg, Dwarf_Word *ret,
- int sec_index, Dwarf_Word offset,
- bool addr64)
+int __libdw_relocate_offset (Dwarf *dbg,
+ int sec_index, uintptr_t addr,
+ int width, Dwarf_Addr *val)
internal_function;
+#define READ_AND_RELOCATE(RELOC_HOOK) \
+ { \
+ int status; \
+ if ((status = __libdw_in_section (dbg, sec_index, *addr, width))) \
+ return status; \
+ \
+ uintptr_t addr0 = (uintptr_t)*addr; \
+ Dwarf_Addr val; \
+ \
+ if (width == 4) \
+ val = read_4ubyte_unaligned_inc (dbg, *addr); \
+ else \
+ { \
+ assert (width == 8); \
+ val = read_8ubyte_unaligned_inc (dbg, *addr); \
+ } \
+ \
+ if ((status = RELOC_HOOK (dbg, sec_index, addr0, width, &val))) \
+ return status; \
+ \
+ *ret = val; \
+ return 0; \
+ }
+
+static inline int
+__libdw_read_address_inc (Dwarf *dbg,
+ int sec_index, unsigned char **addr,
+ int width, Dwarf_Addr *ret)
+{
+ READ_AND_RELOCATE (__libdw_relocate_address)
+}
+
+static inline int
+__libdw_read_offset_inc (Dwarf *dbg,
+ int sec_index, unsigned char **addr,
+ int width, Dwarf_Addr *ret)
+{
+ READ_AND_RELOCATE (__libdw_relocate_offset)
+}
+
+#undef READ_AND_RELOCATE
+
+static inline int
+__libdw_read_address (Dwarf *dbg,
+ int sec_index, unsigned char *addr,
+ int width, Dwarf_Addr *ret)
+{
+ return __libdw_read_address_inc (dbg, sec_index, &addr, width, ret);
+}
+
+static inline int
+__libdw_read_offset (Dwarf *dbg,
+ int sec_index, unsigned char *addr,
+ int width, Dwarf_Addr *ret)
+{
+ return __libdw_read_offset_inc (dbg, sec_index, &addr, width, ret);
+}
+
+#define ADDR_ESCAPE(width) \
+ (width == 8 ? (Elf64_Addr)-1 : (Elf64_Addr)(Elf32_Addr)-1)
+
/* Aliases to avoid PLTs. */
# include <config.h>
#endif
-#include <dwarf.h>
#include "libdwP.h"
-int
-__libdw_read_addr_inc (Dwarf *dbg, Dwarf_Word *ret,
- unsigned char **addr,
- bool addr64)
+internal_function int
+__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
+ int sec_index __attribute__ ((unused)),
+ uintptr_t addr __attribute__ ((unused)),
+ int width __attribute__ ((unused)),
+ Dwarf_Addr *val __attribute__ ((unused)))
{
- if (addr64)
- *ret = read_8ubyte_unaligned_inc (dbg, *addr);
- else
- *ret = read_4ubyte_unaligned_inc (dbg, *addr);
return 0;
}
-int
-__libdw_read_off_inc (Dwarf *dbg, Dwarf_Word *ret,
- int sec_index, Dwarf_Word *offset,
- bool addr64)
+internal_function int
+__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
+ int sec_index __attribute__ ((unused)),
+ uintptr_t addr __attribute__ ((unused)),
+ int width __attribute__ ((unused)),
+ Dwarf_Addr *val __attribute__ ((unused)))
{
- Elf_Data *data = dbg->sectiondata[sec_index];
- if (*offset >= data->d_size
- || *offset + addr64 ? 8 : 4 >= data->d_size)
- {
- __libdw_seterrno (DWARF_E_INVALID_OFFSET);
- return 1;
- }
-
- unsigned char *buf = data->d_buf;
- unsigned char *addr = buf + *offset;
- int status = __libdw_read_addr_inc (dbg, ret, &addr, addr64);
- *offset = addr - buf;
- return status;
-}
-
-int
-__libdw_read_addr (Dwarf *dbg, Dwarf_Word *ret,
- unsigned char *addr,
- bool addr64)
-{
- return __libdw_read_addr_inc (dbg, ret, &addr, addr64);
-}
-
-int
-__libdw_read_off (Dwarf *dbg, Dwarf_Word *ret,
- int sec_index, Dwarf_Word offset,
- bool addr64)
-{
- return __libdw_read_off_inc (dbg, ret, sec_index, &offset, addr64);
+ return 0;
}