From: Daniel Berlin <dberlin@dberlin.org>
To: gdb-patches@sources.redhat.com
Cc: jimb@redhat.com
Subject: [RFA]: dwarf2expr.[ch]
Date: Mon, 08 Jul 2002 16:48:00 -0000 [thread overview]
Message-ID: <Pine.LNX.4.44.0207081941190.31676-100000@dberlin.org> (raw)
Here were the dwarf2expr.[ch] that were not included.
Sorry again about that.
I haven't touched this code in ages, since it just works (tested on
powerpc-linux/i686-pc-linux-gnu/powerpc-eabisim on i686), so it may be
there are better ways to do things since i wrote it.
I also can't remember why get_subr was needed, and never implemented it.
Refresh my memory if you could, since you wrote the spec?
:)
I've only reposted it for completeness sake, i'll include it again when i
revise the loc_computed patch.
--Dan
Index: dwarf2expr.c
===================================================================
RCS file: dwarf2expr.c
diff -N dwarf2expr.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- dwarf2expr.c 8 Jul 2002 23:41:18 -0000
***************
*** 0 ****
--- 1,479 ----
+
+ #include "defs.h"
+ #include "symtab.h"
+ #include "gdbtypes.h"
+ #include "elf/dwarf2.h"
+ #include "dwarf2expr.h"
+ struct dwarf_expr_context * new_dwarf_expr_context()
+ {
+ struct dwarf_expr_context *retval;
+ retval = xcalloc (1, sizeof (struct dwarf_expr_context));
+ return retval;
+ }
+ void free_dwarf_expr_context (struct dwarf_expr_context *ctx)
+ {
+ free (ctx->stack);
+ free (ctx);
+ }
+ static void dwarf_expr_grow_stack (struct dwarf_expr_context *ctx, size_t need)
+ {
+ if (ctx->stack_len + need > ctx->stack_allocated)
+ {
+ ctx->stack = xrealloc (ctx->stack,
+ (ctx->stack_len + need) * sizeof (CORE_ADDR));
+ ctx->stack_allocated = ctx->stack_len + need;
+ }
+ }
+ void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value)
+ {
+ dwarf_expr_grow_stack (ctx, 1);
+ ctx->stack[ctx->stack_len++] = value;
+ }
+ void dwarf_expr_pop (struct dwarf_expr_context *ctx)
+ {
+ ctx->stack_len--;
+ }
+ static void execute_stack_op (struct dwarf_expr_context *,
+ unsigned char *,
+ unsigned char *);
+ void dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr, size_t len)
+ {
+ execute_stack_op (ctx, addr, addr + len);
+ }
+
+ CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n)
+ {
+ if (ctx->stack_len < n)
+ (ctx->error) ("Asked for position %d of stack, stack only has %d elements on it\n",
+ n, ctx->stack_len);
+ return ctx->stack[ctx->stack_len - (1+n)];
+
+ }
+ /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
+ by R, and return the new value of BUF. */
+
+ static unsigned char *
+ read_uleb128 (unsigned char *buf, ULONGEST *r)
+ {
+ unsigned shift = 0;
+ ULONGEST result = 0;
+
+ while (1)
+ {
+ unsigned char byte = *buf++;
+ result |= (byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+ *r = result;
+ return buf;
+ }
+
+ /* Decode the signed LEB128 constant at BUF into the variable pointed to
+ by R, and return the new value of BUF. */
+
+ static unsigned char *
+ read_sleb128 (unsigned char *buf, LONGEST *r)
+ {
+ unsigned shift = 0;
+ LONGEST result = 0;
+ unsigned char byte;
+
+ while (1)
+ {
+ byte = *buf++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+ if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
+ result |= - (1 << shift);
+
+ *r = result;
+ return buf;
+ }
+ static void
+ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
+ unsigned char *op_end)
+ {
+ while (op_ptr < op_end)
+ {
+ enum dwarf_location_atom op = *op_ptr++;
+ ULONGEST result, reg;
+ LONGEST offset;
+ ctx->in_reg = 0;
+ switch (op)
+ {
+ case DW_OP_lit0:
+ case DW_OP_lit1:
+ case DW_OP_lit2:
+ case DW_OP_lit3:
+ case DW_OP_lit4:
+ case DW_OP_lit5:
+ case DW_OP_lit6:
+ case DW_OP_lit7:
+ case DW_OP_lit8:
+ case DW_OP_lit9:
+ case DW_OP_lit10:
+ case DW_OP_lit11:
+ case DW_OP_lit12:
+ case DW_OP_lit13:
+ case DW_OP_lit14:
+ case DW_OP_lit15:
+ case DW_OP_lit16:
+ case DW_OP_lit17:
+ case DW_OP_lit18:
+ case DW_OP_lit19:
+ case DW_OP_lit20:
+ case DW_OP_lit21:
+ case DW_OP_lit22:
+ case DW_OP_lit23:
+ case DW_OP_lit24:
+ case DW_OP_lit25:
+ case DW_OP_lit26:
+ case DW_OP_lit27:
+ case DW_OP_lit28:
+ case DW_OP_lit29:
+ case DW_OP_lit30:
+ case DW_OP_lit31:
+ result = op - DW_OP_lit0;
+ break;
+
+ case DW_OP_addr:
+ result = (CORE_ADDR)
+ extract_unsigned_integer (op_ptr,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ op_ptr += TARGET_PTR_BIT / TARGET_CHAR_BIT;
+ break;
+
+ case DW_OP_const1u:
+ result = extract_unsigned_integer (op_ptr, 1);
+ op_ptr += 1;
+ break;
+ case DW_OP_const1s:
+ result = extract_signed_integer (op_ptr, 1);
+ op_ptr += 1;
+ break;
+ case DW_OP_const2u:
+ result = extract_unsigned_integer (op_ptr, 2);
+ op_ptr += 2;
+ break;
+ case DW_OP_const2s:
+ result = extract_signed_integer (op_ptr, 2);
+ op_ptr += 2;
+ break;
+ case DW_OP_const4u:
+ result = extract_unsigned_integer (op_ptr, 4);
+ op_ptr += 4;
+ break;
+ case DW_OP_const4s:
+ result = extract_signed_integer (op_ptr, 4);
+ op_ptr += 4;
+ break;
+ case DW_OP_const8u:
+ result = extract_unsigned_integer (op_ptr, 8);
+ op_ptr += 8;
+ break;
+ case DW_OP_const8s:
+ result = extract_signed_integer (op_ptr, 8);
+ op_ptr += 8;
+ break;
+ case DW_OP_constu:
+ op_ptr = read_uleb128 (op_ptr, &result);
+ break;
+ case DW_OP_consts:
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ result = offset;
+ break;
+
+ case DW_OP_reg0:
+ case DW_OP_reg1:
+ case DW_OP_reg2:
+ case DW_OP_reg3:
+ case DW_OP_reg4:
+ case DW_OP_reg5:
+ case DW_OP_reg6:
+ case DW_OP_reg7:
+ case DW_OP_reg8:
+ case DW_OP_reg9:
+ case DW_OP_reg10:
+ case DW_OP_reg11:
+ case DW_OP_reg12:
+ case DW_OP_reg13:
+ case DW_OP_reg14:
+ case DW_OP_reg15:
+ case DW_OP_reg16:
+ case DW_OP_reg17:
+ case DW_OP_reg18:
+ case DW_OP_reg19:
+ case DW_OP_reg20:
+ case DW_OP_reg21:
+ case DW_OP_reg22:
+ case DW_OP_reg23:
+ case DW_OP_reg24:
+ case DW_OP_reg25:
+ case DW_OP_reg26:
+ case DW_OP_reg27:
+ case DW_OP_reg28:
+ case DW_OP_reg29:
+ case DW_OP_reg30:
+ case DW_OP_reg31:
+ {
+ result = (ctx->read_reg) (ctx->read_reg_baton, op - DW_OP_reg0);
+ ctx->in_reg = 1;
+ }
+ break;
+ case DW_OP_regx:
+ {
+ op_ptr = read_uleb128 (op_ptr, ®);
+ result = (ctx->read_reg) (ctx->read_reg_baton, reg);
+ ctx->in_reg = 1;
+ }
+ break;
+ case DW_OP_breg0:
+ case DW_OP_breg1:
+ case DW_OP_breg2:
+ case DW_OP_breg3:
+ case DW_OP_breg4:
+ case DW_OP_breg5:
+ case DW_OP_breg6:
+ case DW_OP_breg7:
+ case DW_OP_breg8:
+ case DW_OP_breg9:
+ case DW_OP_breg10:
+ case DW_OP_breg11:
+ case DW_OP_breg12:
+ case DW_OP_breg13:
+ case DW_OP_breg14:
+ case DW_OP_breg15:
+ case DW_OP_breg16:
+ case DW_OP_breg17:
+ case DW_OP_breg18:
+ case DW_OP_breg19:
+ case DW_OP_breg20:
+ case DW_OP_breg21:
+ case DW_OP_breg22:
+ case DW_OP_breg23:
+ case DW_OP_breg24:
+ case DW_OP_breg25:
+ case DW_OP_breg26:
+ case DW_OP_breg27:
+ case DW_OP_breg28:
+ case DW_OP_breg29:
+ case DW_OP_breg30:
+ case DW_OP_breg31:
+ {
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ result = (ctx->read_reg) (ctx->read_reg_baton, op - DW_OP_breg0);
+ result += offset;
+ }
+ break;
+ case DW_OP_bregx:
+ {
+ op_ptr = read_uleb128 (op_ptr, ®);
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ result = (ctx->read_reg) (ctx->read_reg_baton, reg);
+ result += offset;
+ }
+ break;
+ case DW_OP_fbreg:
+ {
+ unsigned char *datastart;
+ unsigned char *dataend;
+ unsigned int before_stack_len;
+
+ op_ptr = read_sleb128 (op_ptr, &offset);
+ /* Rather than create a whole new context, we simply
+ record the stack length before execution, then reset it
+ afterwards, effectively erasing whatever the recursive
+ call put there. */
+ before_stack_len = ctx->stack_len;
+ (ctx->get_frame_base)(ctx->get_frame_base_baton, &datastart, &dataend);
+ dwarf_expr_eval (ctx, datastart, dataend - datastart);
+ result = dwarf_expr_fetch (ctx, 0) + offset;
+ ctx->stack_len = before_stack_len;
+ ctx->in_reg = 0;
+ }
+ break;
+ case DW_OP_dup:
+ result = dwarf_expr_fetch (ctx, 0);
+ break;
+
+ case DW_OP_drop:
+ dwarf_expr_pop(ctx);
+ goto no_push;
+
+ case DW_OP_pick:
+ offset = *op_ptr++;
+ result = dwarf_expr_fetch (ctx, offset);
+ break;
+
+ case DW_OP_over:
+ result = dwarf_expr_fetch (ctx, 1);
+ break;
+
+ case DW_OP_rot:
+ {
+ CORE_ADDR t1, t2, t3;
+
+ if (ctx->stack_len < 3)
+ (ctx->error) ("Not enough elements for DW_OP_rot. Need 3, have %d\n",
+ ctx->stack_len);
+ t1 = ctx->stack[ctx->stack_len - 1];
+ t2 = ctx->stack[ctx->stack_len - 2];
+ t3 = ctx->stack[ctx->stack_len - 3];
+ ctx->stack[ctx->stack_len - 1] = t2;
+ ctx->stack[ctx->stack_len - 2] = t3;
+ ctx->stack[ctx->stack_len - 3] = t1;
+ goto no_push;
+ }
+
+ case DW_OP_deref:
+ case DW_OP_deref_size:
+ case DW_OP_abs:
+ case DW_OP_neg:
+ case DW_OP_not:
+ case DW_OP_plus_uconst:
+ /* Unary operations. */
+ result = dwarf_expr_fetch (ctx, 0);
+ dwarf_expr_pop (ctx);
+
+ switch (op)
+ {
+ case DW_OP_deref:
+ {
+ result = (CORE_ADDR)
+ (ctx->read_mem) (ctx->read_mem_baton,
+ result,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ }
+ break;
+
+ case DW_OP_deref_size:
+ {
+ result = (ctx->read_mem) (ctx->read_mem_baton, result, *op_ptr++);
+ }
+ break;
+
+ case DW_OP_abs:
+ if ((signed int) result < 0)
+ result = -result;
+ break;
+ case DW_OP_neg:
+ result = -result;
+ break;
+ case DW_OP_not:
+ result = ~result;
+ break;
+ case DW_OP_plus_uconst:
+ op_ptr = read_uleb128 (op_ptr, ®);
+ result += reg;
+ break;
+ }
+ break;
+
+ case DW_OP_and:
+ case DW_OP_div:
+ case DW_OP_minus:
+ case DW_OP_mod:
+ case DW_OP_mul:
+ case DW_OP_or:
+ case DW_OP_plus:
+ case DW_OP_le:
+ case DW_OP_ge:
+ case DW_OP_eq:
+ case DW_OP_lt:
+ case DW_OP_gt:
+ case DW_OP_ne:
+ {
+ /* Binary operations. */
+ CORE_ADDR first, second;
+ second = dwarf_expr_fetch (ctx, 0);
+ first = dwarf_expr_fetch (ctx, 1);
+ dwarf_expr_pop (ctx);
+ dwarf_expr_pop (ctx);
+ switch (op)
+ {
+ case DW_OP_and:
+ result = second & first;
+ break;
+ case DW_OP_div:
+ result = (LONGEST)second / (LONGEST)first;
+ break;
+ case DW_OP_minus:
+ result = second - first;
+ break;
+ case DW_OP_mod:
+ result = (LONGEST)second % (LONGEST)first;
+ break;
+ case DW_OP_mul:
+ result = second * first;
+ break;
+ case DW_OP_or:
+ result = second | first;
+ break;
+ case DW_OP_plus:
+ result = second + first;
+ break;
+ case DW_OP_shl:
+ result = second << first;
+ break;
+ case DW_OP_shr:
+ result = second >> first;
+ break;
+ case DW_OP_shra:
+ result = (LONGEST)second >> first;
+ break;
+ case DW_OP_xor:
+ result = second ^ first;
+ break;
+ case DW_OP_le:
+ result = (LONGEST)first <= (LONGEST)second;
+ break;
+ case DW_OP_ge:
+ result = (LONGEST)first >= (LONGEST)second;
+ break;
+ case DW_OP_eq:
+ result = (LONGEST)first == (LONGEST)second;
+ break;
+ case DW_OP_lt:
+ result = (LONGEST)first < (LONGEST)second;
+ break;
+ case DW_OP_gt:
+ result = (LONGEST)first > (LONGEST)second;
+ break;
+ case DW_OP_ne:
+ result = (LONGEST)first != (LONGEST)second;
+ break;
+ }
+ }
+ break;
+
+ case DW_OP_skip:
+ offset = extract_signed_integer (op_ptr, 2);
+ op_ptr += 2;
+ op_ptr += offset;
+ goto no_push;
+
+ case DW_OP_bra:
+ offset = extract_signed_integer (op_ptr, 2);
+ op_ptr += 2;
+ if (dwarf_expr_fetch (ctx, 0) != 0)
+ op_ptr += offset;
+ dwarf_expr_pop (ctx);
+ goto no_push;
+
+ case DW_OP_nop:
+ goto no_push;
+
+ default:
+ abort ();
+ }
+
+ /* Most things push a result value. */
+ dwarf_expr_push (ctx, result);
+ no_push:;
+ }
+ }
Index: dwarf2expr.h
===================================================================
RCS file: dwarf2expr.h
diff -N dwarf2expr.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- dwarf2expr.h 8 Jul 2002 23:41:18 -0000
***************
*** 0 ****
--- 1,57 ----
+ #if !defined (DWARF2EXPR_H)
+ #define DWARF2EXPR_H
+ struct dwarf_expr_context
+ {
+ /* The stack of values, allocated with xmalloc. */
+ CORE_ADDR *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. */
+ CORE_ADDR (*read_reg) (void *baton, int regnum);
+ void *read_reg_baton;
+
+ /* Return the LEN-byte value at ADDR. */
+ CORE_ADDR (*read_mem) (void *baton, CORE_ADDR 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. */
+ void (*get_frame_base) (void *baton, unsigned char **begin,
+ unsigned char **end);
+ 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, off_t offset);
+ void *get_subr_baton;
+
+ /* Return the `object address' for DW_OP_push_object_address. */
+ CORE_ADDR (*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;
+
+ int in_reg;
+
+ void (*error) (const char *fmt, ...);
+ };
+ struct dwarf_expr_context * new_dwarf_expr_context();
+ void free_dwarf_expr_context (struct dwarf_expr_context *ctx);
+ void dwarf_expr_push (struct dwarf_expr_context *ctx, CORE_ADDR value);
+ void dwarf_expr_pop (struct dwarf_expr_context *ctx);
+ void dwarf_expr_eval (struct dwarf_expr_context *ctx, unsigned char *addr,
+ size_t len);
+ CORE_ADDR dwarf_expr_fetch (struct dwarf_expr_context *ctx, int n);
+ #endif
next reply other threads:[~2002-07-08 23:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-07-08 16:48 Daniel Berlin [this message]
2002-07-08 20:20 ` Andrew Cagney
2002-07-08 20:49 ` Daniel Berlin
2002-07-08 21:12 ` Andrew Cagney
2002-07-09 15:21 ` Jim Blandy
2002-07-10 9:05 ` Andrew Cagney
2002-07-09 15:10 ` Jim Blandy
2002-07-09 16:00 ` Daniel Berlin
2002-07-10 11:18 ` Daniel Berlin
2002-07-10 12:48 ` Jim Blandy
2002-07-10 13:27 ` Daniel Berlin
2002-07-10 16:15 ` Jim Blandy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.44.0207081941190.31676-100000@dberlin.org \
--to=dberlin@dberlin.org \
--cc=gdb-patches@sources.redhat.com \
--cc=jimb@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox