This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC 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]

Re: Var-tracking generates broken DW_AT_frame_base on s390


Josef Zlomek wrote:

> IMHO this is correct because all references to stack variables in
> location lists should have "frame-size" subtracted from the offset.
> The value "(%r15 + frame-size)" is the stack pointer at the function
> entry. We need some fixed point so that we could handle changes of
> stack pointer when something is pushed to stack when using
> -fomit-frame-pointer and the stack pointer at the function entry
> is a good fixed point.

On s390 there is no 'push'; in functions without frame pointer, the 
stack pointer never changes (except while in prolog/epilog).  We also
have -fomit-frame-pointer on by default.

> Anyway, I'll look into it to see if there is any problem.

There most certainly is a problem.  For example, the following trivial
program:

void g (char *);
void f (void)
{
   char buf[101];

   g (buf);
}

compiles to (using -O -g)

f:
.LFB2:
        .file 1 "test.c"
        .loc 1 4 0
.LVL0:
        stm     %r13,%r15,52(%r15)
.LCFI0:
        basr    %r13,0
.L2:
        ahi     %r15,-200
.LCFI1:
.LVL1:
        .loc 1 7 0
        la      %r2,96(%r15)    # <- address of buf = %r15 + 96
        l       %r1,.L3-.L2(%r13)
        basr    %r14,%r1
        .loc 1 8 0
        l       %r4,256(%r15)
        lm      %r13,%r15,252(%r15)
        br      %r4
        .align  4
.L3:
        .long   g
        .align  2
.LFE2:
        .size   f, .-f


Note that variable buf is located at %r15 + 96 (using the %r15
value *inside* the function).

The debug info for variable buf is:

        .uleb128 0x3    # (DIE (0x3c) DW_TAG_variable)
        .ascii "buf\0"  # DW_AT_name
        .byte   0x1     # DW_AT_decl_file
        .byte   0x5     # DW_AT_decl_line
        .4byte  0x4c    # DW_AT_type
        .byte   0x3     # DW_AT_location
        .byte   0x91    # DW_OP_fbreg
        .sleb128 96

Note the DW_OP_fbreg 96 output.  This means that this piece of
code assumes the frame base is the value of %r15 inside the
function.

However, the DW_AT_frame_base is as follows:

        .uleb128 0x2    # (DIE (0x25) DW_TAG_subprogram)
        .4byte  0x4c    # DW_AT_sibling
        .byte   0x1     # DW_AT_external
        .ascii "f\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file
        .byte   0x4     # DW_AT_decl_line
        .byte   0x1     # DW_AT_prototyped
        .4byte  .LFB2   # DW_AT_low_pc
        .4byte  .LFE2   # DW_AT_high_pc
        .4byte  .LLST0  # DW_AT_frame_base

with this location list:

.LLST0:
        .4byte  .LVL0-.Ltext0   # Location list begin address (*.LLST0)
        .4byte  .LVL1-.Ltext0   # Location list end address (*.LLST0)
        .2byte  0x2     # Location expression size
        .byte   0x7f    # DW_OP_breg15
        .sleb128 0
        .4byte  .LVL1-.Ltext0   # Location list begin address (*.LLST0)
        .4byte  .LFE2-.Ltext0   # Location list end address (*.LLST0)
        .2byte  0x3     # Location expression size
        .byte   0x7f    # DW_OP_breg15
        .sleb128 200
        .4byte  0x0     # Location list terminator begin (*.LLST0)
        .4byte  0x0     # Location list terminator end (*.LLST0)

So inside the function (from .LVL1 on), the frame base is assumed to 
be at %r15 + 200.

I have no decided opinion about *which* of the two definitions
is wrong (the DW_TAG_variable location or the DW_AT_frame_base
location list), but one of them must be wrong.

> BTW: you need to use GDB 6.1 to debug programs with location lists.

Of course.  (But gdb < 6.1 doesn't work too well on s390 anyway ...)

Thanks for looking into this!

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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