Implement '-target-detach pid'.
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index 5762c822547a2f17e8ec606a4014139a3a5c7dce..080cd06165a528b4632188b45adc79368942a302 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 location expression support for GDB.
 
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
 
    Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
 
@@ -8,18 +8,16 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or (at
-   your option) any later version.
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "ui-out.h"
 #include "dwarf2loc.h"
 
 #include "gdb_string.h"
-
-#ifndef DWARF2_REG_TO_REGNUM
-#define DWARF2_REG_TO_REGNUM(REG) (REG)
-#endif
+#include "gdb_assert.h"
 
 /* A helper function for dealing with location lists.  Given a
    symbol baton (BATON) and a pc value (PC), find the appropriate
@@ -59,11 +54,13 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
   CORE_ADDR low, high;
   gdb_byte *loc_ptr, *buf_end;
   int length;
-  unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
+  struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
-                                   SECT_OFF_TEXT (baton->objfile));
+  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
+                                   SECT_OFF_TEXT (objfile));
   CORE_ADDR base_address = baton->base_address + base_offset;
 
   loc_ptr = baton->data;
@@ -71,10 +68,10 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
 
   while (1)
     {
-      low = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
-      high = dwarf2_read_address (loc_ptr, buf_end, &length);
-      loc_ptr += length;
+      low = dwarf2_read_address (gdbarch, loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
+      high = dwarf2_read_address (gdbarch, loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
 
       /* An end-of-list entry.  */
       if (low == 0 && high == 0)
@@ -115,25 +112,18 @@ struct dwarf_expr_baton
 /* Helper functions for dwarf2_evaluate_loc_desc.  */
 
 /* Using the frame specified in BATON, return the value of register
-   REGNUM, treated as an unsigned integer.  */
+   REGNUM, treated as a pointer.  */
 static CORE_ADDR
 dwarf_expr_read_reg (void *baton, int dwarf_regnum)
 {
   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
-  CORE_ADDR result, save_addr;
-  enum lval_type lval_type;
-  gdb_byte *buf;
-  int optimized, regnum, realnum, regsize;
-
-  regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum);
-  regsize = register_size (current_gdbarch, regnum);
-  buf = alloca (regsize);
-
-  frame_unwind_register (debaton->frame, regnum, buf);
-  /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
-     address is always unsigned.  That may or may not be true.  */
-  result = extract_unsigned_integer (buf, regsize);
+  struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
+  CORE_ADDR result;
+  int regnum;
 
+  regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
+  result = address_from_register (builtin_type (gdbarch)->builtin_data_ptr,
+                                 regnum, debaton->frame);
   return result;
 }
 
@@ -159,6 +149,11 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
 
   framefunc = get_frame_function (debaton->frame);
 
+  /* If we found a frame-relative symbol then it was certainly within
+     some function associated with a frame. If we can't find the frame,
+     something has gone wrong.  */
+  gdb_assert (framefunc != NULL);
+
   if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs)
     {
       struct dwarf2_loclist_baton *symbaton;
@@ -172,8 +167,13 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
     {
       struct dwarf2_locexpr_baton *symbaton;
       symbaton = SYMBOL_LOCATION_BATON (framefunc);
-      *length = symbaton->size;
-      *start = symbaton->data;
+      if (symbaton != NULL)
+       {
+         *length = symbaton->size;
+         *start = symbaton->data;
+       }
+      else
+       *start = NULL;
     }
 
   if (*start == NULL)
@@ -197,7 +197,7 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
 static struct value *
 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
                          gdb_byte *data, unsigned short size,
-                         struct objfile *objfile)
+                         struct dwarf2_per_cu_data *per_cu)
 {
   struct gdbarch *arch = get_frame_arch (frame);
   struct value *retval;
@@ -209,12 +209,15 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
       retval = allocate_value (SYMBOL_TYPE (var));
       VALUE_LVAL (retval) = not_lval;
       set_value_optimized_out (retval, 1);
+      return retval;
     }
 
   baton.frame = frame;
-  baton.objfile = objfile;
+  baton.objfile = dwarf2_per_cu_objfile (per_cu);
 
   ctx = new_dwarf_expr_context ();
