}
int
-dwfl_addrframe (dwfl, address, frame)
+dwfl_addrframe (dwfl, address, frame, bias)
Dwfl *dwfl;
Dwarf_Addr address;
Dwarf_Frame **frame;
+ Dwarf_Addr *bias;
{
Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (dwfl, address);
if (mod == NULL)
return -1;
/* Try to get a .debug_frame match first, then a .eh_frame match. */
- Dwarf_Addr bias;
- int result = try_cfi (INTUSE(dwfl_module_dwarf_cfi) (mod, &bias), &bias,
+ int result = try_cfi (INTUSE(dwfl_module_dwarf_cfi) (mod, bias), bias,
false, address, frame);
if (result > 0)
- result = try_cfi (INTUSE(dwfl_module_eh_cfi) (mod, &bias), &bias,
+ result = try_cfi (INTUSE(dwfl_module_eh_cfi) (mod, bias), bias,
true, address, frame);
return result;
extern Dwarf_CFI *dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
extern Dwarf_CFI *dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
-// XXX needs module bias? for DW_OP_addr in exprs?
/* Compute what's known about a call frame when the PC is at ADDRESS.
This integrates both DWARF proper and EH information as available.
- Returns 0 for success or -1 for errors.
- On success, *FRAME is a malloc'd pointer. */
-extern int dwfl_addrframe (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Frame **frame)
- __nonnull_attribute__ (3);
+ Returns 0 for success or -1 for errors. On success, *FRAME is a
+ malloc'd pointer and *BIAS is the address bias for uses of
+ DW_OP_addr and the like in expressions extracted from *FRAME. */
+extern int dwfl_addrframe (Dwfl *dwfl, Dwarf_Addr address,
+ Dwarf_Frame **frame, Dwarf_Addr *bias)
+ __nonnull_attribute__ (3, 4);
#ifdef __cplusplus
static void
-print_detail (int result, const Dwarf_Op *ops, size_t nops)
+print_detail (int result, const Dwarf_Op *ops, size_t nops, Dwarf_Addr bias)
{
if (result < 0)
printf ("indeterminate (%s)\n", dwarf_errmsg (-1));
printf (" %#x", ops[i].atom);
if (ops[i].number2 == 0)
{
- if (ops[i].number != 0)
+ if (ops[i].atom == DW_OP_addr)
+ printf ("(%#" PRIx64 ")", ops[i].number + bias);
+ else if (ops[i].number != 0)
printf ("(%" PRId64 ")", ops[i].number);
}
else
}
}
+struct stuff
+{
+ Dwarf_Frame *frame;
+ Dwarf_Addr bias;
+};
+
static int
print_register (void *arg,
int regno,
int bits __attribute__ ((unused)),
int type __attribute__ ((unused)))
{
- Dwarf_Frame *frame = arg;
+ struct stuff *stuff = arg;
printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname);
Dwarf_Op ops_mem[2];
Dwarf_Op *ops;
size_t nops;
- int result = dwarf_frame_register (frame, regno, ops_mem, &ops, &nops);
- print_detail (result, ops, nops);
+ int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops);
+ print_detail (result, ops, nops, stuff->bias);
return DWARF_CB_OK;
}
static void
handle_address (GElf_Addr pc, Dwfl *dwfl)
{
- Dwarf_Frame *frame;
- int result = dwfl_addrframe (dwfl, pc, &frame);
+ struct stuff stuff;
+
+ int result = dwfl_addrframe (dwfl, pc, &stuff.frame, &stuff.bias);
if (result != 0)
error (EXIT_FAILURE, 0, "dwfl_addrframe: %s", dwfl_errmsg (-1));
Dwarf_Addr start = pc;
Dwarf_Addr end = pc;
bool signalp;
- int ra_regno = dwarf_frame_info (frame, &start, &end, &signalp);
+ int ra_regno = dwarf_frame_info (stuff.frame, &start, &end, &signalp);
+ if (ra_regno >= 0)
+ {
+ start += stuff.bias;
+ end += stuff.bias;
+ }
printf ("%#" PRIx64 " => [%#" PRIx64 ", %#" PRIx64 "):\n", pc, start, end);
ra_regno, signalp ? " (signal frame)" : "");
Dwarf_Op *cfa_ops;
- int cfa_nops = dwarf_frame_cfa (frame, &cfa_ops);
+ int cfa_nops = dwarf_frame_cfa (stuff.frame, &cfa_ops);
if (cfa_nops < 0)
error (EXIT_FAILURE, 0, "dwarf_frame_cfa: %s", dwarf_errmsg (-1));
printf ("\tCFA ");
- print_detail (1, cfa_ops, cfa_nops);
+ print_detail (1, cfa_ops, cfa_nops, stuff.bias);
(void) dwfl_module_register_names (dwfl_addrmodule (dwfl, pc),
- &print_register, frame);
+ &print_register, &stuff);
}
int