Translate DW_CFA_expression/DW_CFA_val_expression properly to imply pushing CFA befor...
authorRoland McGrath <roland@redhat.com>
Mon, 26 Apr 2010 18:50:27 +0000 (11:50 -0700)
committerRoland McGrath <roland@redhat.com>
Mon, 26 Apr 2010 18:50:27 +0000 (11:50 -0700)
libdw/ChangeLog
libdw/dwarf_frame_cfa.c
libdw/dwarf_frame_register.c
libdw/dwarf_getlocation.c
libdw/libdwP.h

index 5fa7515..f927032 100644 (file)
@@ -1,3 +1,12 @@
+2010-04-26  Roland McGrath  <roland@redhat.com>
+
+       * dwarf_getlocation.c (__libdw_intern_expression): Take new arg CFAP.
+       Prepend DW_OP_call_frame_cfa if true.
+       (getlocation): Update caller.
+       * dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise.
+       * dwarf_frame_register.c (dwarf_frame_register): Likewise.
+       * libdwP.h: Update decl.
+
 2010-04-22  Roland McGrath  <roland@redhat.com>
 
        * cfi.c (execute_cfi): Track last-set CFA regno and offset even
index d1c5710..03c5fbd 100644 (file)
@@ -84,7 +84,7 @@ dwarf_frame_cfa (fs, ops, nops)
       result = __libdw_intern_expression
        (NULL, fs->cache->other_byte_order,
         fs->cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8,
-        &fs->cache->expr_tree, &fs->cfa_data.expr, false,
+        &fs->cache->expr_tree, &fs->cfa_data.expr, false, false,
         ops, nops, IDX_debug_frame);
       break;
 
index 3d232e9..e42b76b 100644 (file)
@@ -1,5 +1,5 @@
 /* Get register location expression for frame.
-   Copyright (C) 2009 Red Hat, Inc.
+   Copyright (C) 2009-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -131,7 +131,7 @@ dwarf_frame_register (fs, regno, ops_mem, ops, nops)
                                       fs->cache->other_byte_order,
                                       address_size,
                                       &fs->cache->expr_tree, &block,
-                                      reg->rule == reg_val_expression,
+                                      true, reg->rule == reg_val_expression,
                                       ops, nops, IDX_debug_frame) < 0)
          return -1;
        break;
index 720b20f..f362fe2 100644 (file)
@@ -1,5 +1,5 @@
 /* Return location expression list.
-   Copyright (C) 2000-2009 Red Hat, Inc.
+   Copyright (C) 2000-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -221,7 +221,8 @@ int
 internal_function
 __libdw_intern_expression (Dwarf *dbg,
                           bool other_byte_order, unsigned int address_size,
-                          void **cache, const Dwarf_Block *block, bool valuep,
+                          void **cache, const Dwarf_Block *block,
+                          bool cfap, bool valuep,
                           Dwarf_Op **llbuf, size_t *listlen, int sec_index)
 {
   /* Check whether we already looked at this list.  */
@@ -444,6 +445,9 @@ __libdw_intern_expression (Dwarf *dbg,
       ++n;
     }
 
+  if (cfap)
+    ++n;
+
   /* Allocate the array.  */
   Dwarf_Op *result;
   if (dbg != NULL)
@@ -463,6 +467,16 @@ __libdw_intern_expression (Dwarf *dbg,
   *llbuf = result;
   *listlen = n;
 
+  if (cfap)
+    {
+      /* Synthesize the operation to push the CFA before the expression.  */
+      --n;
+      result[0].atom = DW_OP_call_frame_cfa;
+      result[0].number = 0;
+      result[0].number2 = 0;
+      result[0].offset = -1;
+    }
+
   do
     {
       /* We populate the array from the back since the list is backwards.  */
@@ -507,7 +521,8 @@ getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
             Dwarf_Op **llbuf, size_t *listlen, int sec_index)
 {
   return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
-                                   cu->address_size, &cu->locs, block, false,
+                                   cu->address_size, &cu->locs, block,
+                                   false, false,
                                    llbuf, listlen, sec_index);
 }
 
index 248a58d..44beac6 100644 (file)
@@ -433,10 +433,10 @@ extern int __libdw_intern_expression (Dwarf *dbg,
                                      bool other_byte_order,
                                      unsigned int address_size,
                                      void **cache, const Dwarf_Block *block,
-                                     bool valuep,
+                                     bool cfap, bool valuep,
                                      Dwarf_Op **llbuf, size_t *listlen,
                                      int sec_index)
-  __nonnull_attribute__ (4, 5, 7, 8) internal_function;
+  __nonnull_attribute__ (4, 5, 8, 9) internal_function;
 
 
 /* Return error code of last failing function call.  This value is kept