+  ctx->gdbarch = get_objfile_arch (baton.objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
   ctx->read_mem = dwarf_expr_read_mem;
@@ -236,7 +239,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
          if (p->in_reg)
            {
              bfd_byte regval[MAX_REGISTER_SIZE];
-             int gdb_regnum = DWARF2_REG_TO_REGNUM (p->value);
+             int gdb_regnum = gdbarch_dwarf2_reg_to_regnum
+                                (arch, p->value);
              get_frame_register (frame, gdb_regnum, regval);
              memcpy (contents + offset, regval, p->size);
            }
@@ -250,7 +254,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
   else if (ctx->in_reg)
     {
       CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
-      int gdb_regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum);
+      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum
+                        (arch, dwarf_regnum);
       retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
     }
   else
@@ -263,6 +268,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
       VALUE_ADDRESS (retval) = address;
     }
 
+  set_value_initialized (retval, ctx->initialized);
+
   free_dwarf_expr_context (ctx);
 
   return retval;
@@ -321,7 +328,8 @@ needs_frame_tls_address (void *baton, CORE_ADDR offset)
    requires a frame to evaluate.  */
 
 static int
-dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
+dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
+                            struct dwarf2_per_cu_data *per_cu)
 {
   struct needs_frame_baton baton;
   struct dwarf_expr_context *ctx;
@@ -330,6 +338,8 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
   baton.needs_frame = 0;
 
   ctx = new_dwarf_expr_context ();
+  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
+  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = needs_frame_read_reg;
   ctx->read_mem = needs_frame_read_mem;
@@ -392,7 +402,8 @@ dwarf2_tracepoint_var_ref (struct symbol *symbol, struct agent_expr *ax,
        error (_("Unexpected opcode after DW_OP_fbreg for symbol \"%s\"."),
               SYMBOL_PRINT_NAME (symbol));
 
-      TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
+      gdbarch_virtual_frame_pointer (current_gdbarch, 
+                                    ax->scope, &frame_reg, &frame_offset);
       ax_reg (ax, frame_reg);
       ax_const_l (ax, frame_offset);
       ax_simple (ax, aop_add);
@@ -431,7 +442,7 @@ locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
   struct value *val;
   val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
-                                 dlbaton->objfile);
+                                 dlbaton->per_cu);
 
   return val;
 }
@@ -441,7 +452,8 @@ static int
 locexpr_read_needs_frame (struct symbol *symbol)
 {
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
-  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
+  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
+                                     dlbaton->per_cu);
 }
 
 /* Print a natural-language description of SYMBOL to STREAM.  */
@@ -450,14 +462,19 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
 {
   /* FIXME: be more extensive.  */
   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+  int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
 
   if (dlbaton->size == 1
       && dlbaton->data[0] >= DW_OP_reg0
       && dlbaton->data[0] <= DW_OP_reg31)
     {
-      int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0);
+      struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      int regno = gdbarch_dwarf2_reg_to_regnum (gdbarch,
+                                               dlbaton->data[0] - DW_OP_reg0);
       fprintf_filtered (stream,
-                       "a variable in register %s", REGISTER_NAME (regno));
+                       "a variable in register %s",
+                       gdbarch_register_name (gdbarch, regno));
       return 1;
     }
 
@@ -477,14 +494,16 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
       && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
     if (dlbaton->data[0] == DW_OP_addr)
       {
-       int bytes_read;
-       CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
+       struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+       struct gdbarch *gdbarch = get_objfile_arch (objfile);
+       CORE_ADDR offset = dwarf2_read_address (gdbarch,
+                                               &dlbaton->data[1],
                                                &dlbaton->data[dlbaton->size - 1],
-                                               &bytes_read);
+                                               addr_size);
        fprintf_filtered (stream, 
                          "a thread-local variable at offset %s in the "
                          "thread-local storage for `%s'",
-                         paddr_nz (offset), dlbaton->objfile->name);
+                         paddr_nz (offset), objfile->name);
        return 1;
       }
   
@@ -546,7 +565,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
     }
   else
     val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
-                                   dlbaton->objfile);
+                                   dlbaton->per_cu);
 
   return val;
 }
This page took 0.034844 seconds and 4 git commands to generate.