From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27600 invoked by alias); 2 Apr 2002 14:50:46 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 27587 invoked from network); 2 Apr 2002 14:50:44 -0000 Received: from unknown (HELO tetsuo.nj.caldera.com) (63.124.204.226) by sources.redhat.com with SMTP; 2 Apr 2002 14:50:44 -0000 Received: from caldera.com (localhost.localdomain [127.0.0.1]) by tetsuo.nj.caldera.com (8.11.6/8.11.6) with ESMTP id g32EvX931912; Tue, 2 Apr 2002 09:57:33 -0500 Message-ID: <3CA9C6DC.12980657@caldera.com> Date: Tue, 02 Apr 2002 06:50:00 -0000 From: Petr Sorfa Organization: Caldera X-Accept-Language: en MIME-Version: 1.0 To: Jim Blandy CC: Daniel Berlin , gdb-patches@sources.redhat.com Subject: Re: [PATCH] Let dwarf2 CFI's execute_stack_op be used outside of CFI References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-04/txt/msg00019.txt.bz2 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);