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]

Re: [PATCH] Let dwarf2 CFI's execute_stack_op be used outside of CFI


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);


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