This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

dwarf2 frame unwinder assumptions on SP


Hi all,

I am working on the connection of the dwarf2 frame unwinder
to our GDB port, and I have trouble with some assumptions
made by GDB about SP.

Currently, in my x-tdep.c I have:
  set_gdbarch_unwind_pc(gdbarch, x_unwind_pc);
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);

This improves the backtracing capability (especially in presence
of alloca()), but exhibits many regressions when displaying the
parameters of functions called. (eg gdb.base/funcargs)

I have isolated the reason of failure, but don't know how to
solve it cleanly.

In the debug_info section, the call6b() function has:
DW_AT_frame_base            DW_OP_bregx12+48
(register 12 is our SP)
and the 1st parameter of call6b() has:
DW_AT_location              DW_OP_fbreg -16

The frame_base described here is the value of SP upon
entry in call6b().

In the debug_frame section, in CIE, we have:
DW_CFA_def_cfa: r12 ofs 16

which means that our CFA is SP + 16 upon function entry.


Now, when 'backtrace' looks for the value of the 1st parameter,
it needs to recompute the value of SP.
The default for this is provided by
frame2-frame.c:dwarf2_frame_default_init_reg() to:
  ...
  else if (regnum == SP_REGNUM)
    reg->how = DWARF2_FRAME_REG_CFA;

which leads to my trouble.

The comes from an assumption about the GCC behaviour and
the Dwarf spec saying that "Typically, the CFA is defined
to be the value of the stack pointer at the call site in
the previous frame" which does not hold for our
target/ABI (the compiler is Open64).

I would like to express that SP is CFA-16, but I don't
see how to achieve that.

Indeed, in dwarf2-frame.c:dwarf2_frame_prev_register(),
no code would enable the beheviour I want. I thought of
using DWARF2_FRAME_REG_SAVED_EXP but it involves an extra
indirection.

The possibilities I can think of are as follows:
1 - add a case like DWARF2_FRAME_REG_CFA_OFFSET
    in dwarf2-frame.[ch] to do what I need

2 - copy a large part of the generic support from
    dwarf2-frame.c into x-tdep.c to have a customized
    x_frame_prev_register()

3 - have a specific dwarf2_sniffer / frame_prev_register
    that calls the generic code, except for SP (still
    not clear how to do that cleanly, as most of the functions
    I need to call are 'static')

4 - modify the compiler so that DW_AT_frame_base takes into
    account the missing 16 bytes and thus have frame_base == CFA
    but frame_base != SP. I fear this will lead to trouble
    further....

5 - modify the compiler / libdwarf so that it makes use of the
    Dwarf3 operators such as DW_CFA_offset_extended_sf which
    allow for signed offsets (which, basically is the reason
    for having CFA != SP: in our ABI, the caller reserves 16 bytes
    on the stack for callee usage)


I hope my description is clear enough so that someone can help me.

Thanks,

Christophe.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]