Rename common to gdbsupport
[deliverable/binutils-gdb.git] / gdb / dwarf2expr.c
index a693856ef5aa15a1d2644ca565dc9fd3895fdcc3..6d919600e84b195889cfa98e15ebc1b70d9f811f 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 Expression Evaluator.
 
 /* DWARF 2 Expression Evaluator.
 
-   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   Copyright (C) 2001-2019 Free Software Foundation, Inc.
 
    Contributed by Daniel Berlin (dan@dberlin.org)
 
 
    Contributed by Daniel Berlin (dan@dberlin.org)
 
@@ -27,7 +27,7 @@
 #include "dwarf2.h"
 #include "dwarf2expr.h"
 #include "dwarf2loc.h"
 #include "dwarf2.h"
 #include "dwarf2expr.h"
 #include "dwarf2loc.h"
-#include "common/underlying.h"
+#include "gdbsupport/underlying.h"
 
 /* Cookie for gdbarch data.  */
 
 
 /* Cookie for gdbarch data.  */
 
@@ -88,10 +88,7 @@ dwarf_expr_context::address_type () const
 /* Create a new context for the expression evaluator.  */
 
 dwarf_expr_context::dwarf_expr_context ()
 /* Create a new context for the expression evaluator.  */
 
 dwarf_expr_context::dwarf_expr_context ()
-: stack (NULL),
-  stack_len (0),
-  stack_allocated (10),
-  gdbarch (NULL),
+: gdbarch (NULL),
   addr_size (0),
   ref_addr_size (0),
   offset (0),
   addr_size (0),
   ref_addr_size (0),
   offset (0),
@@ -100,53 +97,22 @@ dwarf_expr_context::dwarf_expr_context ()
   location (DWARF_VALUE_MEMORY),
   len (0),
   data (NULL),
   location (DWARF_VALUE_MEMORY),
   len (0),
   data (NULL),
-  initialized (0),
-  num_pieces (0),
-  pieces (NULL)
+  initialized (0)
 {
 {
-  this->stack = XNEWVEC (struct dwarf_stack_value, this->stack_allocated);
-}
-
-/* Clean up a dwarf_expr_context.  */
-
-dwarf_expr_context::~dwarf_expr_context ()
-{
-  xfree (this->stack);
-  xfree (this->pieces);
-}
-
-/* Expand the memory allocated stack to contain at least
-   NEED more elements than are currently used.  */
-
-void
-dwarf_expr_context::grow_stack (size_t need)
-{
-  if (this->stack_len + need > this->stack_allocated)
-    {
-      size_t newlen = this->stack_len + need + 10;
-
-      this->stack = XRESIZEVEC (struct dwarf_stack_value, this->stack, newlen);
-      this->stack_allocated = newlen;
-    }
 }
 
 /* Push VALUE onto the stack.  */
 
 void
 }
 
 /* Push VALUE onto the stack.  */
 
 void
-dwarf_expr_context::push (struct value *value, int in_stack_memory)
+dwarf_expr_context::push (struct value *value, bool in_stack_memory)
 {
 {
-  struct dwarf_stack_value *v;
-
-  grow_stack (1);
-  v = &this->stack[this->stack_len++];
-  v->value = value;
-  v->in_stack_memory = in_stack_memory;
+  stack.emplace_back (value, in_stack_memory);
 }
 
 /* Push VALUE onto the stack.  */
 
 void
 }
 
 /* Push VALUE onto the stack.  */
 
 void
-dwarf_expr_context::push_address (CORE_ADDR value, int in_stack_memory)
+dwarf_expr_context::push_address (CORE_ADDR value, bool in_stack_memory)
 {
   push (value_from_ulongest (address_type (), value), in_stack_memory);
 }
 {
   push (value_from_ulongest (address_type (), value), in_stack_memory);
 }
@@ -156,9 +122,10 @@ dwarf_expr_context::push_address (CORE_ADDR value, int in_stack_memory)
 void
 dwarf_expr_context::pop ()
 {
 void
 dwarf_expr_context::pop ()
 {
-  if (this->stack_len <= 0)
+  if (stack.empty ())
     error (_("dwarf expression stack underflow"));
     error (_("dwarf expression stack underflow"));
-  this->stack_len--;
+
+  stack.pop_back ();
 }
 
 /* Retrieve the N'th item on the stack.  */
 }
 
 /* Retrieve the N'th item on the stack.  */
