Given a program like this: int foo(int a, int b, int c) { return a+b+c; } int bar(int a, int b, int c) { return foo(a, b, c); } int main(int argc, char **argv) { return bar(1,2,3); } for foo and bar, gcc generates code that stores the arguments a, b, and c on the stack by using the argument pointer, but it does this indirectly, like so: foo .PROC .CALLINFO FRAME=80,NO_CALLS,SAVE_SP,ENTRY_GR=3 .ENTRY copy %r3,%r1 copy %r30,%r3 std,ma %r1,80(%r30) std %r3,-8(%r30) ldo -64(%r29),%r20 stw %r26,4(%r20) stw %r25,12(%r20) stw %r24,20(%r20) [...] gcc proceeds to emit debug info for a, b, and c relative to r20: $ opt/bin/readelf -wi dwarfbug [...] <2><7d>: Abbrev Number: 3 (DW_TAG_formal_parameter) DW_AT_name : a DW_AT_decl_file : 1 DW_AT_decl_line : 1 DW_AT_type : <a2> DW_AT_location : 2 byte block: 84 4 (DW_OP_breg20: 4) <2><89>: Abbrev Number: 3 (DW_TAG_formal_parameter) DW_AT_name : b DW_AT_decl_file : 1 DW_AT_decl_line : 1 DW_AT_type : <a2> DW_AT_location : 2 byte block: 84 c (DW_OP_breg20: 12) <2><95>: Abbrev Number: 3 (DW_TAG_formal_parameter) DW_AT_name : c DW_AT_decl_file : 1 DW_AT_decl_line : 1 DW_AT_type : <a2> DW_AT_location : 2 byte block: 84 14 (DW_OP_breg20: 20) The problem is that since r20 is not a call preserved register, when you are doing a stack unwind, you have no way to retrieve those variables in anything other than the topmost frame. I've seen it do this with r20 and r28, but I guess it can do it with any available register. On 32-bit hppa, the parameters are always described relative to the frame base (DW_OP_fbreg), which works fine. I'm testing this on hpux, but this looks like it affects all 64-bit hppa targets.
I forgot to mention that the above was compiled with gcc -g -o dwarfbug dwarfbug.c
Some discussion about this PR is here: http://gcc.gnu.org/ml/gcc-patches/2005-11/msg01563.html
I thought this was fixed for 4.1.0.
Subject: Re: [hppa64] Bad dwarf output using non-preserved base register > ------- Comment #3 from pinskia at gcc dot gnu dot org 2006-03-18 17:31 ------- > I thought this was fixed for 4.1.0. I don't think so. It was another dwarf2 report filed by Randolph involving the passing of structs that Jim Wilson fixed. Dave
Indeed, as Dave said this is a different and not yet fixed problem.
Is this still an issue?
On 1/11/2012 9:54 AM, rguenth at gcc dot gnu.org wrote: > Is this still an issue? > Yes.
Thus, confirmed.
The problem is there isn't a fixed relationship between the stack pointer register, %r30, and the argument pointer register, %r29. HP didn't provide a slot in the stack frame to save the argument pointer. It is call clobbered. The only option to fix this issue would be be to preserve it across calls. This would impact performance.
So it's a target issue, not a debug one. Of course we could avoid generating wrong-debug by generating none whenever the argument pointer is involved? Not sure whether I'd call hppa64-hpux important enough to worry.
On 2019-03-13 4:09 a.m., rguenth at gcc dot gnu.org wrote: > So it's a target issue, not a debug one. Of course we could avoid generating > wrong-debug by generating none whenever the argument pointer is involved? It appears to me that this is likely a generic target problem: rtx default_internal_arg_pointer (void) { /* If the reg that the virtual arg pointer will be translated into is not a fixed reg or is the stack pointer, make a copy of the virtual arg pointer, and address parms via the copy. The frame pointer is considered fixed even though it is not marked as such. */ if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM || ! (fixed_regs[ARG_POINTER_REGNUM] || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))) return copy_to_reg (virtual_incoming_args_rtx); else return virtual_incoming_args_rtx; } static rtx pa_internal_arg_pointer (void) { /* The argument pointer and the hard frame pointer are the same in the 32-bit runtime, so we don't need a copy. */ if (TARGET_64BIT) return copy_to_reg (virtual_incoming_args_rtx); else return virtual_incoming_args_rtx; } Both routines use copy_to_reg.