From 2e5fff4c6c28cba5107436c10810d98d902ccb88 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 19 Apr 2009 22:22:01 -0700 Subject: [PATCH] CFI interface fixes. --- libdw/fde.c | 2 +- libdwfl/dwfl_addrframe.c | 8 ++++---- libdwfl/libdwfl.h | 11 ++++++----- tests/addrcfi.c | 36 +++++++++++++++++++++++++----------- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/libdw/fde.c b/libdw/fde.c index df38a2911..160238fb2 100644 --- a/libdw/fde.c +++ b/libdw/fde.c @@ -203,7 +203,7 @@ binary_search_fde (Dwarf_CFI *cache, Dwarf_Addr address) Dwarf_Addr fde = read_encoded_value (&dummy_cfi, cache->search_table_encoding, &p); - if (address > start) + if (address >= start) { l = idx + 1; diff --git a/libdwfl/dwfl_addrframe.c b/libdwfl/dwfl_addrframe.c index cd0a9a5b0..664a51d58 100644 --- a/libdwfl/dwfl_addrframe.c +++ b/libdwfl/dwfl_addrframe.c @@ -72,21 +72,21 @@ try_cfi (Dwarf_CFI *cfi, Dwarf_Addr *bias, bool hard, } 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; diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 4af6a65de..999d14ee8 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -565,13 +565,14 @@ extern int dwfl_module_register_names (Dwfl_Module *mod, 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 diff --git a/tests/addrcfi.c b/tests/addrcfi.c index 101c5c0b0..9b32c0a12 100644 --- a/tests/addrcfi.c +++ b/tests/addrcfi.c @@ -38,7 +38,7 @@ 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)); @@ -52,7 +52,9 @@ print_detail (int result, const Dwarf_Op *ops, size_t nops) 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 @@ -63,6 +65,12 @@ print_detail (int result, const Dwarf_Op *ops, size_t nops) } } +struct stuff +{ + Dwarf_Frame *frame; + Dwarf_Addr bias; +}; + static int print_register (void *arg, int regno, @@ -72,15 +80,15 @@ print_register (void *arg, 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; } @@ -88,15 +96,21 @@ print_register (void *arg, 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); @@ -108,15 +122,15 @@ handle_address (GElf_Addr pc, Dwfl *dwfl) 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 -- 2.47.2