@@ -166,11 +133,11 @@ dwarf_expr_context::pop ()
 struct value *
 dwarf_expr_context::fetch (int n)
 {
 struct value *
 dwarf_expr_context::fetch (int n)
 {
-  if (this->stack_len <= n)
+  if (stack.size () <= n)
      error (_("Asked for position %d of stack, "
      error (_("Asked for position %d of stack, "
-             "stack only has %d elements on it."),
-           n, this->stack_len);
-  return this->stack[this->stack_len - (1 + n)].value;
+             "stack only has %zu elements on it."),
+           n, stack.size ());
+  return stack[stack.size () - (1 + n)].value;
 }
 
 /* Require that TYPE be an integral type; throw an exception if not.  */
 }
 
 /* Require that TYPE be an integral type; throw an exception if not.  */
@@ -263,69 +230,64 @@ dwarf_expr_context::fetch_address (int n)
 
 /* Retrieve the in_stack_memory flag of the N'th item on the stack.  */
 
 
 /* Retrieve the in_stack_memory flag of the N'th item on the stack.  */
 
-int
+bool
 dwarf_expr_context::fetch_in_stack_memory (int n)
 {
 dwarf_expr_context::fetch_in_stack_memory (int n)
 {
-  if (this->stack_len <= n)
+  if (stack.size () <= n)
      error (_("Asked for position %d of stack, "
      error (_("Asked for position %d of stack, "
-             "stack only has %d elements on it."),
-           n, this->stack_len);
-  return this->stack[this->stack_len - (1 + n)].in_stack_memory;
+             "stack only has %zu elements on it."),
+           n, stack.size ());
+  return stack[stack.size () - (1 + n)].in_stack_memory;
 }
 
 /* Return true if the expression stack is empty.  */
 
 }
 
 /* Return true if the expression stack is empty.  */
 
-int
+bool
 dwarf_expr_context::stack_empty_p () const
 {
 dwarf_expr_context::stack_empty_p () const
 {
-  return this->stack_len == 0;
+  return stack.empty ();
 }
 
 /* Add a new piece to the dwarf_expr_context's piece list.  */
 void
 dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
 {
 }
 
 /* Add a new piece to the dwarf_expr_context's piece list.  */
 void
 dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
 {
-  struct dwarf_expr_piece *p;
+  this->pieces.emplace_back ();
+  dwarf_expr_piece &p = this->pieces.back ();
 
 
-  this->num_pieces++;
+  p.location = this->location;
+  p.size = size;
+  p.offset = offset;
 
 
-  this->pieces
-    = XRESIZEVEC (struct dwarf_expr_piece, this->pieces, this->num_pieces);
-
-  p = &this->pieces[this->num_pieces - 1];
-  p->location = this->location;
-  p->size = size;
-  p->offset = offset;
-
-  if (p->location == DWARF_VALUE_LITERAL)
+  if (p.location == DWARF_VALUE_LITERAL)
     {
     {
-      p->v.literal.data = this->data;
-      p->v.literal.length = this->len;
+      p.v.literal.data = this->data;
+      p.v.literal.length = this->len;
     }
   else if (stack_empty_p ())
     {
     }
   else if (stack_empty_p ())
     {
-      p->location = DWARF_VALUE_OPTIMIZED_OUT;
+      p.location = DWARF_VALUE_OPTIMIZED_OUT;
       /* Also reset the context's location, for our callers.  This is
         a somewhat strange approach, but this lets us avoid setting
         the location to DWARF_VALUE_MEMORY in all the individual
         cases in the evaluator.  */
       this->location = DWARF_VALUE_OPTIMIZED_OUT;
     }
       /* Also reset the context's location, for our callers.  This is
         a somewhat strange approach, but this lets us avoid setting
         the location to DWARF_VALUE_MEMORY in all the individual
         cases in the evaluator.  */
       this->location = DWARF_VALUE_OPTIMIZED_OUT;
     }
-  else if (p->location == DWARF_VALUE_MEMORY)
+  else if (p.location == DWARF_VALUE_MEMORY)
     {
     {
-      p->v.mem.addr = fetch_address (0);
-      p->v.mem.in_stack_memory = fetch_in_stack_memory (0);
+      p.v.mem.addr = fetch_address (0);
+      p.v.mem.in_stack_memory = fetch_in_stack_memory (0);
     }
     }
-  else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
+  else if (p.location == DWARF_VALUE_IMPLICIT_POINTER)
     {
     {
-      p->v.ptr.die_sect_off = (sect_offset) this->len;
-      p->v.ptr.offset = value_as_long (fetch (0));
+      p.v.ptr.die_sect_off = (sect_offset) this->len;
+      p.v.ptr.offset = value_as_long (fetch (0));
     }
     }
-  else if (p->location == DWARF_VALUE_REGISTER)
-    p->v.regno = value_as_long (fetch (0));
+  else if (p.location == DWARF_VALUE_REGISTER)
+    p.v.regno = value_as_long (fetch (0));
   else
     {
   else
     {
-      p->v.value = fetch (0);
+      p.v.value = fetch (0);
     }
 }
 
     }
 }
 
