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: Petr Sorfa <petrs at caldera dot com>
- To: Jim Blandy <jimb at redhat dot com>
- Cc: Daniel Berlin <dan at dberlin dot org>, gdb-patches at sources dot redhat dot com
- Date: Tue, 02 Apr 2002 09:57:32 -0500
- Subject: Re: [PATCH] Let dwarf2 CFI's execute_stack_op be used outside of CFI
- Organization: Caldera
- References: <Pine.LNX.4.44.0203281615530.3834-100000@dberlin.org> <npsn6knubd.fsf@zwingli.cygnus.com>
Hi Jim,
I've implemented a dwarf3 location expression parser for GDB. My
solution is, well, different than yours. I've gone for a more simpler
(limited) solution based on the existing dwarf2read.c decode_locdesc
function. It basically processes the location expression data passed to
through a "dwarf block" which contains the raw DWARF data block and it's
size.
Since GDB currently does not have an intermediate location expression
framework, I attach the dwarf blocks to relevant areas, such as:
struct general_symbol_info (for data location)
struct type (for array ranges (upper and lower bounds, stride),
associated and allocated expressions)
I understand that you are suggesting a more useful and generic solution
which can be detached from gdb completely.
Just letting you know the approach I took.
Petr
> 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);