* gas/mips/mips.exp (run_dump_test_arch): Check for the presence
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index 196502279c8875d3279ca93baef6cf1f4646abd5..b2aecf253396caee15184bc0d3509230dc5b1d35 100644 (file)
@@ -70,8 +70,7 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
-                                   SECT_OFF_TEXT (objfile));
+  CORE_ADDR base_offset = dwarf2_per_cu_text_offset (baton->per_cu);
   CORE_ADDR base_address = baton->base_address + base_offset;
 
   loc_ptr = baton->data;
@@ -882,7 +881,7 @@ static struct lval_funcs pieced_value_funcs = {
    SIZE, to find the current location of variable of TYPE in the context
    of FRAME.  */
 
-static struct value *
+struct value *
 dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
                          const gdb_byte *data, unsigned short size,
                          struct dwarf2_per_cu_data *per_cu)
@@ -891,6 +890,7 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   struct dwarf_expr_baton baton;
   struct dwarf_expr_context *ctx;
   struct cleanup *old_chain;
+  struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
 
   if (size == 0)
     {
@@ -906,8 +906,9 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
 
-  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
+  ctx->gdbarch = get_objfile_arch (objfile);
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
+  ctx->offset = dwarf2_per_cu_text_offset (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
   ctx->read_mem = dwarf_expr_read_mem;
@@ -1083,6 +1084,7 @@ dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size,
   struct dwarf_expr_context *ctx;
   int in_reg;
   struct cleanup *old_chain;
+  struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
 
   baton.needs_frame = 0;
   baton.per_cu = per_cu;
@@ -1090,8 +1092,9 @@ dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size,
   ctx = new_dwarf_expr_context ();
   old_chain = make_cleanup_free_dwarf_expr_context (ctx);
 
-  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
+  ctx->gdbarch = get_objfile_arch (objfile);
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
+  ctx->offset = dwarf2_per_cu_text_offset (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = needs_frame_read_reg;
   ctx->read_mem = needs_frame_read_mem;
@@ -1293,9 +1296,15 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
          break;
 
        case DW_OP_addr:
-         ax_const_l (expr, extract_unsigned_integer (op_ptr,
-                                                     addr_size, byte_order));
+         uoffset = extract_unsigned_integer (op_ptr, addr_size, byte_order);
          op_ptr += addr_size;
+         /* Some versions of GCC emit DW_OP_addr before
+            DW_OP_GNU_push_tls_address.  In this case the value is an
+            index, not an address.  We don't support things like
+            branching between the address and the TLS op.  */
+         if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
+           uoffset += dwarf2_per_cu_text_offset (per_cu);
+         ax_const_l (expr, uoffset);
          break;
 
        case DW_OP_const1u:
@@ -1931,7 +1940,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       struct symbol *framefunc;
       int frame_reg = 0;
       LONGEST frame_offset;
-      const gdb_byte *base_data, *new_data;
+      const gdb_byte *base_data, *new_data, *save_data = data;
       size_t base_size;
       LONGEST base_offset = 0;
 
@@ -1975,10 +1984,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
        {
          /* We don't know what to do with the frame base expression,
             so we can't trace this variable; give up.  */
-         error (_("Cannot describe location of symbol \"%s\"; "
-                  "DWARF 2 encoding not handled, "
-                  "first opcode in base data is 0x%x."),
-                SYMBOL_PRINT_NAME (symbol), base_data[0]);
+         return save_data;
        }
 
       regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, frame_reg);
@@ -2007,15 +2013,19 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
 
      DW_AT_location    : 10 byte block: 3 4 0 0 0 0 0 0 0 e0
                         (DW_OP_addr: 4; DW_OP_GNU_push_tls_address)
-     
+
      0x3 is the encoding for DW_OP_addr, which has an operand as long
      as the size of an address on the target machine (here is 8
-     bytes).  0xe0 is the encoding for DW_OP_GNU_push_tls_address.
-     The operand represents the offset at which the variable is within
-     the thread local storage.  */
+     bytes).  Note that more recent version of GCC emit DW_OP_const4u
+     or DW_OP_const8u, depending on address size, rather than
+     DW_OP_addr.  0xe0 is the encoding for
+     DW_OP_GNU_push_tls_address. The operand represents the offset at
+     which the variable is within the thread local storage.  */
 
   else if (data + 1 + addr_size < end
-          && data[0] == DW_OP_addr
+          && (data[0] == DW_OP_addr
+              || (addr_size == 4 && data[0] == DW_OP_const4u)
+              || (addr_size == 8 && data[0] == DW_OP_const8u))
           && data[1 + addr_size] == DW_OP_GNU_push_tls_address
           && piece_end_p (data + 2 + addr_size, end))
     {
@@ -2416,9 +2426,12 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
   unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
 
-  compile_dwarf_to_ax (ax, value, gdbarch, addr_size,
-                      dlbaton->data, dlbaton->data + dlbaton->size,
-                      dlbaton->per_cu);
+  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);
 }
 
 /* The set of location functions used with the DWARF-2 expression
@@ -2493,8 +2506,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
-                                   SECT_OFF_TEXT (objfile));
+  CORE_ADDR base_offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
   CORE_ADDR base_address = dlbaton->base_address + base_offset;
 
   loc_ptr = dlbaton->data;
@@ -2568,9 +2580,11 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
   unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
 
   data = find_location_expression (dlbaton, &size, ax->scope);
-
-  compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size,
-                      dlbaton->per_cu);
+  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);
 }
 
 /* The set of location functions used with the DWARF-2 expression
This page took 0.025577 seconds and 4 git commands to generate.