Hi Roland,

On Mon, 2009-07-20 at 12:12 -0700, Roland McGrath wrote:
> Let's take the two separately.  For the low-level stuff, DW_OP_stack_value
> is trivial to support.  I added that.

Thanks. BTW. You removed DW_OP_GNU_push_tls_address in 96349f, I assume
by accident.

> > -    DW_OP_implicit_value = 0x9e, /* DW_FORM_block follows opcode.  */
> > +    DW_OP_implicit_value = 0x9e, /* ULEB128 size, followed by size bytes
> > +                               in target memory representation.  */
> 
> Um.  So, that's what DW_FORM_block means.
> 
> The whole issue of the constant block being in target format is not new.
> It's as it should be, and it's just the same as you already have for
> e.g. DW_AT_const_value with a DW_FORM_block* (constant block) value.

Ah, yes. I clearly was a bit confused. I really wanted DW_FORM... to be
about the data type, but it isn't. Which is a pity since that does
indeed mean, there is no easy way of representing it in general. O well.

Here is an updated patch for readelf -w support, that doesn't try to be
clever and that just outputs the value bytes as is in hex. e.g.
"implicit_value 4 (ef be ad de)"

2009-07-20  Mark Wielaard  <[email protected]>

    * readelf.c (print_ops): Add handling of DW_OP_implicit_value
    and DW_OP_stack_value.

> My inclination is to make DW_OP_implicit_value a special case from the
> libdw API perspective.  That is, the number/number2 fields will be
> "internal form" rather than directly usable.  Then we give a call you can
> pass such a Dwarf_Op to yield a Dwarf_Block.  
> 
> My inclination is to let this do some sanity-checking against bogus
> Dwarf_Op's consed by callers, which means not just shoving pointers in
> there.  Instead, it means the implicit_value->block call would take not
> just the Dwarf_Op but also something like the Dwarf_Attribute that was used
> to retrieve it.  With that, we could encode it as number=size,number2=secoff
> where secoff is the offset into the .debug_{info,loc} section where the
> data begins (i.e. after the size ULEB128).  From the Dwarf_Attribute's form
> we can tell whether this op should refer to .debug_loc or .debug_info, and
> then partially sanity-check the offset and size.

That would certainly work for me. You would also need a variant that
takes a Dwarf_Frame to match up with .debug_frame/.eh_frame.

Thanks,

Mark
>From 6d762e6effbff170bdad35d29c564c6fff1896b6 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <[email protected]>
Date: Mon, 20 Jul 2009 23:11:08 +0200
Subject: [PATCH] Add handling of DW_OP_implicit_value and DW_OP_stack_value to readelf -w.

---
 src/ChangeLog |    5 +++++
 src/readelf.c |   18 ++++++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 69f9a65..84e4f54 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-20  Mark Wielaard  <[email protected]>
+
+	* readelf.c (print_ops): Add handling of DW_OP_implicit_value
+	and DW_OP_stack_value.
+
 2009-07-14  Ulrich Drepper  <[email protected]>
 
 	* elflint.c (check_elf_header): Allow Linux ABI.
diff --git a/src/readelf.c b/src/readelf.c
index 2e8257f..772e897 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3880,6 +3880,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
       [DW_OP_form_tls_address] = "form_tls_address",
       [DW_OP_call_frame_cfa] = "call_frame_cfa",
       [DW_OP_bit_piece] = "bit_piece",
+      [DW_OP_implicit_value] = "implicit_value",
+      [DW_OP_stack_value] = "stack_value",
     };
 
   if (len == 0)
@@ -4092,6 +4094,22 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  offset += 3;
 	  break;
 
+	case DW_OP_implicit_value:
+	  {
+	    const unsigned char *start_op = data;
+	    unsigned int ulen;
+	    get_uleb128 (ulen, data); /* XXX check overrun */
+	    printf ("%*s[%4" PRIuMAX "] %s %u (",
+		    indent, "", (uintmax_t) offset, known[op], ulen);
+	    NEED (ulen);
+	    while (ulen-- > 1)
+	      printf("%02x ", *data++);
+	    printf("%02x)\n", *data++);
+	    len -= (data - start_op);
+	    offset += 1 + (data - start_op);
+	    break;
+	  }
+
 	default:
 	  /* No Operand.  */
 	  if (op < sizeof known / sizeof known[0] && known[op] != NULL)
-- 
1.6.2.5

_______________________________________________
elfutils-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/elfutils-devel

Reply via email to