* ppc-opc.c (insert_mbe, extract_mbe): Shift 1L instead of 1 up.
[deliverable/binutils-gdb.git] / gdb / dwarf2expr.c
index 02e246f6d58f7f1d0d21b4e7b36410ce3b5de194..3d1523b601009508f8b0d1a3e6d956b0eeb5b469 100644 (file)
@@ -35,12 +35,13 @@ static void execute_stack_op (struct dwarf_expr_context *,
 /* Create a new context for the expression evaluator.  */
 
 struct dwarf_expr_context *
-new_dwarf_expr_context ()
+new_dwarf_expr_context (void)
 {
   struct dwarf_expr_context *retval;
   retval = xcalloc (1, sizeof (struct dwarf_expr_context));
-  retval->stack_len = 10;
-  retval->stack = xmalloc (10 * sizeof (CORE_ADDR));
+  retval->stack_len = 0;
+  retval->stack_allocated = 10;
+  retval->stack = xmalloc (retval->stack_allocated * sizeof (CORE_ADDR));
   return retval;
 }
 
@@ -61,12 +62,10 @@ dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
 {
   if (ctx->stack_len + need > ctx->stack_allocated)
     {
-      size_t templen = ctx->stack_len * 2;
-      while (templen < (ctx->stack_len + need))
-          templen *= 2;
+      size_t newlen = ctx->stack_len + need + 10;
       ctx->stack = xrealloc (ctx->stack,
-                            templen * sizeof (CORE_ADDR));
-      ctx->stack_allocated = templen;
+                            newlen * sizeof (CORE_ADDR));
+      ctx->stack_allocated = newlen;
     }
 }
 
@@ -115,7 +114,7 @@ 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.  */
 
-static unsigned char *
+unsigned char *
 read_uleb128 (unsigned char *buf, unsigned char *buf_end, ULONGEST * r)
 {
   unsigned shift = 0;
@@ -141,7 +140,7 @@ 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.  */
 
-static unsigned char *
+unsigned char *
 read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r)
 {
   unsigned shift = 0;
@@ -170,16 +169,18 @@ read_sleb128 (unsigned char *buf, unsigned char *buf_end, LONGEST * r)
    BUF_END.  The address is returned, and *BYTES_READ is set to the
    number of bytes read from BUF.  */
 
-static CORE_ADDR
-read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
+CORE_ADDR
+dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
 {
   CORE_ADDR result;
 
   if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT)
-    error ("read_address: Corrupted DWARF expression.");
+    error ("dwarf2_read_address: Corrupted DWARF expression.");
 
   *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
-  result = extract_address (buf, 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);
   return result;
 }
 
@@ -228,16 +229,15 @@ static void
 execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
                  unsigned char *op_end)
 {
+  ctx->in_reg = 0;
+
   while (op_ptr < op_end)
     {
       enum dwarf_location_atom op = *op_ptr++;
-      CORE_ADDR result, memaddr;
+      CORE_ADDR result;
       ULONGEST uoffset, reg;
       LONGEST offset;
       int bytes_read;
-      enum lval_type expr_lval;
-
-      ctx->in_reg = 0;
 
       switch (op)
        {
@@ -277,7 +277,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
          break;
 
        case DW_OP_addr:
-         result = read_address (op_ptr, op_end, &bytes_read);
+         result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
          op_ptr += bytes_read;
          break;
 
@@ -356,43 +356,23 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
        case DW_OP_reg29:
        case DW_OP_reg30:
        case DW_OP_reg31:
-         /* NOTE: in the presence of DW_OP_piece this check is incorrect.  */
-         if (op_ptr != op_end)
+         if (op_ptr != op_end && *op_ptr != DW_OP_piece)
            error ("DWARF-2 expression error: DW_OP_reg operations must be "
-                  "used alone.");
+                  "used either alone or in conjuction with DW_OP_piece.");
 
-         /* FIXME drow/2003-02-21: This call to read_reg could be pushed
-            into the evaluator's caller by changing the semantics for in_reg.
-            Then we wouldn't need to return an lval_type and a memaddr.  */
-         result = (ctx->read_reg) (ctx->baton, op - DW_OP_reg0, &expr_lval,
-                                   &memaddr);
-
-         if (expr_lval == lval_register)
-           {
-             ctx->regnum = op - DW_OP_reg0;
-             ctx->in_reg = 1;
-           }
-         else
-           result = memaddr;
+         result = op - DW_OP_reg0;
+         ctx->in_reg = 1;
 
          break;
 
        case DW_OP_regx:
          op_ptr = read_uleb128 (op_ptr, op_end, &reg);
-         if (op_ptr != op_end)
+         if (op_ptr != op_end && *op_ptr != DW_OP_piece)
            error ("DWARF-2 expression error: DW_OP_reg operations must be "
-                  "used alone.");
-
-         result = (ctx->read_reg) (ctx->baton, reg, &expr_lval, &memaddr);
-
-         if (expr_lval == lval_register)
-           {
-             ctx->regnum = reg;
-             ctx->in_reg = 1;
-           }
-         else
-           result = memaddr;
+                  "used either alone or in conjuction with DW_OP_piece.");
 
+         result = reg;
+         ctx->in_reg = 1;
          break;
 
        case DW_OP_breg0:
@@ -429,8 +409,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
        case DW_OP_breg31:
          {
            op_ptr = read_sleb128 (op_ptr, op_end, &offset);
-           result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0,
-                                     &expr_lval, &memaddr);
+           result = (ctx->read_reg) (ctx->baton, op - DW_OP_breg0);
            result += offset;
          }
          break;
