2009-10-22 Paul Pluzhnikov <ppluzhnikov@google.com>
[binutils-gdb.git] / gdb / dwarf2-frame.c
index f9ca067dfe163e5acaf9c52437a48b6902fd230c..5e9be2ccb2cc7ae896725ade66755e5c79672362 100644 (file)
@@ -357,7 +357,8 @@ register %s (#%d) at %s"),
 
 static CORE_ADDR
 execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
-                 struct frame_info *this_frame, CORE_ADDR initial)
+                 struct frame_info *this_frame, CORE_ADDR initial,
+                 int initial_in_stack_memory)
 {
   struct dwarf_expr_context *ctx;
   CORE_ADDR result;
@@ -375,12 +376,19 @@ execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
   ctx->get_frame_cfa = no_get_frame_cfa;
   ctx->get_tls_address = no_get_tls_address;
 
-  dwarf_expr_push (ctx, initial);
+  dwarf_expr_push (ctx, initial, initial_in_stack_memory);
   dwarf_expr_eval (ctx, exp, len);
   result = dwarf_expr_fetch (ctx, 0);
 
-  if (ctx->in_reg)
+  if (ctx->location == DWARF_VALUE_REGISTER)
     result = read_reg (this_frame, result);
+  else if (ctx->location != DWARF_VALUE_MEMORY)
+    {
+      /* This is actually invalid DWARF, but if we ever do run across
+        it somehow, we might as well support it.  So, instead, report
+        it as unimplemented.  */
+      error (_("Not implemented: computing unwound register using explicit value operator"));
+    }
 
   do_cleanups (old_chain);
 
@@ -968,7 +976,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
     case CFA_EXP:
       cache->cfa =
        execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len,
-                         cache->addr_size, this_frame, 0);
+                         cache->addr_size, this_frame, 0, 0);
       break;
 
     default:
@@ -1124,7 +1132,7 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     case DWARF2_FRAME_REG_SAVED_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp,
                               cache->reg[regnum].exp_len,
-                              cache->addr_size, this_frame, cache->cfa);
+                              cache->addr_size, this_frame, cache->cfa, 1);
       return frame_unwind_got_memory (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_SAVED_VAL_OFFSET:
@@ -1134,7 +1142,7 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
     case DWARF2_FRAME_REG_SAVED_VAL_EXP:
       addr = execute_stack_op (cache->reg[regnum].loc.exp,
                               cache->reg[regnum].exp_len,
-                              cache->addr_size, this_frame, cache->cfa);
+                              cache->addr_size, this_frame, cache->cfa, 1);
       return frame_unwind_got_constant (this_frame, regnum, addr);
 
     case DWARF2_FRAME_REG_UNSPECIFIED:
@@ -1517,6 +1525,14 @@ find_cie (struct dwarf2_cie_table *cie_table, ULONGEST cie_pointer)
 {
   struct dwarf2_cie **p_cie;
 
+  /* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to
+     bsearch be non-NULL.  */
+  if (cie_table->entries == NULL)
+    {
+      gdb_assert (cie_table->num_entries == 0);
+      return NULL;
+    }
+
   p_cie = bsearch (&cie_pointer, cie_table->entries, cie_table->num_entries,
                    sizeof (cie_table->entries[0]), bsearch_cie_cmp);
   if (p_cie != NULL)
@@ -2104,8 +2120,8 @@ dwarf2_build_frame_info (struct objfile *objfile)
           obstack_grow (&objfile->objfile_obstack, &fde_table.entries[j],
                         sizeof (fde_table.entries[0]));
           while (++j < fde_table.num_entries
-                 && (fde_table.entries[k]->initial_location ==
-                     fde_table.entries[j]->initial_location))
+                 && (fde_table.entries[k]->initial_location
+                     == fde_table.entries[j]->initial_location))
             /* Skip.  */;
         }
       fde_table2->entries = obstack_finish (&objfile->objfile_obstack);