* rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
index 81b2f8701abc90642b360f18f6094072843a27bd..f6ef04f71bc42e13b1ee60b1b2d62c45f612eb2c 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 location expression support for GDB.
 
-   Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
 
    Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
 
@@ -37,6 +37,7 @@
 #include "dwarf2loc.h"
 
 #include "gdb_string.h"
+#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
@@ -53,11 +54,12 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
   CORE_ADDR low, high;
   gdb_byte *loc_ptr, *buf_end;
   int length;
-  unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+  struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
+  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;
@@ -65,10 +67,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 (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
+      high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      loc_ptr += addr_size;
 
       /* An end-of-list entry.  */
       if (low == 0 && high == 0)
@@ -114,11 +116,12 @@ static CORE_ADDR
 dwarf_expr_read_reg (void *baton, int dwarf_regnum)
 {
   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+  struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
   CORE_ADDR result;
   int regnum;
 
-  regnum = gdbarch_dwarf2_reg_to_regnum (current_gdbarch, dwarf_regnum);
-  result = address_from_register (builtin_type_void_data_ptr,
+  regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
+  result = address_from_register (builtin_type (gdbarch)->builtin_data_ptr,
                                  regnum, debaton->frame);
   return result;
 }
@@ -145,6 +148,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;
@@ -158,8 +166,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)
@@ -183,7 +196,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;
@@ -199,9 +212,10 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
     }
 
   baton.frame = frame;
-  baton.objfile = objfile;
+  baton.objfile = dwarf2_per_cu_objfile (per_cu);
 
   ctx = new_dwarf_expr_context ();
+  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;
@@ -224,7 +238,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
            {
              bfd_byte regval[MAX_REGISTER_SIZE];
              int gdb_regnum = gdbarch_dwarf2_reg_to_regnum
-                                (current_gdbarch, p->value);
+                                (arch, p->value);
              get_frame_register (frame, gdb_regnum, regval);
              memcpy (contents + offset, regval, p->size);
            }
@@ -239,7 +253,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
     {
       CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
       int gdb_regnum = gdbarch_dwarf2_reg_to_regnum
-                        (current_gdbarch, dwarf_regnum);
+                        (arch, dwarf_regnum);
       retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
     }
   else
@@ -312,7 +326,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;
@@ -321,6 +336,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
   baton.needs_frame = 0;
 
   ctx = new_dwarf_expr_context ();
+  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;
@@ -423,7 +439,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;
 }
@@ -433,7 +449,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.  */
@@ -442,16 +459,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 = gdbarch_dwarf2_reg_to_regnum
-                   (current_gdbarch, 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",
-                       gdbarch_register_name (current_gdbarch, regno));
+                       gdbarch_register_name (gdbarch, regno));
       return 1;
     }
 
@@ -471,14 +491,14 @@ 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;
+       struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
        CORE_ADDR offset = dwarf2_read_address (&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;
       }
   
@@ -540,7 +560,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.026504 seconds and 4 git commands to generate.