On Fri, Sep 17, 2010 at 06:32:29PM +0200, Petr Machata wrote:
21.07.2010 03:58, Roland McGrath wrote:
>Jakub was interested in sampling some DWARF data to compare what one
>compiler vs another is doing with some broad statistics of semantic
>interest. The first particular thing to measure is how much location/value
>information we are getting for variables and parameters.
This is now on the dwarf branch. Use like this:
dwarflint --check=locstats binary
Thanks.
Unfortunately it doesn't work too well with trunk gcc because of
implicit_pointer.
I've tried to patch
--- dwarflint/check_debug_loc_range.cc.jj 2010-09-20 14:01:41.000000000 +0200
+++ dwarflint/check_debug_loc_range.cc 2010-09-20 15:04:10.543533890 +0200
@@ -731,7 +731,8 @@ namespace
{
/* Operands are passed back as attribute forms. In particular,
DW_FORM_dataX for X-byte operands, DW_FORM_[us]data for
- ULEB128/SLEB128 operands, and DW_FORM_addr for 32b/64b operands.
+ ULEB128/SLEB128 operands, and DW_FORM_addr/DW_FORM_ref_addr
+ for 32b/64b operands.
If the opcode takes no operands, 0 is passed.
Return value is false if we couldn't determine (i.e. invalid
@@ -767,16 +768,21 @@ namespace
form. For block forms, the value passed back in VALUEP is block
length. */
bool
- read_ctx_read_form (struct read_ctx *ctx, int address_size, uint8_t form,
- uint64_t *valuep, struct where *where, const char *what,
- bool *is_blockp)
+ read_ctx_read_form (struct read_ctx *ctx, struct cu *cu,
+ uint8_t form, uint64_t *valuep, struct where *where,
+ const char *what, bool *is_blockp)
{
if (is_blockp != NULL)
*is_blockp = false;
switch (form)
{
case DW_FORM_addr:
- return read_ctx_read_offset (ctx, address_size == 8, valuep);
+ return read_ctx_read_offset (ctx, cu->head->address_size == 8, valuep);
+ case DW_FORM_ref_addr:
+ return read_ctx_read_offset (ctx, (cu->head->version >= 3
+ ? cu->head->offset_size
+ : cu->head->address_size) == 8,
+ valuep);
case DW_FORM_udata:
return checked_read_uleb128 (ctx, valuep, where, what);
case DW_FORM_sdata:
@@ -831,7 +837,7 @@ namespace
}
*is_blockp = true;
- return read_ctx_read_form (ctx, address_size, dform,
+ return read_ctx_read_form (ctx, cu, dform,
valuep, where, what, NULL)
&& read_ctx_skip (ctx, *valuep);
}
@@ -879,7 +885,7 @@ namespace
bool isblock;
uint64_t off = read_ctx_get_offset (ctx) + init_off;
- if (!read_ctx_read_form (ctx, cu->head->address_size, form,
+ if (!read_ctx_read_form (ctx, cu, form,
valuep, where, str, &isblock))
{
wr_error (*where)
--- src/dwarf-opcodes.h.jj 2010-09-20 14:01:41.000000000 +0200
+++ src/dwarf-opcodes.h 2010-09-20 14:58:30.987377620 +0200
@@ -196,7 +196,7 @@
DW_OP_0 (DW_OP_push_object_address) \
DW_OP_1 (DW_OP_call2, DW_FORM_data2) \
DW_OP_1 (DW_OP_call4, DW_FORM_data4) \
- DW_OP_1 (DW_OP_call_ref, DW_FORM_addr) \
+ DW_OP_1 (DW_OP_call_ref, DW_FORM_ref_addr) \
DW_OP_0 (DW_OP_form_tls_address) \
DW_OP_0 (DW_OP_GNU_push_tls_address) \
DW_OP_0 (DW_OP_call_frame_cfa) \
@@ -204,4 +204,6 @@
DW_OP_0 (DW_OP_GNU_uninit) \
/* DWARF 4 */ \
DW_OP_0 (DW_OP_stack_value) \
- DW_OP_1 (DW_OP_implicit_value, DW_FORM_block)
+ DW_OP_1 (DW_OP_implicit_value, DW_FORM_block) \
+ /* GNU extensions */ \
+ DW_OP_1 (DW_OP_GNU_implicit_pointer, DW_FORM_ref_addr)
but that isn't enough, with that it still complains:
error: location expression: offset 0x1b496: can't decode opcode "unknown opcode
0".
...
Didn't have time to debug this more...
Jakub