@@ -438,7 +417,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
          {
            op_ptr = read_uleb128 (op_ptr, op_end, &reg);
            op_ptr = read_sleb128 (op_ptr, op_end, &offset);
-           result = (ctx->read_reg) (ctx->baton, reg, &expr_lval, &memaddr);
+           result = (ctx->read_reg) (ctx->baton, reg);
            result += offset;
          }
          break;
@@ -454,19 +433,25 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
               afterwards, effectively erasing whatever the recursive
               call put there.  */
            before_stack_len = ctx->stack_len;
+           /* FIXME: cagney/2003-03-26: This code should be using
+               get_frame_base_address(), and then implement a dwarf2
+               specific this_base method.  */
            (ctx->get_frame_base) (ctx->baton, &datastart, &datalen);
            dwarf_expr_eval (ctx, datastart, datalen);
            result = dwarf_expr_fetch (ctx, 0);
-           if (! ctx->in_reg)
+           if (ctx->in_reg)
+             result = (ctx->read_reg) (ctx->baton, result);
+           else
              {
                char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
                int bytes_read;
 
                (ctx->read_mem) (ctx->baton, buf, result,
                                 TARGET_ADDR_BIT / TARGET_CHAR_BIT);
-               result = read_address (buf,
-                                      buf + TARGET_ADDR_BIT / TARGET_CHAR_BIT,
-                                      &bytes_read);
+               result = dwarf2_read_address (buf,
+                                             buf + (TARGET_ADDR_BIT
+                                                    / TARGET_CHAR_BIT),
+                                             &bytes_read);
              }
            result = result + offset;
            ctx->stack_len = before_stack_len;
@@ -525,9 +510,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
 
                (ctx->read_mem) (ctx->baton, buf, result,
                                 TARGET_ADDR_BIT / TARGET_CHAR_BIT);
-               result = read_address (buf,
-                                      buf + TARGET_ADDR_BIT / TARGET_CHAR_BIT,
-                                      &bytes_read);
+               result = dwarf2_read_address (buf,
+                                             buf + (TARGET_ADDR_BIT
+                                                    / TARGET_CHAR_BIT),
+                                             &bytes_read);
              }
              break;
 
@@ -537,9 +523,10 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
                int bytes_read;
 
                (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
-               result = read_address (buf,
-                                      buf + TARGET_ADDR_BIT / TARGET_CHAR_BIT,
-                                      &bytes_read);
+               result = dwarf2_read_address (buf,
+                                             buf + (TARGET_ADDR_BIT
+                                                    / TARGET_CHAR_BIT),
+                                             &bytes_read);
              }
              break;
 
@@ -654,6 +641,14 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
          break;
 
        case DW_OP_GNU_push_tls_address:
+         /* Variable is at a constant offset in the thread-local
+         storage block into the objfile for the current thread and
+         the dynamic linker module containing this expression. Here
+         we return returns the offset from that base.  The top of the
+         stack has the offset from the beginning of the thread
+         control block at which the variable is located.  Nothing
+         should follow this operator, so the top of stack would be
+         returned.  */
          result = dwarf_expr_fetch (ctx, 0);
          dwarf_expr_pop (ctx);
          result = (ctx->get_tls_address) (ctx->baton, result);
This page took 0.091239 seconds and 4 git commands to generate.