GCC 3.3 Prelease broken on s390

Ulrich Weigand weigand@immd1.informatik.uni-erlangen.de
Tue May 6 22:28:00 GMT 2003


Richard Henderson wrote:

> Eh?  There are assumptions *all over* that code that the
> CFA of one frame is the stack pointer of the previous.

Where?  Except for a gdb problem where it incorrectly
assumed that the DWARF-2 CFA and the DWARF-2 frame_base
must be the same (this has been fixed in the meantime),
we've never seen any problems ...

Our choice of CFA has remained unchanged since 2.95.x,
and there's a lot of existing binaries that have their
.eh_frame encoding accordingly, so I do not think this
is something we can change at this point.

> I can work with you to address this, but I'm going to need
> a few pointers to speed up the process.  E.g. a picture of
> the stack frame between one function and the next.

Assuming function f() calls g(), we have this layout:

   |                                                    | <- CFA of f ()
   |  register save area                                |
   |====================================================|
   |  locals of f ()                                    |
   |                                                    |
   |  parameter overflow area (holds parameters         |
   |  of g as called by f)                              |
   |                                                    | <- CFA of g ()
   |  register save area allocated by f ()              |
   |====================================================| <- SP of f ()
   |  locals of g ()                                    |
   |                                                    |
   |  register save area allocated by g ()              |
   ====================================================== <- SP of g ()
 
We are running with a biased stack in that every function
does not use the lowest 96/160 bytes of its stack frame,
those are reserved as register save area for use by called
routines.

When a function call from f() to g() happens, g() is
entered with SP still pointing to the bottom of the
reigster save area.  The first thing g's prolog does
is to save its registers (including the stack pointer)
into that area (which was allocated by f()).  It then
subtracts an offset from the stack pointer, thereby
allocating its stack frame plus the register save area
for use by functions called by itself.

The epilog simply restores registers from the save area,
including the stack pointer -- thereby cleaning up the
stack frame.

At typical FDE looks like this:

0000014c 0000000c 00000000 CIE
  Version:               1
  Augmentation:          ""
  Code alignment factor: 1
  Data alignment factor: -4
  Return address column: 14

  DW_CFA_def_cfa: r15 ofs 96

0000015c 00000020 00000014 FDE cie=0000014c pc=004009a0..004009fe
  DW_CFA_advance_loc: 4 to 004009a4
  DW_CFA_offset: r15 at cfa-36
  DW_CFA_offset: r14 at cfa-40
  DW_CFA_offset: r13 at cfa-44
  DW_CFA_offset: r12 at cfa-48
  DW_CFA_offset: r11 at cfa-52
  DW_CFA_offset: r10 at cfa-56
  DW_CFA_advance_loc: 22 to 004009ba
  DW_CFA_def_cfa_offset: 192
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

So when we enter the function, the CFA can be found at r15 + 96
(r15 is the stack pointer).  Once the prolog is complete, the
CFA is now addressable at r15 + 192 (because we bought another
96 bytes of stack; this would be an empty frame).

In the register save area at cfa-XX the various registers are
saved and need to be restored from there for stack unwinding.

The function return address is in r14 on function entry.
The unwinder would find it from the place where it is stored
in the register area (at cfa-40) as pointed out by the FDE.

All this has been working just fine ...

Bye,
Ulrich

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



More information about the Gcc mailing list