]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
CFI interface fixes.
authorRoland McGrath <roland@redhat.com>
Mon, 20 Apr 2009 05:22:01 +0000 (22:22 -0700)
committerRoland McGrath <roland@redhat.com>
Mon, 20 Apr 2009 05:24:24 +0000 (22:24 -0700)
libdw/fde.c
libdwfl/dwfl_addrframe.c
libdwfl/libdwfl.h
tests/addrcfi.c

index df38a291190df40880540bfc5c2a7131cad4ec96..160238fb215d68ea9bd691d0e2c0214a7e448ece 100644 (file)
@@ -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;
 
index cd0a9a5b0f1bffdc79017a1c91cf348976e554a3..664a51d585acc2440f0339e4372c67eaa2148784 100644 (file)
@@ -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;
index 4af6a65de37733baba1e0076b9b6c089dfe50e71..999d14ee8cf6a06cda731e7b41c59eed13123bae 100644 (file)
@@ -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
index 101c5c0b014cc76aa9e58de258ac43c46127ed37..9b32c0a1279c3699bf3e7097323543338b03a058 100644 (file)
@@ -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