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



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]