This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Var-tracking generates broken DW_AT_frame_base on s390
- From: Ulrich Weigand <weigand at i1 dot informatik dot uni-erlangen dot de>
- To: zlomj9am at artax dot karlin dot mff dot cuni dot cz (Josef Zlomek)
- Cc: weigand at i1 dot informatik dot uni-erlangen dot de (Ulrich Weigand), gcc at gcc dot gnu dot org
- Date: Mon, 21 Jun 2004 17:02:13 +0200 (CEST)
- Subject: 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