location list

Sasha Da Rocha Pinheiro darochapinhe@wisc.edu
Sat Jun 6 00:30:34 GMT 2020


As you can see the following variables have distinct locations:
 [    81]      variable             abbrev: 5
               name                 (string) "a"
               decl_file            (data1) sasha.c (1)
               decl_line            (data1) 12
               type                 (ref4) [    cd]
               location             (sec_offset) location list [     0]
 [    9f]        variable             abbrev: 5
                 name                 (string) "g"
                 decl_file            (data1) sasha.c (1)
                 decl_line            (data1) 15
                 type                 (ref4) [    cd]
                 location             (sec_offset) location list [    4a]
[    bd]          variable             abbrev: 5
                   name                 (string) "z"
                   decl_file            (data1) sasha.c (1)
                   decl_line            (data1) 16
                   type                 (ref4) [    cd]
                   location             (sec_offset) location list [    6e]

But when I use the code I sent before to list the three variables, I always get:

[main01.cpp:73] - Variable and location found (a), size(1).
[main01.cpp:78] - interval: (0x0,0x5) 
[main01.cpp:78] - interval: (0x5,0xa) 
[main01.cpp:78] - interval: (0x16,0x24) 
[main01.cpp:73] - Variable and location found (g), size(1).
[main01.cpp:78] - interval: (0x0,0x5) 
[main01.cpp:78] - interval: (0x5,0xa) 
[main01.cpp:78] - interval: (0x16,0x24) 
[main01.cpp:73] - Variable and location found (z), size(1).
[main01.cpp:78] - interval: (0x0,0x5) 
[main01.cpp:78] - interval: (0x5,0xa) 
[main01.cpp:78] - interval: (0x16,0x24) 


No matter the locationAttribute the code always get the first location descriptors in .debug_loc: 
 
DWARF section [ 7] '.debug_loc' at offset 0x1c6:

 CU [     b] base: .text+000000000000000000 <main>
 [     0] range 0, 5
          .text+000000000000000000 <main>..
          .text+0x0000000000000004 <main+0x4>
           [ 0] lit0
           [ 1] stack_value
          range 5, a
          .text+0x0000000000000005 <main+0x5>..
          .text+0x0000000000000009 <main+0x9>
           [ 0] reg1
          range 16, 24
          .text+0x0000000000000016 <main+0x16>..
          .text+0x0000000000000023 <main+0x23>
           [ 0] reg1
 [    4a] range 0, 5
          .text+000000000000000000 <main>..
          .text+0x0000000000000004 <main+0x4>
           [ 0] lit0
           [ 1] stack_value
 [    6e] range 5, a
          .text+0x0000000000000005 <main+0x5>..
          .text+0x0000000000000009 <main+0x9>
           [ 0] lit0
           [ 1] stack_value
          range a, e
          .text+0x000000000000000a <main+0xa>..
          .text+0x000000000000000d <main+0xd>
           [ 0] const4u 65537
           [ 5] breg0 0
           [ 7] minus
           [ 8] stack_value



Sasha

From: Sasha Da Rocha Pinheiro <darochapinhe@wisc.edu>
Sent: Tuesday, June 2, 2020 1:12 PM
To: Mark Wielaard <mark@klomp.org>; elfutils-devel@sourceware.org <elfutils-devel@sourceware.org>
Subject: Re: location list 
 
Well, I have been trying to use the Dwarf_Attribute.
If you see the snippet below, locationAttribute is acquired by doing dwarf_attr(&e, DW_AT_location, &locationAttribute);
and &e is the DW_TAG_variable DIE.

        Dwarf_Op * exprs = NULL;
        size_t exprlen = 0;
        std::vector<LocDesc> locDescs;
        ptrdiff_t offset = 0;
        Dwarf_Addr basep, start, end;
        do {
            offset = dwarf_getlocations(&locationAttribute, offset, &basep,
                    &start, &end, &exprs, &exprlen);
            if(offset==-1) return false;
            if(offset==0) break;
            LocDesc ld;
            ld.ld_lopc = start;
            ld.ld_hipc = end;
            ld.dwarfOp = exprs;
            ld.opLen = exprlen;
            locDescs.push_back(ld);
        }while(offset > 0);

But what happens here is I always get the very first entry in .debug_loc. Where clearly for this variable, the location list (sec_offset) is at [    4a] of that section.
Maybe I am using the offset or the basep wrongly?


Sasha




From: Mark Wielaard <mark@klomp.org>
Sent: Tuesday, June 2, 2020 12:19 PM
To: Sasha Da Rocha Pinheiro <darochapinhe@wisc.edu>; elfutils-devel@sourceware.org <elfutils-devel@sourceware.org>
Subject: Re: location list 
 
Hi,

On Tue, 2020-06-02 at 14:18 +0000, Sasha Da Rocha Pinheiro wrote:
> I am trying to parse a location list given as an sec_offset. 
> How do I get this offset value that points to .debug_loc so I can
> call dwarf_getlocations()?
> Should I pass this offset as the second parameter of this call? 

Normally an offset isn't enough information to resolve an DIE attribute
reference. So if at all possible you should try to use an
Dwarf_Attribute you got from some DIE.

It isn't really supported, but you could try creating a "fake"
attribute that carries all information. e.g.

Dwarf_Attribute loc_attr;
loc_attr.code = DW_AT_location;
loc_attr.form = DW_FORM_data4; /* Assuming 32bit DWARF.  */
loc_attr.valp = &offset; /* Your offset should be a 32bit type.  */
loc_attr.cu = cu;

dwarf_getlocations (&loc_attr, offset, ...);

Note that the CU needs to be version 3 or lower for the above to work.
If the CU is > 3 then the only correct form to use is
DW_FORM_sec_offset, and your valp should point to a uleb128 encoded
offset value.

But in general I would not recommend this approach. It isn't really
supported. And some code might do sanity checks on the valp pointer and
decide it looks bogus and just error out. Also you have to have a valid
Dwarf_CU pointer around because you cannot create a valid fake CU
easily.

So try to keep a reference (or copy) around of the Dwarf_Attribute from
which you got this offset and use that for your dwarf_getlocations
call.

Cheers,

Mark


More information about the Elfutils-devel mailing list