Hi Mark,

yes, I did use dwarf_frame_register(), I believe I mentioned that :).
In the case I brought up you're saying it was an elfutils' libdw decision to 
provide negative number as DW_OP_plus_uconst (unsigned constant)? So there 
would be no harm to cast it to a signed int??

Do you know if the rules to find the registers will always have only another 
one register associated to it? Because libdwarf function 
dwarf_get_fde_info_for_reg3() returns a register_num, which is described as:
"Argument register_num should point to a location which will hold the register 
number associated with the register rule."

elfutils only gives us a location description in an array of Dwarf_Op. Does it 
provide methods to "execute" it so we can get the result of the expressions? Or 
it delegates it to the consumer?

Regards
Sasha




From: Mark Wielaard <m...@klomp.org>
Sent: Saturday, April 27, 2019 12:57 PM
To: Sasha Da Rocha Pinheiro
Cc: elfutils-devel@sourceware.org
Subject: Re: Dwarf_Op
 
On Fri, Apr 26, 2019 at 04:48:49PM +0000, Sasha Da Rocha Pinheiro wrote:

> The output from dwarfdump:
>
> <    5><0x00400918:0x00400974><main><cie offset 0x000000b4::cie index     
> 0><fde offset 0x000000b0 length: 0x00000024>
>        <eh aug data len 0x0>
>         0x00400918: <off cfa=00(r31) >
>         0x0040091c: <off cfa=32(r31) > <off r29=-32(cfa) > <off r30=-24(cfa) >
>         0x00400920: <off cfa=32(r29) > <off r29=-32(cfa) > <off r30=-24(cfa) >
>         0x00400970: <off cfa=00(r31) >
>
> I'm getting the rules for r30 at PC 0x0040091c.
> The value you see -24 from cfa is passed delivered by libdw as:
>
> (gdb) p/x locations[i]
> $19 = {atom = 0x23, number = 0xffffffffffffffe8, number2 = 0x0, offset = 0x0}
>
> The atom here is DW_OP_plus_uconst.
> Previously I have said it was 0xffffffe8, because the printf with specifier 
> %x printed that way. But gdb seems to print its full 8 bytes.
> I used dwarf_frame_register.
>
> Even though, the member number is of unsigned int type with signed encoded 
> values. Am I correct?

Yes, a Dwarf_Op struct holds two number elements which are (unsigned 64bit)
Dwarf_Words:

typedef struct
{
  uint8_t atom;                 /* Operation */
  Dwarf_Word number;            /* Operand */
  Dwarf_Word number2;           /* Possible second operand */
  Dwarf_Word offset;            /* Offset in location expression */
} Dwarf_Op;

I assume you are using dwarf_frame_register () to turn the CFI for a
particular register into a location expression (array of Dwarf_Ops).
Which in this case would indeed produce DW_OP_call_frame_cfa,
DW_OP_plus_uconst (with the constant -24 in number).

Unfortunately there is no better/precise way to turn the CFI register
rule into a Dwarf Expression Location.

But note that if you use the Dwarf_Ops to calculate an Dwarf_Addr,
then the 64bit unsigned arithmetic will work out (because the plus of
the big unsigned constant will wrap around and turn into a small minus
constant).

Cheers,

Mark

Reply via email to