gdb/
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index 0f58954d76992778780c213e30be03b39c353ea2..285081e472fd56b9b952042242239def23329694 100644 (file)
@@ -282,8 +282,8 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 {
   struct dwarf_expr_baton *debaton = ctx->baton;
 
-  return per_cu_dwarf_call (ctx, die_offset, debaton->per_cu,
-                           ctx->get_frame_pc, ctx->baton);
+  per_cu_dwarf_call (ctx, die_offset, debaton->per_cu,
+                    ctx->get_frame_pc, ctx->baton);
 }
 
 struct piece_closure
@@ -422,7 +422,7 @@ insert_bits (unsigned int datum,
 {
   unsigned int mask;
 
-  gdb_assert (dest_offset_bits >= 0 && dest_offset_bits + nbits <= 8);
+  gdb_assert (dest_offset_bits + nbits <= 8);
 
   mask = (1 << nbits) - 1;
   if (bits_big_endian)
@@ -591,8 +591,20 @@ read_pieced_value (struct value *v)
 
            if (gdb_regnum != -1)
              {
-               get_frame_register_bytes (frame, gdb_regnum, reg_offset, 
-                                         this_size, buffer);
+               int optim, unavail;
+
+               if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+                                              this_size, buffer,
+                                              &optim, &unavail))
+                 {
+                   /* Just so garbage doesn't ever shine through.  */
+                   memset (buffer, 0, this_size);
+
+                   if (optim)
+                     set_value_optimized_out (v, 1);
+                   if (unavail)
+                     mark_value_bytes_unavailable (v, offset, this_size);
+                 }
              }
            else
              {
@@ -776,8 +788,22 @@ write_pieced_value (struct value *to, struct value *from)
              {
                if (need_bitwise)
                  {
-                   get_frame_register_bytes (frame, gdb_regnum, reg_offset,
-                                             this_size, buffer);
+                   int optim, unavail;
+
+                   if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+                                                  this_size, buffer,
+                                                  &optim, &unavail))
+                     {
+                       if (optim)
+                         error (_("Can't do read-modify-write to "
+                                  "update bitfield; containing word has been "
+                                  "optimized out"));
+                       if (unavail)
+                         throw_error (NOT_AVAILABLE_ERROR,
+                                      _("Can't do read-modify-write to update "
+                                        "bitfield; containing word "
+                                        "is unavailable"));
+                     }
                    copy_bitwise (buffer, dest_offset_bits,
                                  contents, source_offset_bits,
                                  this_size_bits,
@@ -976,6 +1002,7 @@ indirect_pieced_value (struct value *value)
   frame = get_selected_frame (_("No frame selected."));
   byte_offset = value_as_address (value);
 
+  gdb_assert (piece);
   baton = dwarf2_fetch_die_location_block (piece->v.ptr.die, c->per_cu,
                                           get_frame_address_in_block_wrapper,
                                           frame);
@@ -1159,7 +1186,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
        case DWARF_VALUE_LITERAL:
          {
            bfd_byte *contents;
-           const bfd_byte *data;
+           const bfd_byte *ldata;
            size_t n = ctx->len;
 
            if (byte_offset + TYPE_LENGTH (type) > n)
@@ -1168,12 +1195,12 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
            retval = allocate_value (type);
            contents = value_contents_raw (retval);
 
-           data = ctx->data + byte_offset;
+           ldata = ctx->data + byte_offset;
            n -= byte_offset;
 
            if (n > TYPE_LENGTH (type))
              n = TYPE_LENGTH (type);
-           memcpy (contents, data, n);
+           memcpy (contents, ldata, n);
          }
          break;
 
@@ -1273,8 +1300,8 @@ needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
 {
   struct needs_frame_baton *nf_baton = ctx->baton;
 
-  return per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu,
-                           ctx->get_frame_pc, ctx->baton);
+  per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu,
+                    ctx->get_frame_pc, ctx->baton);
 }
 
 /* Return non-zero iff the location expression at DATA (length SIZE)
@@ -1334,8 +1361,15 @@ dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size,
 static void
 unimplemented (unsigned int op)
 {
-  error (_("DWARF operator %s cannot be translated to an agent expression"),
-        dwarf_stack_op_name (op, 1));
+  const char *name = dwarf_stack_op_name (op);
+
+  if (name)
+    error (_("DWARF operator %s cannot be translated to an agent expression"),
+          name);
+  else
+    error (_("Unknown DWARF operator 0x%02x cannot be translated "
+            "to an agent expression"),
+          op);
 }
 
 /* A helper function to convert a DWARF register to an arch register.
@@ -1419,11 +1453,11 @@ get_ax_pc (void *baton)
    example, if the expression cannot be compiled, or if the expression
    is invalid.  */
 
-static void
-compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
-                    struct gdbarch *arch, unsigned int addr_size,
-                    const gdb_byte *op_ptr, const gdb_byte *op_end,
-                    struct dwarf2_per_cu_data *per_cu)
+void
+dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
+                          struct gdbarch *arch, unsigned int addr_size,
+                          const gdb_byte *op_ptr, const gdb_byte *op_end,
+                          struct dwarf2_per_cu_data *per_cu)
 {
   struct cleanup *cleanups;
   int i, *offsets;
@@ -1710,8 +1744,8 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
                                     &datastart, &datalen);
 
            op_ptr = read_sleb128 (op_ptr, op_end, &offset);
