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