summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2009-07-08 14:07:20 -0700
committerRoland McGrath <[email protected]>2009-07-08 14:07:20 -0700
commitbdb2e5030de6a36bc696aa031619cf9509015a83 (patch)
treef625265b990a9b2bfeca99dee61f3638d2c3fee7 /src
parentae3028b6ddc4143d592f94d2fb1a86e81411e884 (diff)
parent714f66a60f55dada62ac808cd5cffeddd1f4ad39 (diff)
Merge commit 'origin/master' into dwarf
Conflicts: libdw/ChangeLog src/ChangeLog
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/readelf.c93
2 files changed, 69 insertions, 35 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2ef1e42c..58198a8b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -203,6 +203,17 @@
* dwarflint.c: Checking for zero padding and unreferenced bytes.
CU size and padding at the end of CU are now checked.
+2009-07-08 Mark Wielaard <[email protected]>
+
+ * readelf.c (attr_callback): Handle DW_Form constants for
+ DW_AT_data_member_location.
+
+2009-07-06 Roland McGrath <[email protected]>
+
+ * readelf.c (register_info): New function. Handle unknown register #s.
+ (print_cfa_program): Use it.
+ (handle_core_register, handle_core_registers): Likewise.
+
2009-06-28 Roland McGrath <[email protected]>
* readelf.c (print_address_names): New static variable.
diff --git a/src/readelf.c b/src/readelf.c
index e925565b..28c73feb 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3732,6 +3732,35 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
}
}
+#define REGNAMESZ 16
+static const char *
+register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
+ char name[REGNAMESZ], int *bits, int *type)
+{
+ const char *set;
+ const char *pfx;
+ int ignore;
+ ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
+ bits ?: &ignore, type ?: &ignore);
+ if (n <= 0)
+ {
+ snprintf (name, sizeof name, "reg%u", loc->regno);
+ if (bits != NULL)
+ *bits = loc->bits;
+ if (type != NULL)
+ *type = DW_ATE_unsigned;
+ set = "??? unrecognized";
+ }
+ else
+ {
+ if (bits != NULL && *bits <= 0)
+ *bits = loc->bits;
+ if (type != NULL && *type == DW_ATE_void)
+ *type = DW_ATE_unsigned;
+
+ }
+ return set;
+}
static void
print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
@@ -3739,14 +3768,11 @@ print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
int data_align, unsigned int ptr_size, Dwfl_Module *dwflmod,
Ebl *ebl, Dwarf *dbg)
{
- char regnamebuf[16];
+ char regnamebuf[REGNAMESZ];
const char *regname (unsigned int regno)
{
- const char *str;
- int i;
- return (ebl_register_info (ebl, regno, regnamebuf, sizeof (regnamebuf),
- &str, &str, &i, &i) < 0
- ? "???" : regnamebuf);
+ register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
+ return regnamebuf;
}
puts ("\n Program:");
@@ -4526,9 +4552,20 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
const char *valuestr = NULL;
switch (attr)
{
+ /* This case can take either a constant or a loclistptr. */
+ case DW_AT_data_member_location:
+ if (form != DW_FORM_data4 && form != DW_FORM_data8)
+ {
+ printf (" %*s%-20s %" PRIxMAX "\n",
+ (int) (level * 2), "", dwarf_attr_string (attr),
+ (uintmax_t) num);
+ return DWARF_CB_OK;
+ }
+ /* else fallthrough */
+
+ /* These cases always take a loclistptr and no constant. */
case DW_AT_location:
case DW_AT_data_location:
- case DW_AT_data_member_location:
case DW_AT_vtable_elem_location:
case DW_AT_string_length:
case DW_AT_use_location:
@@ -6284,17 +6321,10 @@ handle_core_register (Ebl *ebl, Elf *core, int maxregname,
for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
{
- const char *pfx;
- const char *set;
- char name[16];
+ char name[REGNAMESZ];
int bits;
int type;
- ssize_t n = ebl_register_info (ebl, reg, name, sizeof name,
- &pfx, &set, &bits, &type);
- if (n <= 0)
- error (EXIT_FAILURE, 0,
- gettext ("unable to handle register number %d"),
- regloc->regno);
+ register_info (ebl, reg, regloc, name, &bits, &type);
#define TYPES \
BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8, 4); \
@@ -6382,10 +6412,10 @@ struct register_info
{
const Ebl_Register_Location *regloc;
const char *set;
- char name[16];
- Dwarf_Half regno;
- uint8_t bits;
- uint8_t type;
+ char name[REGNAMESZ];
+ int regno;
+ int bits;
+ int type;
};
static int
@@ -6439,8 +6469,12 @@ handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
if (maxnreg <= 0)
- error (EXIT_FAILURE, 0,
- gettext ("cannot get register info: %s"), elf_errmsg (-1));
+ {
+ for (size_t i = 0; i < nregloc; ++i)
+ if (maxnreg < reglocs[i].regno + reglocs[i].count)
+ maxnreg = reglocs[i].regno + reglocs[i].count;
+ assert (maxnreg > 0);
+ }
struct register_info regs[maxnreg];
memset (regs, 0, sizeof regs);
@@ -6456,20 +6490,9 @@ handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
if (reg > maxreg)
maxreg = reg;
struct register_info *info = &regs[reg];
-
- const char *pfx;
- int bits;
- int type;
- ssize_t n = ebl_register_info (ebl, reg, info->name, sizeof info->name,
- &pfx, &info->set, &bits, &type);
- if (n <= 0)
- error (EXIT_FAILURE, 0,
- gettext ("cannot register info: %s"), elf_errmsg (-1));
-
info->regloc = &reglocs[i];
- info->regno = reg;
- info->bits = bits;
- info->type = type;
+ info->set = register_info (ebl, reg, &reglocs[i],
+ info->name, &info->bits, &info->type);
}
qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);