@@ -607,12 +569,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
       enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr++;
       ULONGEST result;
       /* Assume the value is not in stack memory.
       enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr++;
       ULONGEST result;
       /* Assume the value is not in stack memory.
-        Code that knows otherwise sets this to 1.
+        Code that knows otherwise sets this to true.
         Some arithmetic on stack addresses can probably be assumed to still
         be a stack address, but we skip this complication for now.
         This is just an optimization, so it's always ok to punt
         Some arithmetic on stack addresses can probably be assumed to still
         be a stack address, but we skip this complication for now.
         This is just an optimization, so it's always ok to punt
-        and leave this as 0.  */
-      int in_stack_memory = 0;
+        and leave this as false.  */
+      bool in_stack_memory = false;
       uint64_t uoffset, reg;
       int64_t offset;
       struct value *result_val = NULL;
       uint64_t uoffset, reg;
       int64_t offset;
       struct value *result_val = NULL;
@@ -672,6 +634,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
          result_val = value_from_ulongest (address_type, result);
          break;
 
          result_val = value_from_ulongest (address_type, result);
          break;
 
+       case DW_OP_addrx:
        case DW_OP_GNU_addr_index:
          op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
          result = this->get_addr_index (uoffset);
        case DW_OP_GNU_addr_index:
          op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
          result = this->get_addr_index (uoffset);
@@ -883,14 +846,16 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
          {
            const gdb_byte *datastart;
            size_t datalen;
          {
            const gdb_byte *datastart;
            size_t datalen;
-           unsigned int before_stack_len;
 
            op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
 
            op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
+
            /* Rather than create a whole new context, we simply
            /* Rather than create a whole new context, we simply
-              record the stack length before execution, then reset it
-              afterwards, effectively erasing whatever the recursive
-              call put there.  */
-           before_stack_len = this->stack_len;
+              backup the current stack locally and install a new empty stack,
+              then reset it afterwards, effectively erasing whatever the
+              recursive call put there.  */
+           std::vector<dwarf_stack_value> saved_stack = std::move (stack);
+           stack.clear ();
+
            /* FIXME: cagney/2003-03-26: This code should be using
                get_frame_base_address(), and then implement a dwarf2
                specific this_base method.  */
            /* FIXME: cagney/2003-03-26: This code should be using
                get_frame_base_address(), and then implement a dwarf2
                specific this_base method.  */
@@ -905,8 +870,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
                       "base using explicit value operator"));
            result = result + offset;
            result_val = value_from_ulongest (address_type, result);
                       "base using explicit value operator"));
            result = result + offset;
            result_val = value_from_ulongest (address_type, result);
-           in_stack_memory = 1;
-           this->stack_len = before_stack_len;
+           in_stack_memory = true;
+
+           /* Restore the content of the original stack.  */
+           stack = std::move (saved_stack);
+
            this->location = DWARF_VALUE_MEMORY;
          }
          break;
            this->location = DWARF_VALUE_MEMORY;
          }
          break;
@@ -928,16 +896,14 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
          
        case DW_OP_swap:
          {
          
        case DW_OP_swap:
          {
-           struct dwarf_stack_value t1, t2;
-
-           if (this->stack_len < 2)
+           if (stack.size () < 2)
               error (_("Not enough elements for "
               error (_("Not enough elements for "
-                       "DW_OP_swap.  Need 2, have %d."),
-                     this->stack_len);
-           t1 = this->stack[this->stack_len - 1];
-           t2 = this->stack[this->stack_len - 2];
-           this->stack[this->stack_len - 1] = t2;
-           this->stack[this->stack_len - 2] = t1;
+                       "DW_OP_swap.  Need 2, have %zu."),
+                     stack.size ());
+
+           dwarf_stack_value &t1 = stack[stack.size () - 1];
+           dwarf_stack_value &t2 = stack[stack.size () - 2];
+           std::swap (t1, t2);
            goto no_push;
          }
 
            goto no_push;
          }
 
