This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA]: Symbol evaluation code
- To: gdb-patches at sources dot redhat dot com
- Subject: [RFA]: Symbol evaluation code
- From: Daniel Berlin <dan at cgsoftware dot com>
- Date: 29 May 2001 13:38:26 -0400
I'd like approval for this code.
I plan on making the push_opcode non-varargs before making anything
use it, but i really want to get this stuff out of my tree and into
sourceware, before I start having fun with cvs conflicts. Also, one
of my HD's is starting to go, and I didn't want to lose it.
I've deliberately not included the Makefile.in portion of the patch,
so that it is not compiled in yet. I will submit that along with the
non-vararging patch, in a few days.
2001-05-29 Daniel Berlin <dan@cgsoftware.com>
* symtab.h: Add LOC_LOC_EXPR and LOC_LOC_LIST to the location types.
Add dynamic_location and loc/frameloc to the symbol structure.
(SYMBOL_LOC_EXPR): New macro.
(SYMBOL_FRAME_LOC_EXPR): Ditto.
Add forward declaration of locexpr struct.
* symeval.c: New file.
* symeval.def: New file.
* symeval.h: New file.
Index: symeval.c
===================================================================
RCS file: symeval.c
diff -N symeval.c
*** /dev/null Tue May 5 13:32:27 1998
--- symeval.c Tue May 29 10:34:00 2001
***************
*** 0 ****
--- 1,595 ----
+ /* Location expression evaluation for the GNU debugger, GDB.
+ Copyright 2001
+ Free Software Foundation, Inc.
+
+ Contributed by Daniel Berlin <dan@cgsoftware.com>
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ 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. */
+ #include "defs.h"
+ #include "symtab.h"
+ #include "frame.h"
+ #include "value.h"
+ #include "gdbcore.h"
+ #include "symeval.h"
+ #include "gdb_assert.h"
+
+ #define MORE_BYTES 0x80
+ #define DATA_MASK 0x7f
+ #define DIGIT_WIDTH 7
+ #define SIGN_BIT 0x40
+
+ /* 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 & DATA_MASK) << shift;
+ if ((byte & MORE_BYTES) == 0)
+ break;
+ shift += DIGIT_WIDTH;
+ }
+ *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 & DATA_MASK) << shift;
+ shift += DIGIT_WIDTH;
+ if ((byte & MORE_BYTES) == 0)
+ break;
+ }
+ if (shift < (sizeof (*r) * 8) && (byte & SIGN_BIT) != 0)
+ result |= - (1 << shift);
+
+ *r = result;
+ return buf;
+ }
+
+ struct locexpr
+ {
+ unsigned int size;
+ unsigned char *data;
+ };
+
+ struct locexpr_cookie
+ {
+ struct locexpr *expr;
+ unsigned int position;
+ enum locexpr_opcode lastopcode;
+ unsigned char operands_left;
+ };
+ static int
+ sizeof_uleb128 (ULONGEST value)
+ {
+ int size =0, byte;
+ do
+ {
+ byte = value & DATA_MASK;
+ value >>= DIGIT_WIDTH;
+ size++;
+ } while (value != 0);
+ return size;
+ }
+
+ static int
+ sizeof_sleb128 (LONGEST value)
+ {
+ int size =0, byte;
+ do
+ {
+ byte = value & DATA_MASK;
+ value >>= DIGIT_WIDTH;
+ size++;
+ } while (!(( value == 0 && (byte & SIGN_BIT) == 0) || (value == -1 && (byte & SIGN_BIT) != 0)));
+ return size;
+ }
+
+
+ /* Encode the value into ULEB128 into the expr->data */
+
+ static void
+ encode_uleb128 (struct locexpr *expr, ULONGEST value)
+ {
+ char *place;
+ int size = sizeof_uleb128(value);
+ expr->data = xrealloc (expr->data, expr->size + size);
+ place = expr->data + expr->size;
+ expr->size += size;
+ do
+ {
+ unsigned char uc;
+ uc = value & DATA_MASK;
+ value >>= DIGIT_WIDTH;
+ if (value != 0)
+ uc |= MORE_BYTES;
+ *place = uc;
+ place++;
+ } while (value);
+
+ }
+ /* Encode the value into SLEB128 into the expr->data */
+
+ static void
+ encode_sleb128 (struct locexpr *expr, LONGEST value)
+ {
+ char *place;
+ int size = sizeof_sleb128(value);
+ int sign = - (value < 0);
+ int more = 1;
+ expr->data = xrealloc (expr->data, expr->size + size);
+ place = expr->data + expr->size;
+ expr->size += size;
+ do
+ {
+ unsigned char uc = value & DATA_MASK;
+ value >>= DIGIT_WIDTH;
+ if (value == sign && ((uc & SIGN_BIT) == (sign & SIGN_BIT)))
+ more = 0;
+ else
+ uc |= MORE_BYTES;
+ *place = uc;
+ place++;
+ } while (more);
+ }
+
+ static void
+ encode_uchar (struct locexpr *expr, unsigned char value)
+ {
+ expr->data = xrealloc (expr->data, expr->size+1);
+ *(expr->data + expr->size) = value;
+ expr->size++;
+ }
+
+ void
+ init_locexpr(struct locexpr **expr)
+ {
+ *expr = xmalloc(sizeof (struct locexpr));
+ }
+ void
+ destroy_locexpr (struct locexpr **expr)
+ {
+ xfree ((*expr)->data);
+ xfree (*expr);
+
+ }
+ #define DEFINE_LOCEXPR_OPCODE(opcode, desc, numargs, argtypes) numargs,
+ static const int locexpr_opcount[] = {
+ #include "symeval.def"
+ };
+ #undef DEFINE_LOCEXPR_OPCODE
+ #define DEFINE_LOCEXPR_OPCODE(opcode, desc, numargs, argtypes) argtypes,
+ static const char *locexpr_opfmt[] = {
+ #include "symeval.def"
+ };
+ #undef DEFINE_LOCEXPR_OPCODE
+ #define DEFINE_LOCEXPR_OPCODE(opcode, desc, numargs, argtypes) #opcode,
+ static const char *locexpr_opstring[] = {
+ #include "symeval.def"
+ }
+ ;
+ #undef DEFINE_LOCEXPR_OPCODE
+ void
+ locexpr_push_op (struct locexpr *expr, enum locexpr_opcode operation, const char *fmt, ...)
+ {
+ va_list ap;
+ LONGEST sval;
+ ULONGEST uval;
+ unsigned char ucval;
+ expr->data = xrealloc (expr->data, expr->size + 1);
+ expr->data[expr->size] = operation;
+ expr->size++;
+ if (strcmp (fmt, locexpr_opfmt[operation]))
+ {
+ internal_error (__FILE__, __LINE__,
+ "You passed a format string of %s for opcode %s, and its format string is %s\n",
+ fmt, locexpr_opstring[operation], locexpr_opfmt[operation]);
+ }
+ va_start (ap, fmt);
+ while (*fmt)
+ {
+ switch (*fmt++)
+ {
+ case 'u':
+ uval = (ULONGEST) va_arg (ap, unsigned long);
+ encode_uleb128 (expr, uval);
+ break;
+ case 's':
+ sval = (LONGEST) va_arg (ap, signed long);
+ encode_sleb128 (expr, sval);
+ break;
+ case 'c':
+ ucval = (unsigned char) va_arg (ap, unsigned int);
+ encode_uchar (expr, ucval);
+ break;
+ }
+ }
+ va_end (ap);
+ }
+
+ void
+ locexpr_get_op (struct locexpr *expr, struct locexpr_cookie *cookie, enum locexpr_opcode *op)
+ {
+ struct locexpr *realexpr;
+ unsigned int position = 0;
+ gdb_assert (!(expr == NULL && (cookie == NULL || cookie->expr == NULL)));
+ gdb_assert (op != NULL);
+ gdb_assert (cookie == NULL || (cookie->operands_left == 0));
+ if (cookie->expr != NULL)
+ {
+ realexpr = cookie->expr;
+ position = cookie->position;
+ }
+ else
+ {
+ realexpr = expr;
+ position = 0;
+ }
+ *op = realexpr->data[position];
+ cookie->lastopcode = *op;
+ cookie->operands_left = locexpr_opcount[*op];
+ cookie->expr = realexpr;
+ cookie->position++;
+
+ }
+ void
+ locexpr_get_longest (struct locexpr_cookie *cookie, LONGEST *value)
+ {
+ unsigned char *newdata;
+ gdb_assert (cookie != NULL && cookie->expr != NULL);
+ gdb_assert (cookie->operands_left > 0);
+
+ newdata = read_sleb128 (cookie->expr->data + cookie->position, value);
+ cookie->position = newdata - (unsigned char *)cookie->expr->data;
+ cookie->operands_left--;
+
+ }
+ void
+ locexpr_get_ulongest (struct locexpr_cookie *cookie, ULONGEST *value)
+ {
+ unsigned char *newdata;
+ gdb_assert (cookie != NULL && cookie->expr != NULL);
+ gdb_assert (cookie->operands_left > 0);
+
+ newdata = read_uleb128 (cookie->expr->data + cookie->position, value);
+ cookie->position = newdata - (unsigned char *)cookie->expr->data;
+ cookie->operands_left--;
+
+ }
+ void
+ locexpr_get_uchar (struct locexpr_cookie *cookie, unsigned char *value)
+ {
+ gdb_assert (cookie != NULL && cookie->expr != NULL);
+ gdb_assert (cookie->operands_left > 0);
+
+ *value = (unsigned char)*(cookie->expr->data + cookie->position);
+ cookie->position++;
+ cookie->operands_left--;
+ }
+
+
+ static CORE_ADDR
+ execute_stack_op (struct symbol *var, unsigned char *op_ptr, unsigned char *op_end,
+ struct frame_info *frame, CORE_ADDR initial, value_ptr *currval)
+ {
+ CORE_ADDR stack[64]; /* ??? Assume this is enough. */
+ int stack_elt;
+ stack[0] = initial;
+ stack_elt = 1;
+ while (op_ptr < op_end)
+ {
+ enum locexpr_opcode op = *op_ptr++;
+ ULONGEST result, reg;
+ LONGEST offset;
+ switch (op)
+ {
+ case GLO_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 GLO_constu:
+ op_ptr = read_uleb128 (op_ptr, &result);
+ break;
+ case GLO_consts:
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ result = offset;
+ break;
+
+ case GLO_regx:
+ {
+ char *buf = (char*) alloca (MAX_REGISTER_RAW_SIZE);
+
+ op_ptr = read_uleb128 (op_ptr, ®);
+ get_saved_register (buf, NULL, NULL, frame, reg, NULL);
+ result = extract_address (buf, REGISTER_RAW_SIZE (reg));
+ if (currval != NULL)
+ {
+ store_typed_address (VALUE_CONTENTS_RAW (*currval), SYMBOL_TYPE (var), result);
+ VALUE_LVAL (*currval) = not_lval;
+ }
+ }
+ break;
+ case GLO_fbreg:
+ {
+ struct symbol *framefunc;
+ unsigned char *datastart;
+ unsigned char *dataend;
+ struct locexpr *theblock;
+
+ framefunc = get_frame_function (frame);
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ theblock = SYMBOL_FRAME_LOC_EXPR (framefunc);
+ datastart = theblock->data;
+ dataend = theblock->data + theblock->size;
+ result = execute_stack_op (var, datastart, dataend, frame, 0, NULL) + offset;
+ }
+ break;
+ case GLO_dup:
+ if (stack_elt < 1)
+ abort ();
+ result = stack[stack_elt - 1];
+ break;
+
+ case GLO_drop:
+ if (--stack_elt < 0)
+ abort ();
+ goto no_push;
+
+ case GLO_pick:
+ offset = *op_ptr++;
+ if (offset >= stack_elt - 1)
+ abort ();
+ result = stack[stack_elt - 1 - offset];
+ break;
+
+ case GLO_over:
+ if (stack_elt < 2)
+ abort ();
+ result = stack[stack_elt - 2];
+ break;
+
+ case GLO_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 GLO_deref:
+ case GLO_abs:
+ case GLO_neg:
+ case GLO_not:
+ /* Unary operations. */
+ if (--stack_elt < 0)
+ abort ();
+ result = stack[stack_elt];
+
+ switch (op)
+ {
+ case GLO_deref:
+ {
+ 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 GLO_abs:
+ if ((signed int) result < 0)
+ result = -result;
+ break;
+ case GLO_neg:
+ result = -result;
+ break;
+ case GLO_not:
+ result = ~result;
+ break;
+ }
+ break;
+
+ case GLO_and:
+ case GLO_div:
+ case GLO_minus:
+ case GLO_mod:
+ case GLO_mul:
+ case GLO_or:
+ case GLO_plus:
+ case GLO_le:
+ case GLO_ge:
+ case GLO_eq:
+ case GLO_lt:
+ case GLO_gt:
+ case GLO_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 GLO_and:
+ result = second & first;
+ break;
+ case GLO_div:
+ result = (LONGEST)second / (LONGEST)first;
+ break;
+ case GLO_minus:
+ result = second - first;
+ break;
+ case GLO_mod:
+ result = (LONGEST)second % (LONGEST)first;
+ break;
+ case GLO_mul:
+ result = second * first;
+ break;
+ case GLO_or:
+ result = second | first;
+ break;
+ case GLO_plus:
+ result = second + first;
+ break;
+ case GLO_shl:
+ result = second << first;
+ break;
+ case GLO_shr:
+ result = second >> first;
+ break;
+ case GLO_shra:
+ result = (LONGEST)second >> first;
+ break;
+ case GLO_xor:
+ result = second ^ first;
+ break;
+ case GLO_le:
+ result = (LONGEST)first <= (LONGEST)second;
+ break;
+ case GLO_ge:
+ result = (LONGEST)first >= (LONGEST)second;
+ break;
+ case GLO_eq:
+ result = (LONGEST)first == (LONGEST)second;
+ break;
+ case GLO_lt:
+ result = (LONGEST)first < (LONGEST)second;
+ break;
+ case GLO_gt:
+ result = (LONGEST)first > (LONGEST)second;
+ break;
+ case GLO_ne:
+ result = (LONGEST)first != (LONGEST)second;
+ break;
+ }
+ }
+ break;
+
+ case GLO_skip:
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ op_ptr += offset;
+ goto no_push;
+
+ case GLO_bra:
+ if (--stack_elt < 0)
+ abort ();
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ if (stack[stack_elt] != 0)
+ op_ptr += offset;
+ goto no_push;
+
+ case GLO_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 dwarf2 location description, given in THEBLOCK, in the
+ context of frame FRAME. */
+ value_ptr
+ evaluate_loc_expr (struct symbol *var, struct frame_info *frame,
+ struct locexpr *theblock, struct type *type)
+ {
+ CORE_ADDR result;
+ value_ptr 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;
+ }
+ void
+ _initialize_symeval (void)
+ {
+ struct locexpr *test;
+ struct locexpr_cookie temp3;
+ LONGEST temp;
+ ULONGEST temp2;
+ enum locexpr_opcode opcode;
+ memset (&temp3, 0, sizeof (temp3));
+
+ init_locexpr (&test);
+ locexpr_push_op (test, GLO_consts, "s", -100000);
+ locexpr_push_op (test, GLO_constu, "u", 100000);
+ locexpr_get_op (test, &temp3, &opcode);
+ locexpr_get_longest (&temp3, &temp);
+ locexpr_get_op (NULL, &temp3, &opcode);
+ locexpr_get_ulongest (&temp3, &temp2);
+ destroy_locexpr (&test);
+ }
Index: symeval.def
===================================================================
RCS file: symeval.def
diff -N symeval.def
*** /dev/null Tue May 5 13:32:27 1998
--- symeval.def Tue May 29 10:34:00 2001
***************
*** 0 ****
--- 1,38 ----
+ /* DEFINE_LOCEXPR_OPCODE (opcode, description, numargs, argtypes) */
+ DEFINE_LOCEXPR_OPCODE (GLO_addr, "Address", 1, "u")
+ DEFINE_LOCEXPR_OPCODE (GLO_constu, "Unsigned constant", 1, "u")
+ DEFINE_LOCEXPR_OPCODE (GLO_consts, "Signed constant", 1, "s")
+ DEFINE_LOCEXPR_OPCODE (GLO_dup, "Duplicate top of stack", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_drop, "Pop top of stack", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_over, "Push second entry of stack onto top of stack", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_pick, "Push a stack entry onto top of stack", 1, "c")
+ DEFINE_LOCEXPR_OPCODE (GLO_swap, "Swap top two stack entries", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_rot, "Rotate first three stack entries", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_xderef, "Extended dereference of top of stack", 1, "c")
+ DEFINE_LOCEXPR_OPCODE (GLO_deref, "Dereference top of stack", 1, "c")
+ DEFINE_LOCEXPR_OPCODE (GLO_abs, "Absolute value", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_and, "Bitwise AND", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_div, "Signed division", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_minus, "Subtraction", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_mod, "Modulo", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_mul, "Multiply", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_neg, "Negate", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_not, "Bitwise NOT", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_or, "Bitwise OR", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_plus, "Addition", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_shl, "Logical bitshift left", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_shr, "Logical bitshift right", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_shra, "Arithmetic bitshift right", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_xor, "Bitwise XOR", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_bra, "Conditional branch", 1, "s")
+ DEFINE_LOCEXPR_OPCODE (GLO_eq, "==", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_ge, ">=", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_gt, ">", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_le, "<=", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_lt, "<", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_ne, "!=", 0, "")
+ DEFINE_LOCEXPR_OPCODE (GLO_skip, "Unconditional branch", 1, "s")
+ DEFINE_LOCEXPR_OPCODE (GLO_regx, "Get register value", 1, "u")
+ DEFINE_LOCEXPR_OPCODE (GLO_fbreg, "Frame based value", 1, "s")
+ DEFINE_LOCEXPR_OPCODE (GLO_piece, "Piece of object", 1, "u")
+ DEFINE_LOCEXPR_OPCODE (GLO_nop, "No operation", 0, "")
\ No newline at end of file
Index: symeval.h
===================================================================
RCS file: symeval.h
diff -N symeval.h
*** /dev/null Tue May 5 13:32:27 1998
--- symeval.h Tue May 29 10:34:00 2001
***************
*** 0 ****
--- 1,20 ----
+ #ifndef SYMEVAL_H
+ #define SYMEVAL_H
+ /* Make up the enum from the list of opcodes */
+ #define DEFINE_LOCEXPR_OPCODE(opcode, desc, numargs, argtypes) opcode,
+ enum locexpr_opcode
+ {
+ #include "symeval.def"
+ };
+ #undef DEFINE_LOCEXPR_OPCODE
+ struct locexpr_cookie;
+ struct locexpr;
+ void init_locexpr (struct locexpr **);
+ void destroy_locexpr (struct locexpr **);
+ void locexpr_push_op (struct locexpr *, enum locexpr_opcode, const char *, ...);
+ void locexpr_get_op (struct locexpr *, struct locexpr_cookie *, enum locexpr_opcode *);
+ void locexpr_get_longest (struct locexpr_cookie *, LONGEST *);
+ void locexpr_get_ulongest (struct locexpr_cookie *, ULONGEST *);
+ void locexpr_get_uchar (struct locexpr_cookie *, unsigned char *);
+ value_ptr evaluate_loc_expr (struct symbol *, struct frame_info *, struct locexpr *, struct type *);
+ #endif
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.21
diff -c -3 -p -w -B -b -r1.21 symtab.h
*** symtab.h 2001/04/27 00:19:09 1.21
--- symtab.h 2001/05/29 17:34:08
*************** enum address_class
*** 653,660 ****
* than the one where the global was allocated are done
* with a level of indirection.
*/
! LOC_INDIRECT
};
--- 642,654 ----
* than the one where the global was allocated are done
* with a level of indirection.
*/
+
+ LOC_INDIRECT,
! /* Location is a location expression */
! LOC_LOC_EXPR,
! /* Location is a location list (ranges + location expressions) */
! LOC_LOC_LIST
};
*************** struct symbol
*** 713,718 ****
--- 711,721 ----
short basereg;
}
aux_value;
+ struct
+ {
+ struct locexpr *loc;
+ struct locexpr *frameloc;
+ } dynamic_location;
/* Link to a list of aliases for this symbol.
*************** struct symbol
*** 730,735 ****
--- 736,743 ----
#define SYMBOL_TYPE(symbol) (symbol)->type
#define SYMBOL_LINE(symbol) (symbol)->line
#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg
+ #define SYMBOL_LOC_EXPR(symbol) (symbol)->dynamic_location.loc
+ #define SYMBOL_FRAME_LOC_EXPR(symbol) (symbol)->dynamic_location.frameloc
#define SYMBOL_ALIASES(symbol) (symbol)->aliases
#define SYMBOL_RANGES(symbol) (symbol)->ranges
*************** struct linetable
*** 805,810 ****
--- 813,819 ----
struct linetable_entry item[1];
};
+ struct locexpr;
/* All the information on one source file. */
struct source
--
"Yesterday I parked my car in a tow-away zone... When I came
back the entire area was missing.
"-Steven Wright