This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [PATCH] Let dwarf2 CFI's execute_stack_op be used outside of CFI
- From: Jim Blandy <jimb at redhat dot com>
- To: Daniel Berlin <dan at dberlin dot org>
- Cc: gdb-patches at sources dot redhat dot com
- Date: 28 Mar 2002 18:31:18 -0500
- Subject: Re: [PATCH] Let dwarf2 CFI's execute_stack_op be used outside of CFI
- References: <Pine.LNX.4.44.0203281615530.3834-100000@dberlin.org>
I've read through the new Dwarf spec some more. You're right ---
they've added a bunch of stuff like DW_OP_push_object_address and
DW_OP_call, and cases where you're supposed to push stuff on the
stack, etc.
But what I'm going for here is something we could, in the long run,
put in libiberty and just have GDB use from there. Surely there are
other applications that could use a Dwarf expression interpreter.
Would something like the below be sufficient? Rename to taste. (Feel
free to say, "Yes, but that's way beyond what I offered to do." Also
feel free to say, "You look like you're trying to write C++ programs
in C.")
struct dwarf_expr_context
{
/* The stack of values, allocated with xmalloc. */
ADDR_TYPE *stack;
/* The number of values currently pushed on the stack, and the
number of elements allocated to the stack. */
int stack_len, stack_allocated;
/* The size of an address, in bits. */
int addr_size;
/* Return the value of register number REGNUM. */
ADDR_TYPE (*read_reg) (void *baton, int regnum);
void *read_reg_baton;
/* Return the LEN-byte value at ADDR. */
ADDR_TYPE (*read_mem) (void *baton, ADDR_TYPE addr, size_t len);
void *read_mem_baton;
/* Return the location expression for the frame base attribute. The
result must be live until the current expression evaluation is
complete. */
unsigned char *(*get_frame_base) (void *baton);
void *get_frame_base_baton;
/* Return the location expression for the dwarf expression
subroutine in the die at OFFSET in the current compilation unit.
The result must be live until the current expression evaluation
is complete. */
unsigned char *(*get_subr) (void *baton, offset_t offset);
void *get_subr_baton;
/* Return the `object address' for DW_OP_push_object_address. */
ADDR_TYPE (*get_object_address) (void *baton);
void *get_object_address_baton;
/* The current depth of dwarf expression recursion, via DW_OP_call*,
DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum
depth we'll tolerate before raising an error. */
int recursion_depth, max_recursion_depth;
/* Add whatever you want here; the caller is supposed to use
new_dwarf_expr_context to make these, which can fill in default
values. */
};
/* Return a new context, with no values on the stack. */
struct dwarf_expr_context *new_dwarf_expr_context ();
/* Free CONTEXT. */
void free_dwarf_expr_context (struct dwarf_expr_context *context);
/* Push VALUE on CONTEXT's stack. Reallocate the stack as needed. */
void dwarf_expr_push (struct dwarf_expr_context *context, ADDR_TYPE value);
/* Evaluate the LEN bytes at ADDR as a dwarf expression in CONTEXT. */
void dwarf_expr_eval (struct dwarf_expr_context *context,
unsigned char *addr, size_t len);
/* Return the value N values down from the top of CONTEXT's stack.
This raises an error if there aren't at least N+1 values on the stack. */
ADDR_TYPE dwarf_expr_fetch (struct dwarf_expr_context *context, int n);