* inferior.h (read_sp): Remove prototype.
[deliverable/binutils-gdb.git] / gdb / dwarf2expr.c
index 7b9374a7feb93d2542873b6705f255838ea0cef7..ad259f4a40d836887c277751105c5bf121913d97 100644 (file)
@@ -1,5 +1,7 @@
-/* Dwarf2 Expression Evaluator
-   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+/* DWARF 2 Expression Evaluator.
+
+   Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+
    Contributed by Daniel Berlin (dan@dberlin.org)
 
    This file is part of GDB.
@@ -16,8 +18,8 @@
 
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -30,7 +32,8 @@
 /* Local prototypes.  */
 
 static void execute_stack_op (struct dwarf_expr_context *,
-                             unsigned char *, unsigned char *);
+                             gdb_byte *, gdb_byte *);
+static struct type *unsigned_address_type (void);
 
 /* Create a new context for the expression evaluator.  */
 
@@ -96,7 +99,7 @@ dwarf_expr_pop (struct dwarf_expr_context *ctx)
 CORE_ADDR
 dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
 {
-  if (ctx->stack_len < n)
+  if (ctx->stack_len <= n)
      error (_("Asked for position %d of stack, stack only has %d elements on it."),
            n, ctx->stack_len);
   return ctx->stack[ctx->stack_len - (1 + n)];
@@ -130,8 +133,7 @@ add_piece (struct dwarf_expr_context *ctx,
    CTX.  */
 
 void
-dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr,
-                size_t len)
+dwarf_expr_eval (struct dwarf_expr_context *ctx, gdb_byte *addr, size_t len)
 {
   execute_stack_op (ctx, addr, addr + len);
 }
@@ -140,12 +142,12 @@ dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr,
    by R, and return the new value of BUF.  Verify that it doesn't extend
    past BUF_END.  */
 
-unsigned char *
-read_uleb128 (unsigned char *buf, unsigned char *buf_end, ULONGEST * r)
+gdb_byte *
+read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r)
 {
   unsigned shift = 0;
   ULONGEST result = 0;
-  unsigned char byte;
+  gdb_byte byte;
 
   while (1)
     {
@@ -166,12 +168,12 @@ read_uleb128 (unsigned char *buf, unsigned char *buf_end, ULONGEST * r)
    by R, and return the new value of BUF.  Verify that it doesn't extend
    past BUF_END.  */
 
-unsigned char *
-read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r)
+gdb_byte *
+read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r)
 {
   unsigned shift = 0;
   LONGEST result = 0;
-  unsigned char byte;
+  gdb_byte byte;
 
   while (1)
     {
@@ -196,7 +198,7 @@ read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r)
    number of bytes read from BUF.  */
 
 CORE_ADDR
-dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
+dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
 {
   CORE_ADDR result;
 
@@ -204,9 +206,35 @@ dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read
     error (_("dwarf2_read_address: Corrupted DWARF expression."));
 
   *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
-  /* 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, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+
+  /* For most architectures, calling extract_unsigned_integer() alone
+     is sufficient for extracting an address.  However, some
+     architectures (e.g. MIPS) use signed addresses and using
+     extract_unsigned_integer() will not produce a correct
+     result.  Turning the unsigned integer into a value and then
+     decomposing that value as an address will cause
+     gdbarch_integer_to_address() to be invoked for those
+     architectures which require it.  Thus, using value_as_address()
+     will produce the correct result for both types of architectures.
+
+     One concern regarding the use of values for this purpose is
+     efficiency.  Obviously, these extra calls will take more time to
+     execute and creating a value takes more space, space which will
+     have to be garbage collected at a later time.  If constructing
+     and then decomposing a value for this purpose proves to be too
+     inefficient, then gdbarch_integer_to_address() can be called
+     directly.
+
+     The use of `unsigned_address_type' in the code below refers to
+     the type of buf and has no bearing on the signedness of the
+     address being returned.  */
+
+  result = value_as_address (value_from_longest 
+                             (unsigned_address_type (),
+                              extract_unsigned_integer 
+                                (buf,
+                                 TARGET_ADDR_BIT / TARGET_CHAR_BIT)));
+
   return result;
 }
 
@@ -225,7 +253,7 @@ unsigned_address_type (void)
       return builtin_type_uint64;
     default:
       internal_error (__FILE__, __LINE__,
-                     "Unsupported address size.\n");
+                     _("Unsupported address size.\n"));
     }
 }
 
@@ -244,7 +272,7 @@ signed_address_type (void)
       return builtin_type_int64;
     default:
       internal_error (__FILE__, __LINE__,
-                     "Unsupported address size.\n");
+                     _("Unsupported address size.\n"));
     }
 }
 \f
@@ -252,8 +280,8 @@ signed_address_type (void)
    evaluate the expression between OP_PTR and OP_END.  */
 
 static void
-execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
-                 unsigned char *op_end)
+execute_stack_op (struct dwarf_expr_context *ctx,
+                 gdb_byte *op_ptr, gdb_byte *op_end)
 {
   ctx->in_reg = 0;
 
@@ -449,7 +477,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
          break;
        case DW_OP_fbreg:
          {
-           unsigned char *datastart;
+           gdb_byte *datastart;
            size_t datalen;
            unsigned int before_stack_len;
 
@@ -519,7 +547,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
            {
            case DW_OP_deref:
              {
-               char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+               gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
                int bytes_read;
 
                (ctx->read_mem) (ctx->baton, buf, result,
@@ -533,7 +561,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
 
            case DW_OP_deref_size:
              {
-               char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+               gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
                int bytes_read;
 
                (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
@@ -650,7 +678,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
                break;
              default:
                internal_error (__FILE__, __LINE__,
-                               "Can't be reached.");
+                               _("Can't be reached."));
              }
            result = value_as_long (value_binop (val1, val2, binop));
          }
This page took 0.027803 seconds and 4 git commands to generate.