-           compile_dwarf_to_ax (expr, loc, arch, addr_size, datastart,
-                                datastart + datalen, per_cu);
+           dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size, datastart,
+                                      datastart + datalen, per_cu);
 
            if (offset != 0)
              {
@@ -1733,7 +1767,7 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
 
        case DW_OP_pick:
          offset = *op_ptr++;
-         unimplemented (op);
+         ax_pick (expr, offset);
          break;
          
        case DW_OP_swap:
@@ -1741,31 +1775,11 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
          break;
 
        case DW_OP_over:
-         /* We can't directly support DW_OP_over, but GCC emits it as
-            part of a sequence to implement signed modulus.  As a
-            hack, we recognize this sequence.  Note that if GCC ever
-            generates a branch to the middle of this sequence, then
-            we will die somehow.  */
-         if (op_end - op_ptr >= 4
-             && op_ptr[0] == DW_OP_over
-             && op_ptr[1] == DW_OP_div
-             && op_ptr[2] == DW_OP_mul
-             && op_ptr[3] == DW_OP_minus)
-           {
-             /* Sign extend the operands.  */
-             ax_ext (expr, addr_size_bits);
-             ax_simple (expr, aop_swap);
-             ax_ext (expr, addr_size_bits);
-             ax_simple (expr, aop_swap);
-             ax_simple (expr, aop_rem_signed);
-             op_ptr += 4;
-           }
-         else
-           unimplemented (op);
+         ax_pick (expr, 1);
          break;
 
        case DW_OP_rot:
-         unimplemented (op);
+         ax_simple (expr, aop_rot);
          break;
 
        case DW_OP_deref:
@@ -1793,8 +1807,10 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
                ax_simple (expr, aop_ref64);
                break;
              default:
+               /* Note that dwarf_stack_op_name will never return
+                  NULL here.  */
                error (_("Unsupported size %d in %s"),
-                      size, dwarf_stack_op_name (op, 1));
+                      size, dwarf_stack_op_name (op));
              }
          }
          break;
@@ -1946,7 +1962,8 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
          break;
 
        case DW_OP_call_frame_cfa:
-         unimplemented (op);
+         dwarf2_compile_cfa_to_ax (expr, loc, arch, expr->scope, per_cu);
+         loc->kind = axs_lvalue_memory;
          break;
 
        case DW_OP_GNU_push_tls_address:
@@ -2060,9 +2077,9 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
            /* DW_OP_call_ref is currently not supported.  */
            gdb_assert (block.per_cu == per_cu);
 
-           compile_dwarf_to_ax (expr, loc, arch, addr_size,
-                                block.data, block.data + block.size,
-                                per_cu);
+           dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size,
+                                      block.data, block.data + block.size,
+                                      per_cu);
          }
          break;
 
@@ -2070,7 +2087,7 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
          unimplemented (op);
 
        default:
-         error (_("Unhandled dwarf expression opcode 0x%x"), op);
+         unimplemented (op);
        }
     }
 
@@ -2295,7 +2312,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
       LONGEST l;
       const char *name;
 
-      name = dwarf_stack_op_name (op, 0);
+      name = dwarf_stack_op_name (op);
 
       if (!name)
        error (_("Unrecognized DWARF opcode 0x%02x at %ld"),
@@ -2440,27 +2457,23 @@ disassemble_dwarf_expression (struct ui_file *stream,
        case DW_OP_breg29:
        case DW_OP_breg30:
        case DW_OP_breg31:
-         data = read_sleb128 (data, end, &ul);
-         fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
+         data = read_sleb128 (data, end, &l);
+         fprintf_filtered (stream, " %s [$%s]", plongest (l),
                            gdbarch_register_name (arch, op - DW_OP_breg0));
          break;
 
        case DW_OP_bregx:
-         {
-           ULONGEST offset;
-
-           data = read_uleb128 (data, end, &ul);
-           data = read_sleb128 (data, end, &offset);
-           fprintf_filtered (stream, " register %s [$%s] offset %s",
-                             pulongest (ul),
-                             gdbarch_register_name (arch, (int) ul),
-                             pulongest (offset));
-         }
+         data = read_uleb128 (data, end, &ul);
+         data = read_sleb128 (data, end, &l);
+         fprintf_filtered (stream, " register %s [$%s] offset %s",
+                           pulongest (ul),
+                           gdbarch_register_name (arch, (int) ul),
+                           plongest (l));
          break;
 
        case DW_OP_fbreg:
-         data = read_sleb128 (data, end, &ul);
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         data = read_sleb128 (data, end, &l);
+         fprintf_filtered (stream, " %s", plongest (l));
          break;
 
        case DW_OP_xderef_size:
@@ -2664,9 +2677,9 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
   if (dlbaton->data == NULL || dlbaton->size == 0)
     value->optimized_out = 1;
   else
-    compile_dwarf_to_ax (ax, value, gdbarch, addr_size,
-                        dlbaton->data, dlbaton->data + dlbaton->size,
-                        dlbaton->per_cu);
+    dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size,
+                              dlbaton->data, dlbaton->data + dlbaton->size,
+                              dlbaton->per_cu);
 }
 
 /* The set of location functions used with the DWARF-2 expression
@@ -2817,8 +2830,8 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
   if (data == NULL || size == 0)
     value->optimized_out = 1;
   else
-    compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size,
-                        dlbaton->per_cu);
+    dwarf2_compile_expr_to_ax (ax, value, gdbarch, addr_size, data, data + size,
+                              dlbaton->per_cu);
 }
 
 /* The set of location functions used with the DWARF-2 expression
This page took 0.0434 seconds and 4 git commands to generate.