[PATCH/RFA] Allow register other than SP for DWARF2 CFA

Jason R Thorpe thorpej@wasabisystems.com
Mon Jun 17 23:17:00 GMT 2002


On Mon, Jun 17, 2002 at 04:42:31PM -0700, Richard Henderson wrote:

 > Naturally, since this is the VAX, there's not much to help me out in
 > the port itself.  I vaguely remember that just about everything happens
 > in hardware during the call insn itself.

Well, for some value of "hardware" :-)

 > Can you draw me some pictures of what the stack looks like
 > 
 >   (1) immediately before a call
 >   (2) at the function entry label
 >   (3) after any function prologue
 >   (4) after the function return
 > 
 > In particular, where are SP, FP, AP, and their saved slots.
 > 
 > We have to put enough information into the dwarf2 into to be able
 > to make the 3->4 transition.

Ok, here's the story.  Let's consider doing:

void
main(void)
{
	printf("%s\n", "hello world");
}

the compiler (more or less) emits:

.Larg1:
	.asciz	"%s\n"
.Larg2:
	.asciz	"hello world"
.
.
.
main:
	.mask	...	# saveregmask
	pushab	.Larg2	# first insn of main()
	pushab	.Larg1

Thus, the stack at (1) looks like:

	address of .Larg2
SP->	address of .Larg1

...then the call itself:

	calls	$2, printf

This is where the fun begins.  The microcode now does:

	- push arg count as a longword
	- for each reg in the saveregmask, push reg (counting
	  downward, e.g. r11, then r10, then r5, etc. so the
	  lowest register saved appears at the lowest address
	  on the stack)
	- push PC
	- push FP
	- push AP
	- push saveregmask + psl + other stuff as a longword
	- push the value 0 as a longword

...so that now, at (2), the stack looks like:

	address of .Larg2
	address of .Larg1
AP->	2
	caller's saved regs
	saved PC
	saved FP
	saved AP
	caller's saveregmask + ...
FP->	0

...and SP == FP.

Then, the function prologue allocates space on the stack for the callee's
locals, so we have this at (3):

	address of .Larg2
	address of .Larg1
AP->	2
	caller's saved regs  
	saved PC
	saved FP
	saved AP
	caller's saveregmask + ...
FP->	0
	.
	.
	some space
	.
SP->	.

NOTE: All locals are accessed relative to the frame pointer!  I.e. like
so:

	movl	$0, -4(fp)

I.e. the stack pointer just allocates the space and is used as a starting
point for the next call in the chain.

So, now, when you return with the "ret" insn, the first thing that
the microcode does it set SP = FP (thus popping all the locals).  Then
the microcode increments SP one longword at a time restoring the various
registers it saved during the "calls".  When it reaches the argument
count, the microcode automatically pops the count and arguments, as well
(by doing: SP += 4 + argc * 4).

So, this means that at point (4), the stack is:

SP->	top of stack

The "callg" insn complicates this a little.  Rather than assuming the
args are pushed and then pushing the arg count, "callg" takes the address
of a pre-built argument list.  This is used if the next call in the chain
takes the same args, and is also used in the NetBSD dynamic linker to call
the real function after a PLT fixup (meaning AP could point to the arg list
of a previous call frame), and was also used by VAX Fortran, which put
pre-built argument lists into the executable image (meaning the AP might not
point to a location on the stack at all).  If "callg" is used, then the
"ret" insn DOES NOT pop the argument list.

The "calls or callg" indication is part of the "other stuff" pushed along
with the caller's saveregmask.

So, the two major points to take out of this are:

	* The SP is not ever actually saved anywhere; it is always
	  recomputed from the FP.

	* Once you execute "ret", the SP is restored to as it was before
	  the caller pushed any arguments.

...and a minor point would be that ns32k is going to be similar.

Hmm, so, the info to make the (3)->(4) transition during an unwind is
actually on the stack relative to the FP (the "calls or callg" indication
along with the caller's saved registers mask, and the argument count), and
that stuff is going to have to be groveled from the stack at run-time.

Or something.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>



More information about the Gcc-patches mailing list