@@ -948,18 +914,15 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 
        case DW_OP_rot:
          {
 
        case DW_OP_rot:
          {
-           struct dwarf_stack_value t1, t2, t3;
-
-           if (this->stack_len < 3)
+           if (stack.size () < 3)
               error (_("Not enough elements for "
               error (_("Not enough elements for "
-                       "DW_OP_rot.  Need 3, have %d."),
-                     this->stack_len);
-           t1 = this->stack[this->stack_len - 1];
-           t2 = this->stack[this->stack_len - 2];
-           t3 = this->stack[this->stack_len - 3];
-           this->stack[this->stack_len - 1] = t2;
-           this->stack[this->stack_len - 2] = t3;
-           this->stack[this->stack_len - 3] = t1;
+                       "DW_OP_rot.  Need 3, have %zu."),
+                     stack.size ());
+
+           dwarf_stack_value temp = stack[stack.size () - 1];
+           stack[stack.size () - 1] = stack[stack.size () - 2];
+           stack[stack.size () - 2] = stack[stack.size () - 3];
+           stack[stack.size () - 3] = temp;
            goto no_push;
          }
 
            goto no_push;
          }
 
@@ -990,12 +953,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
               from the type length, we need to zero-extend it.  */
            if (TYPE_LENGTH (type) != addr_size)
              {
               from the type length, we need to zero-extend it.  */
            if (TYPE_LENGTH (type) != addr_size)
              {
-               ULONGEST result =
+               ULONGEST datum =
                  extract_unsigned_integer (buf, addr_size, byte_order);
 
                buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
                store_unsigned_integer (buf, TYPE_LENGTH (type),
                  extract_unsigned_integer (buf, addr_size, byte_order);
 
                buf = (gdb_byte *) alloca (TYPE_LENGTH (type));
                store_unsigned_integer (buf, TYPE_LENGTH (type),
-                                       byte_order, result);
+                                       byte_order, datum);
              }
 
            result_val = value_from_contents_and_address (type, buf, addr);
              }
 
            result_val = value_from_contents_and_address (type, buf, addr);
@@ -1195,7 +1158,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
        case DW_OP_call_frame_cfa:
          result = this->get_frame_cfa ();
          result_val = value_from_ulongest (address_type, result);
        case DW_OP_call_frame_cfa:
          result = this->get_frame_cfa ();
          result_val = value_from_ulongest (address_type, result);
-         in_stack_memory = 1;
+         in_stack_memory = true;
          break;
 
        case DW_OP_GNU_push_tls_address:
          break;
 
        case DW_OP_GNU_push_tls_address:
@@ -1256,12 +1219,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 
        case DW_OP_bit_piece:
          {
 
        case DW_OP_bit_piece:
          {
-           uint64_t size, offset;
+           uint64_t size, uleb_offset;
 
             /* Record the piece.  */
            op_ptr = safe_read_uleb128 (op_ptr, op_end, &size);
 
             /* Record the piece.  */
            op_ptr = safe_read_uleb128 (op_ptr, op_end, &size);
-           op_ptr = safe_read_uleb128 (op_ptr, op_end, &offset);
-           add_piece (size, offset);
+           op_ptr = safe_read_uleb128 (op_ptr, op_end, &uleb_offset);
+           add_piece (size, uleb_offset);
 
             /* Pop off the address/regnum, and reset the location
               type.  */
 
             /* Pop off the address/regnum, and reset the location
               type.  */
@@ -1297,6 +1260,17 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
            this->dwarf_call (cu_off);
          }
          goto no_push;
            this->dwarf_call (cu_off);
          }
          goto no_push;
+
+       case DW_OP_GNU_variable_value:
+         {
+           sect_offset sect_off
+             = (sect_offset) extract_unsigned_integer (op_ptr,
+                                                       this->ref_addr_size,
+                                                       byte_order);
+           op_ptr += this->ref_addr_size;
+           result_val = this->dwarf_variable_value (sect_off);
+         }
+         break;
        
        case DW_OP_entry_value:
        case DW_OP_GNU_entry_value:
        
        case DW_OP_entry_value:
        case DW_OP_GNU_entry_value:
@@ -1440,14 +1414,10 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
   if (this->location == DWARF_VALUE_IMPLICIT_POINTER)
     add_piece (8 * this->addr_size, 0);
 
   if (this->location == DWARF_VALUE_IMPLICIT_POINTER)
     add_piece (8 * this->addr_size, 0);
 
-abort_expression:
   this->recursion_depth--;
   gdb_assert (this->recursion_depth >= 0);
 }
 
   this->recursion_depth--;
   gdb_assert (this->recursion_depth >= 0);
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_dwarf2expr;
-
 void
 _initialize_dwarf2expr (void)
 {
 void
 _initialize_dwarf2expr (void)
 {
This page took 0.030336 seconds and 4 git commands to generate.