Bug 24943 - [hppa64] Bad dwarf output using non-preserved base register
Summary: [hppa64] Bad dwarf output using non-preserved base register
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-debug
Depends on:
Blocks:
 
Reported: 2005-11-19 17:08 UTC by Randolph Chung
Modified: 2019-03-13 19:59 UTC (History)
7 users (show)

See Also:
Host: hppa64-hp-hpux11.11
Target: hppa64-hp-hpux11.11
Build: hppa64-hp-hpux11.11
Known to work:
Known to fail: 3.3.4, 4.0.1, 4.1.0
Last reconfirmed: 2012-01-11 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Randolph Chung 2005-11-19 17:08:46 UTC
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.
Comment 1 Randolph Chung 2005-11-20 03:38:32 UTC
I forgot to mention that the above was compiled with gcc -g -o dwarfbug dwarfbug.c
Comment 2 Randolph Chung 2005-12-08 05:26:46 UTC
Some discussion about this PR is here:
http://gcc.gnu.org/ml/gcc-patches/2005-11/msg01563.html
Comment 3 Andrew Pinski 2006-03-18 17:31:22 UTC
I thought this was fixed for 4.1.0.
Comment 4 dave 2006-03-18 17:57:43 UTC
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
Comment 5 Randolph Chung 2006-03-20 02:34:45 UTC
Indeed, as Dave said this is a different and not yet fixed problem.
Comment 6 Richard Biener 2012-01-11 14:54:03 UTC
Is this still an issue?
Comment 7 dave.anglin 2012-01-11 16:29:48 UTC
On 1/11/2012 9:54 AM, rguenth at gcc dot gnu.org wrote:
> Is this still an issue?
>
Yes.
Comment 8 Richard Biener 2012-01-12 09:17:52 UTC
Thus, confirmed.
Comment 9 dave.anglin 2019-03-13 00:17:07 UTC
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.
Comment 10 Richard Biener 2019-03-13 08:09:35 UTC
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.
Comment 11 dave.anglin 2019-03-13 19:59:24 UTC
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.