This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[WIP]: LOC_COMPUTED and LOC_COMPUTED_ARG


No tracepoint support, and the changelog is being worked on.
It also includes dwarf2 location expression support implemented using the 
location functions.
The evaluator in dwarf2read (which i'll get rid of before submitting it 
for real) is a slightly earlier version of the one I wrote that was 
included in dwarf2cfi.c.
--Dan
Index: buildsym.c
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.c,v
retrieving revision 1.14
diff -c -3 -p -w -B -b -r1.14 buildsym.c
*** buildsym.c	2002/01/20 19:42:04	1.14
--- buildsym.c	2002/03/26 15:39:48
*************** finish_block (struct symbol *symbol, str
*** 285,290 ****
--- 285,291 ----
  		case LOC_REGPARM_ADDR:
  		case LOC_BASEREG_ARG:
  		case LOC_LOCAL_ARG:
+ 		case LOC_COMPUTED_ARG:
  		  nparams++;
  		  break;
  		case LOC_UNDEF:
*************** finish_block (struct symbol *symbol, str
*** 300,305 ****
--- 301,307 ----
  		case LOC_BASEREG:
  		case LOC_UNRESOLVED:
  		case LOC_OPTIMIZED_OUT:
+ 		case LOC_COMPUTED:
  		default:
  		  break;
  		}
*************** finish_block (struct symbol *symbol, str
*** 321,326 ****
--- 323,329 ----
  		    case LOC_REGPARM_ADDR:
  		    case LOC_BASEREG_ARG:
  		    case LOC_LOCAL_ARG:
+ 		    case LOC_COMPUTED_ARG:
  		      TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
  		      TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
  		      iparams++;
*************** finish_block (struct symbol *symbol, str
*** 338,343 ****
--- 341,347 ----
  		    case LOC_BASEREG:
  		    case LOC_UNRESOLVED:
  		    case LOC_OPTIMIZED_OUT:
+ 		    case LOC_COMPUTED:
  		    default:
  		      break;
  		    }
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.51
diff -c -3 -p -w -B -b -r1.51 dwarf2read.c
*** dwarf2read.c	2002/03/21 00:53:44	1.51
--- dwarf2read.c	2002/03/26 15:39:50
***************
*** 44,50 ****
--- 44,55 ----
  #include <fcntl.h>
  #include "gdb_string.h"
  #include "gdb_assert.h"
+ #include "dwarf2cfi.h"
  #include <sys/types.h>
+ #include "ui-out.h"
+ #include "value.h"
+ #include "frame.h"
+ #include "gdbcore.h"
  
  #ifndef DWARF2_REG_TO_REGNUM
  #define DWARF2_REG_TO_REGNUM(REG) (REG)
*************** static struct abbrev_info *dwarf_alloc_a
*** 794,799 ****
--- 799,823 ----
  
  static struct die_info *dwarf_alloc_die (void);
  
+ static struct value * locexpr_read_variable (void *baton, struct frame_info *frame);
+ 
+ static int locexpr_read_needs_frame (void *baton);
+ 
+ static int locexpr_describe_location (void *baton, struct ui_file *stream);
+ 
+ static struct location_funcs locexpr_funcs = { 
+   locexpr_read_variable,
+   locexpr_read_needs_frame,
+   locexpr_describe_location,
+   NULL
+ };
+ 
+ struct locexpr_baton
+ {
+   struct symbol * sym;
+   struct dwarf_block locexpr;
+   struct objfile *obj;
+ };
  /* Try to locate the sections we need for DWARF 2 debugging
     information and return true if we have enough to do something.  */
  
*************** read_func_scope (struct die_info *die, s
*** 1663,1669 ****
    struct die_info *child_die;
    struct attribute *attr;
    char *name;
! 
    name = dwarf2_linkage_name (die);
  
    /* Ignore functions with missing or empty names and functions with
--- 1687,1693 ----
    struct die_info *child_die;
    struct attribute *attr;
    char *name;
!   struct locexpr_baton *baton;
    name = dwarf2_linkage_name (die);
  
    /* Ignore functions with missing or empty names and functions with
*************** read_func_scope (struct die_info *die, s
*** 1704,1709 ****
--- 1728,1742 ----
  
    new = push_context (0, lowpc);
    new->name = new_symbol (die, die->type, objfile, cu_header);
+   if (attr)
+     {
+       baton = obstack_alloc (&objfile->symbol_obstack, sizeof (struct locexpr_baton));
+       baton->sym = new->name;
+       baton->obj = objfile;
+       memcpy (&baton->locexpr, DW_BLOCK (attr), sizeof (struct dwarf_block));
+       SYMBOL_LOCATION_FUNCS (new->name) = &locexpr_funcs;
+       SYMBOL_LOCATION_BATON (new->name) = baton;
+     }
    list_in_scope = &local_symbols;
  
    if (die->has_children)
*************** new_symbol (struct die_info *die, struct
*** 4305,4312 ****
--- 4338,4357 ----
  	  attr = dwarf_attr (die, DW_AT_location);
  	  if (attr)
  	    {
+ 	      struct locexpr_baton *baton = obstack_alloc (&objfile->symbol_obstack, sizeof (struct locexpr_baton));
+ 	      baton->sym = sym;
+ 	      memcpy (&baton->locexpr, DW_BLOCK (attr), sizeof (struct dwarf_block));
+ 	      baton->obj = objfile;
+ 	      SYMBOL_CLASS (sym) = LOC_COMPUTED;
+ 	      SYMBOL_LOCATION_FUNCS (sym) = &locexpr_funcs;
+ 	      SYMBOL_LOCATION_BATON (sym) = baton;
  	      attr2 = dwarf_attr (die, DW_AT_external);
                if (attr2 && (DW_UNSND (attr2) != 0))
+ 		add_symbol_to_list (sym, &global_symbols);
+               else
+ 		add_symbol_to_list (sym, list_in_scope);
+ #if 0
+ 	      if (attr2 && (DW_UNSND (attr2) != 0))
  		{
  		  SYMBOL_VALUE_ADDRESS (sym) =
  		    decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
*************** new_symbol (struct die_info *die, struct
*** 4363,4368 ****
--- 4408,4414 ----
  		      SYMBOL_CLASS (sym) = LOC_STATIC;
  		    }
  		}
+ #endif
  	    }
  	  else
  	    {
*************** dwarf_alloc_die (void)
*** 6126,6129 ****
--- 6172,6689 ----
    die = (struct die_info *) xmalloc (sizeof (struct die_info));
    memset (die, 0, sizeof (struct die_info));
    return (die);
+ }
+ 
+ static struct value * evaluate_loc_desc (struct symbol *, struct frame_info *, struct dwarf_block *, struct type *);
+ static struct value *
+ locexpr_read_variable (void *baton, struct frame_info *frame)
+ {
+   struct locexpr_baton *dlbaton = (struct locexpr_baton *) baton;
+   struct value * val;
+   val = evaluate_loc_desc (dlbaton->sym, frame, &dlbaton->locexpr, SYMBOL_TYPE (dlbaton->sym));
+   return val;
+ }
+ static int 
+ locexpr_read_needs_frame (void *baton)
+ {
+   return 1;
+ }
+ static int 
+ locexpr_describe_location (void *baton, struct ui_file *stream)
+ {
+   fprintf_filtered (stream, "a DWARF2 location expression evaluated at runtime");
+   return 1;
+ }
+ /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
+    by R, and return the new value of BUF.  */
+ 
+ static unsigned char *
+ read_uleb128 (unsigned char *buf, ULONGEST *r)
+ {
+   unsigned shift = 0;
+   ULONGEST result = 0;
+   
+   while (1)
+     {
+       unsigned char byte = *buf++;
+       result |= (byte & 0x7f) << shift;
+       if ((byte & 0x80) == 0)
+ 	break;
+       shift += 7;
+     }
+   *r = result;
+   return buf;
+ }
+ 
+ /* Decode the signed LEB128 constant at BUF into the variable pointed to
+    by R, and return the new value of BUF.  */
+ 
+ static unsigned char *
+ read_sleb128 (unsigned char *buf, LONGEST *r)
+ {
+   unsigned shift = 0;
+   LONGEST result = 0;
+   unsigned char byte;
+   
+   while (1)
+     {
+       byte = *buf++;
+       result |= (byte & 0x7f) << shift;
+       shift += 7;
+       if ((byte & 0x80) == 0)
+ 	break;
+     }
+   if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
+     result |= - (1 << shift);
+   
+   *r = result;
+   return buf;
+ }
+ static CORE_ADDR
+ execute_stack_op (struct symbol *var,  unsigned char *op_ptr, unsigned char *op_end,
+ 		  struct frame_info *frame, CORE_ADDR initial, struct value * *currval)
+ {
+   CORE_ADDR stack[64];  /* ??? Assume this is enough. */
+   int stack_elt;
+   stack[0] = initial;
+   stack_elt = 1;
+   while (op_ptr < op_end)
+     {
+       enum dwarf_location_atom op = *op_ptr++;
+       ULONGEST result, reg;
+       LONGEST offset;
+       switch (op)
+ 	{
+ 	case DW_OP_lit0:
+ 	case DW_OP_lit1:
+ 	case DW_OP_lit2:
+ 	case DW_OP_lit3:
+ 	case DW_OP_lit4:
+ 	case DW_OP_lit5:
+ 	case DW_OP_lit6:
+ 	case DW_OP_lit7:
+ 	case DW_OP_lit8:
+ 	case DW_OP_lit9:
+ 	case DW_OP_lit10:
+ 	case DW_OP_lit11:
+ 	case DW_OP_lit12:
+ 	case DW_OP_lit13:
+ 	case DW_OP_lit14:
+ 	case DW_OP_lit15:
+ 	case DW_OP_lit16:
+ 	case DW_OP_lit17:
+ 	case DW_OP_lit18:
+ 	case DW_OP_lit19:
+ 	case DW_OP_lit20:
+ 	case DW_OP_lit21:
+ 	case DW_OP_lit22:
+ 	case DW_OP_lit23:
+ 	case DW_OP_lit24:
+ 	case DW_OP_lit25:
+ 	case DW_OP_lit26:
+ 	case DW_OP_lit27:
+ 	case DW_OP_lit28:
+ 	case DW_OP_lit29:
+ 	case DW_OP_lit30:
+ 	case DW_OP_lit31:
+ 	  result = op - DW_OP_lit0;
+ 	  break;
+           
+ 	case DW_OP_addr:
+ 	  result = (CORE_ADDR) extract_unsigned_integer (op_ptr, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ 	  op_ptr += TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ 	  break;
+           
+ 	case DW_OP_const1u:
+ 	  result = extract_unsigned_integer (op_ptr, 1);
+ 	  op_ptr += 1;
+ 	  break;
+ 	case DW_OP_const1s:
+ 	  result = extract_signed_integer (op_ptr, 1);
+ 	  op_ptr += 1;
+ 	  break;
+ 	case DW_OP_const2u:
+ 	  result = extract_unsigned_integer (op_ptr, 2);
+ 	  op_ptr += 2;
+ 	  break;
+ 	case DW_OP_const2s:
+ 	  result = extract_signed_integer (op_ptr, 2);
+ 	  op_ptr += 2;
+ 	  break;
+ 	case DW_OP_const4u:
+ 	  result = extract_unsigned_integer (op_ptr, 4);
+ 	  op_ptr += 4;
+ 	  break;
+ 	case DW_OP_const4s:
+ 	  result = extract_signed_integer (op_ptr, 4);
+ 	  op_ptr += 4;
+ 	  break;
+ 	case DW_OP_const8u:
+ 	  result = extract_unsigned_integer (op_ptr, 8);
+ 	  op_ptr += 8;
+ 	  break;
+ 	case DW_OP_const8s:
+ 	  result = extract_signed_integer (op_ptr, 8);
+ 	  op_ptr += 8;
+ 	  break;
+ 	case DW_OP_constu:
+ 	  op_ptr = read_uleb128 (op_ptr, &result);
+ 	  break;
+ 	case DW_OP_consts:
+ 	  op_ptr = read_sleb128 (op_ptr, &offset);
+ 	  result = offset;
+ 	  break;
+ 	  
+ 	case DW_OP_reg0:
+ 	case DW_OP_reg1:
+ 	case DW_OP_reg2:
+ 	case DW_OP_reg3:
+ 	case DW_OP_reg4:
+ 	case DW_OP_reg5:
+ 	case DW_OP_reg6:
+ 	case DW_OP_reg7:
+ 	case DW_OP_reg8:
+ 	case DW_OP_reg9:
+ 	case DW_OP_reg10:
+ 	case DW_OP_reg11:
+ 	case DW_OP_reg12:
+ 	case DW_OP_reg13:
+ 	case DW_OP_reg14:
+ 	case DW_OP_reg15:
+ 	case DW_OP_reg16:
+ 	case DW_OP_reg17:
+ 	case DW_OP_reg18:
+ 	case DW_OP_reg19:
+ 	case DW_OP_reg20:
+ 	case DW_OP_reg21:
+ 	case DW_OP_reg22:
+ 	case DW_OP_reg23:
+ 	case DW_OP_reg24:
+ 	case DW_OP_reg25:
+ 	case DW_OP_reg26:
+ 	case DW_OP_reg27:
+ 	case DW_OP_reg28:
+ 	case DW_OP_reg29:
+ 	case DW_OP_reg30:
+ 	case DW_OP_reg31:      
+ 	  {
+ 	    /* Allocate a buffer to store the register data */
+ 	    char *buf = (char*) alloca (MAX_REGISTER_RAW_SIZE);            
+ 	    
+ 	    get_saved_register (buf, NULL, NULL, frame, op - DW_OP_reg0, NULL);
+ 	    result = extract_address (buf, REGISTER_RAW_SIZE (op - DW_OP_reg0));
+ 	    if (currval != NULL)
+ 	      {
+ 		store_typed_address (VALUE_CONTENTS_RAW (*currval), SYMBOL_TYPE (var), result);
+ 		VALUE_LVAL (*currval) = not_lval;
+ 	      }
+ 	  }
+ 	  break;
+ 	case DW_OP_regx:  
+ 	  {
+ 	    char *buf = (char*) alloca (MAX_REGISTER_RAW_SIZE);   
+ 	    
+ 	    op_ptr = read_uleb128 (op_ptr, &reg);
+ 	    get_saved_register (buf, NULL, NULL, frame, reg, NULL);
+ 	    result = extract_address (buf, REGISTER_RAW_SIZE (reg));
+ 	  }
+ 	  break;
+ 	case DW_OP_breg0:
+ 	case DW_OP_breg1:
+ 	case DW_OP_breg2:
+ 	case DW_OP_breg3:
+ 	case DW_OP_breg4:
+ 	case DW_OP_breg5:
+ 	case DW_OP_breg6:
+ 	case DW_OP_breg7:
+ 	case DW_OP_breg8:
+ 	case DW_OP_breg9:
+ 	case DW_OP_breg10:
+ 	case DW_OP_breg11:
+ 	case DW_OP_breg12:
+ 	case DW_OP_breg13:
+ 	case DW_OP_breg14:
+ 	case DW_OP_breg15:
+ 	case DW_OP_breg16:
+ 	case DW_OP_breg17:
+ 	case DW_OP_breg18:
+ 	case DW_OP_breg19:
+ 	case DW_OP_breg20:
+ 	case DW_OP_breg21:
+ 	case DW_OP_breg22:
+ 	case DW_OP_breg23:
+ 	case DW_OP_breg24:
+ 	case DW_OP_breg25:
+ 	case DW_OP_breg26:
+ 	case DW_OP_breg27:
+ 	case DW_OP_breg28:
+ 	case DW_OP_breg29:
+ 	case DW_OP_breg30:
+ 	case DW_OP_breg31:
+ 	  {
+ 	    char *buf = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+             
+ 	    op_ptr = read_sleb128 (op_ptr, &offset);
+ 	    get_saved_register (buf, NULL, NULL, frame, op - DW_OP_breg0, NULL);
+ 	    result = extract_address (buf, REGISTER_RAW_SIZE (op - DW_OP_breg0));
+ 	    result += offset;
+ 	  }
+ 	  break;
+ 	case DW_OP_bregx:
+ 	  {
+ 	    char *buf = (char *) alloca (MAX_REGISTER_RAW_SIZE);
+ 	    
+ 	    op_ptr = read_uleb128 (op_ptr, &reg);
+ 	    op_ptr = read_sleb128 (op_ptr, &offset);
+ 	    get_saved_register (buf, NULL, NULL, frame, reg, NULL);
+ 	    result = extract_address (buf, REGISTER_RAW_SIZE (reg));
+ 	    result += offset;
+ 	  }
+ 	  break;
+ 	case DW_OP_fbreg:
+ 	  {
+ 	    struct symbol *framefunc;
+ 	    unsigned char *datastart;
+ 	    unsigned char *dataend;
+ 	    struct dwarf_block *theblock;
+ 	    struct locexpr_baton *baton;
+ 
+ 	    framefunc = get_frame_function (frame);
+ 	    op_ptr = read_sleb128 (op_ptr, &offset);
+ 	    baton = SYMBOL_LOCATION_BATON (framefunc);
+ 	    theblock = &baton->locexpr;
+ 	    datastart = theblock->data;
+ 	    dataend = theblock->data + theblock->size;
+ 	    result = execute_stack_op (var, datastart, dataend, frame, 0, NULL) + offset;
+ 	  }
+ 	  break;
+ 	case DW_OP_dup:
+ 	  if (stack_elt < 1)
+ 	    abort ();
+ 	  result = stack[stack_elt - 1];
+ 	  break;
+           
+ 	case DW_OP_drop:
+ 	  if (--stack_elt < 0)
+ 	    abort ();
+ 	  goto no_push;
+           
+ 	case DW_OP_pick:
+ 	  offset = *op_ptr++;
+ 	  if (offset >= stack_elt - 1)
+ 	    abort ();
+ 	  result = stack[stack_elt - 1 - offset];
+ 	  break;
+           
+ 	case DW_OP_over:
+ 	  if (stack_elt < 2)
+ 	    abort ();
+ 	  result = stack[stack_elt - 2];
+ 	  break;
+ 	  
+ 	case DW_OP_rot:
+ 	  {
+ 	    CORE_ADDR t1, t2, t3;
+             
+ 	    if (stack_elt < 3)
+ 	      abort ();
+ 	    t1 = stack[stack_elt - 1];
+ 	    t2 = stack[stack_elt - 2];
+ 	    t3 = stack[stack_elt - 3];
+ 	    stack[stack_elt - 1] = t2;
+ 	    stack[stack_elt - 2] = t3;
+ 	    stack[stack_elt - 3] = t1;
+ 	    goto no_push;
+ 	  }
+           
+ 	case DW_OP_deref:
+ 	case DW_OP_deref_size:
+ 	case DW_OP_abs:
+ 	case DW_OP_neg:
+ 	case DW_OP_not:
+ 	case DW_OP_plus_uconst:
+ 	  /* Unary operations.  */
+ 	  if (--stack_elt < 0)
+ 	    abort ();
+ 	  result = stack[stack_elt];
+           
+ 	  switch (op)
+ 	    {
+ 	    case DW_OP_deref:
+ 	      {
+ 		result = (CORE_ADDR) read_memory_unsigned_integer (result, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ 	      }
+ 	      break;
+               
+ 	    case DW_OP_deref_size:
+ 	      {
+ 		switch (*op_ptr++)
+ 		  {
+ 		  case 1:
+ 		    result = read_memory_unsigned_integer (result, 1);
+ 		    break;
+ 		  case 2:
+ 		    result = read_memory_unsigned_integer (result, 2);
+ 		    break;
+ 		  case 4:
+ 		    result = read_memory_unsigned_integer (result, 4);
+ 		    break;
+ 		  case 8:
+ 		    result = read_memory_unsigned_integer (result, 8);
+ 		    break;
+ 		  default:
+ 		    abort ();
+ 		  }
+ 	      }
+ 	      break;
+               
+ 	    case DW_OP_abs:
+ 	      if ((signed int) result < 0)
+ 		result = -result;
+ 	      break;
+ 	    case DW_OP_neg:
+ 	      result = -result;
+ 	      break;
+ 	    case DW_OP_not:
+ 	      result = ~result;
+ 	      break;
+ 	    case DW_OP_plus_uconst:
+ 	      op_ptr = read_uleb128 (op_ptr, &reg);
+ 	      result += reg;
+ 	      break;
+ 	    }
+ 	  break;
+           
+ 	case DW_OP_and:
+ 	case DW_OP_div:
+ 	case DW_OP_minus:
+ 	case DW_OP_mod:
+ 	case DW_OP_mul:
+ 	case DW_OP_or:
+ 	case DW_OP_plus:
+ 	case DW_OP_le:
+ 	case DW_OP_ge:
+ 	case DW_OP_eq:
+ 	case DW_OP_lt:
+ 	case DW_OP_gt:
+ 	case DW_OP_ne:
+ 	  {
+ 	    /* Binary operations.  */
+ 	    CORE_ADDR first, second;
+ 	    if ((stack_elt -= 2) < 0)
+ 	      abort ();
+ 	    second = stack[stack_elt];
+ 	    first = stack[stack_elt + 1];
+             
+ 	    switch (op)
+ 	      {
+ 	      case DW_OP_and:
+ 		result = second & first;
+ 		break;
+ 	      case DW_OP_div:
+ 		result = (LONGEST)second / (LONGEST)first;
+ 		break;
+ 	      case DW_OP_minus:
+ 		result = second - first;
+ 		break;
+ 	      case DW_OP_mod:
+ 		result = (LONGEST)second % (LONGEST)first;
+ 		break;
+ 	      case DW_OP_mul:
+ 		result = second * first;
+ 		break;
+ 	      case DW_OP_or:
+ 		result = second | first;
+ 		break;
+ 	      case DW_OP_plus:
+ 		result = second + first;
+ 		break;
+ 	      case DW_OP_shl:
+ 		result = second << first;
+ 		break;
+ 	      case DW_OP_shr:
+ 		result = second >> first;
+ 		break;
+ 	      case DW_OP_shra:
+ 		result = (LONGEST)second >> first;
+ 		break;
+ 	      case DW_OP_xor:
+ 		result = second ^ first;
+ 		break;
+ 	      case DW_OP_le:
+ 		result = (LONGEST)first <= (LONGEST)second;
+ 		break;
+ 	      case DW_OP_ge:
+ 		result = (LONGEST)first >= (LONGEST)second;
+ 		break;
+ 	      case DW_OP_eq:
+ 		result = (LONGEST)first == (LONGEST)second;
+ 		break;
+ 	      case DW_OP_lt:
+ 		result = (LONGEST)first < (LONGEST)second;
+ 		break;
+ 	      case DW_OP_gt:
+ 		result = (LONGEST)first > (LONGEST)second;
+ 		break;
+ 	      case DW_OP_ne:
+ 		result = (LONGEST)first != (LONGEST)second;
+ 		break;
+ 	      }
+ 	  }
+ 	  break;
+           
+ 	case DW_OP_skip:
+ 	  offset = extract_signed_integer (op_ptr, 2);
+ 	  op_ptr += 2;
+ 	  op_ptr += offset;
+ 	  goto no_push;
+           
+ 	case DW_OP_bra:
+ 	  if (--stack_elt < 0)
+ 	    abort ();
+ 	  offset = extract_signed_integer (op_ptr, 2);
+ 	  op_ptr += 2;
+ 	  if (stack[stack_elt] != 0)
+ 	    op_ptr += offset;
+ 	  goto no_push;
+           
+ 	case DW_OP_nop:
+ 	  goto no_push;
+           
+ 	default:
+ 	  abort ();
+          }
+       
+       /* Most things push a result value.  */
+       if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
+ 	abort ();
+       stack[++stack_elt] = result;
+     no_push:;
+     }
+   
+   /* We were executing this program to get a value.  It should be
+      at top of stack.  */
+   if (stack_elt-1 < 0)
+     abort ();
+   return stack[stack_elt];
+ }
+ 
+ /* Evaluate a location description, given in THEBLOCK, in the
+    context of frame FRAME. */
+ static struct value *
+ evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
+ 		   struct dwarf_block *theblock, struct type *type)
+ {
+   CORE_ADDR result;
+   struct value * retval;
+   retval = allocate_value(type);
+   VALUE_LVAL (retval) = lval_memory;
+   VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var);
+   result = execute_stack_op (var, theblock->data, theblock->data+theblock->size, frame, 0, &retval);
+   if (VALUE_LVAL (retval) == lval_memory)
+     {
+       VALUE_LAZY (retval) = 1;
+       VALUE_ADDRESS (retval) = result;
+     }
+   return retval;
  }
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.29
diff -c -3 -p -w -B -b -r1.29 findvar.c
*** findvar.c	2002/03/16 02:57:42	1.29
--- findvar.c	2002/03/26 15:39:50
*************** symbol_read_needs_frame (struct symbol *
*** 369,374 ****
--- 369,378 ----
      {
        /* All cases listed explicitly so that gcc -Wall will detect it if
           we failed to consider one.  */
+     case LOC_COMPUTED:
+     case LOC_COMPUTED_ARG:
+       return (SYMBOL_LOCATION_FUNCS(sym)->read_needs_frame) (SYMBOL_LOCATION_BATON(sym));
+ 
      case LOC_REGISTER:
      case LOC_ARG:
      case LOC_REF_ARG:
*************** addresses have not been bound by the dyn
*** 575,581 ****
--- 579,596 ----
  	  }
        }
        break;
+     case LOC_COMPUTED:
+     case LOC_COMPUTED_ARG:
+       {
+ 	struct location_funcs *funcs = SYMBOL_LOCATION_FUNCS (var);
+ 	void *baton = SYMBOL_LOCATION_BATON (var);
+ 	
+ 	if (frame == 0 && (funcs->read_needs_frame)(baton))
+ 	  return 0;
+ 	return (funcs->read_variable) (baton, frame);
  	
+       }
+       break;
      case LOC_UNRESOLVED:
        {
  	struct minimal_symbol *msym;
Index: printcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/printcmd.c,v
retrieving revision 1.37
diff -c -3 -p -w -B -b -r1.37 printcmd.c
*** printcmd.c	2002/03/06 06:28:33	1.37
--- printcmd.c	2002/03/26 15:39:50
*************** address_info (char *exp, int from_tty)
*** 1181,1186 ****
--- 1181,1190 ----
  	}
        break;
  
+     case LOC_COMPUTED:
+     case LOC_COMPUTED_ARG:
+       (SYMBOL_LOCATION_FUNCS (sym)->describe_location)(SYMBOL_LOCATION_BATON (sym), gdb_stdout);
+       break;
      case LOC_REGISTER:
        printf_filtered ("a variable in register %s", REGISTER_NAME (val));
        break;
Index: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.30
diff -c -3 -p -w -B -b -r1.30 stack.c
*** stack.c	2002/03/23 17:38:13	1.30
--- stack.c	2002/03/26 15:39:51
*************** print_block_frame_locals (struct block *
*** 1173,1178 ****
--- 1173,1179 ----
  	case LOC_REGISTER:
  	case LOC_STATIC:
  	case LOC_BASEREG:
+         case LOC_COMPUTED:
  	  values_printed = 1;
  	  for (j = 0; j < num_tabs; j++)
  	    fputs_filtered ("\t", stream);
Index: symmisc.c
===================================================================
RCS file: /cvs/src/src/gdb/symmisc.c,v
retrieving revision 1.8
diff -c -3 -p -w -B -b -r1.8 symmisc.c
*** symmisc.c	2002/03/22 18:57:08	1.8
--- symmisc.c	2002/03/26 15:39:51
*************** print_partial_symbols (struct partial_sy
*** 860,865 ****
--- 860,869 ----
  	case LOC_OPTIMIZED_OUT:
  	  fputs_filtered ("optimized out", outfile);
  	  break;
+ 	case LOC_COMPUTED:
+ 	case LOC_COMPUTED_ARG:
+ 	  fputs_filtered ("computed at runtime", outfile);
+ 	  break;
  	default:
  	  fputs_filtered ("<invalid location>", outfile);
  	  break;
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.28
diff -c -3 -p -w -B -b -r1.28 symtab.h
*** symtab.h	2002/03/22 18:57:08	1.28
--- symtab.h	2002/03/26 15:39:52
***************
*** 29,35 ****
  #define obstack_chunk_alloc xmalloc
  #define obstack_chunk_free xfree
  #include "bcache.h"
! 
  /* Don't do this; it means that if some .o's are compiled with GNU C
     and some are not (easy to do accidentally the way we configure
     things; also it is a pain to have to "make clean" every time you
--- 29,36 ----
  #define obstack_chunk_alloc xmalloc
  #define obstack_chunk_free xfree
  #include "bcache.h"
! struct axs_value;
! struct agent_expr;
  /* Don't do this; it means that if some .o's are compiled with GNU C
     and some are not (easy to do accidentally the way we configure
     things; also it is a pain to have to "make clean" every time you
*************** enum address_class
*** 661,668 ****
       * than the one where the global was allocated are done
       * with a level of indirection.
       */
  
!     LOC_INDIRECT
  
    };
  
--- 662,719 ----
       * than the one where the global was allocated are done
       * with a level of indirection.
       */
+ 
+     LOC_INDIRECT,
+     
+     /* The variable address is computed by a set of location
+        functions.  */
+     LOC_COMPUTED,
+     
+     /* The variable is an argument, and it's address is computed by a
+        set of location functions.  */
+     LOC_COMPUTED_ARG
+ 
+   };
+ 
+ /* A structure of function pointers describing the location of a
+    variable, structure member, or structure base class.
     
!    These functions' BATON arguments are generic data pointers, holding
!    whatever data the functions need --- the code which provides this
!    structure also provides the actual contents of the baton, and
!    decides its form.  However, there may be other rules about where
!    the baton data must be allocated; whoever is pointing to this
!    `struct location_funcs' object will know the rules.  For example,
!    when a symbol S's location is LOC_COMPUTED, then
!    SYMBOL_LOCATION_FUNCS(S) is pointing to a location_funcs structure,
!    and SYMBOL_LOCATION_BATON(S) is the baton, which must be allocated
!    on the same obstack as the symbol itself.  */
! 
! struct location_funcs {
!   
!   /* Return the value of the variable described by BATON, relative to
!      the stack frame FRAME.  If the variable has been optimized
!      out, return zero.
! 
!      If `read_needs_frame (BATON)' is zero, then FRAME may be
!      zero.  */
!   struct value *(*read_variable) (void *baton, struct frame_info *frame);
!   
!   /* Return true if we need a frame to find the value of the object
!      described by BATON.  */
!   int (*read_needs_frame) (void *baton);
!   
!   /* Write to STREAM a natural-language description of the location of
!      the object described by BATON.  */
!   int (*describe_location) (void *baton, struct ui_file *stream);
!   
!   /* Tracepoint support.  Append bytecodes to the tracepoint agent
!      expression AX that push the address of the object described by
!      BATON.  Set VALUE appropriately.  Note --- for objects in
!      registers, this needn't emit any code; as long as it sets VALUE
!      properly, then the caller will generate the right code in the
!      process of treating this as an lvalue or rvalue.  */ void
!    (*tracepoint_var_ref) (void *baton, struct agent_expr *ax, struct axs_value *value);
  
  };
  
*************** struct symbol
*** 719,724 ****
--- 770,777 ----
        {
  	/* Used by LOC_BASEREG and LOC_BASEREG_ARG.  */
  	short basereg;
+ 	/* Location baton to pass to location functions.  */
+ 	void *locbaton;
        }
      aux_value;
  
*************** struct symbol
*** 730,735 ****
--- 783,792 ----
      /* List of ranges where this symbol is active.  This is only
         used by alias symbols at the current time.  */
      struct range_list *ranges;
+     
+     /* Location functions for LOC_COMPUTED and LOC_COMPUTED_ARGS.  */
+     struct location_funcs *locfuncs;
+     
    };
  
  
*************** struct symbol
*** 740,745 ****
--- 797,804 ----
  #define SYMBOL_BASEREG(symbol)		(symbol)->aux_value.basereg
  #define SYMBOL_ALIASES(symbol)		(symbol)->aliases
  #define SYMBOL_RANGES(symbol)		(symbol)->ranges
+ #define SYMBOL_LOCATION_BATON(symbol)   (symbol)->aux_value.locbaton
+ #define SYMBOL_LOCATION_FUNCS(symbol)   (symbol)->locfuncs
  
  /* A partial_symbol records the name, namespace, and address class of
     symbols whose types we have not parsed yet.  For functions, it also


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]