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]

Re: continuing egcs-1.1 problems


>>>>> In <9811101610.AA27716@marc.watson.ibm.com> 
>>>>>	David Edelsohn <dje@watson.ibm.com> wrote:

David> 	I am certain that removing the alignment part of the patch and
David> only reversing the trampoline test ordering will solve the symptom.  I
David> thought that someone already did that.  The question is whether the
David> trampoline test ordering truly is the source of the problem.
David> 
David> 	I thought that we previously received a confirmation a couple of
David> months ago that the alignment part of the patch violated the SVR4 PPC ABI
David> and was incorrect.
David> 
David> David
David> 

David,

I was waiting to see if Gary might respond further, but he's probably
still away from home and out of touch.

I'll take a stab at this, with the caveat that I don't really understand
the ins and outs of the code.

Please refer below to the unpatched trampoline code.

FIRST PATCH (trampoline test ordering)
======================================

The actual size of the trampoline is calculated and stored into
the symbol __trampoline_size by

    __trampoline_size = .-__trampoline_initial

Gauging from the beginning comments to __trampoline_setup

    /* R3 = stack address to store trampoline */
    /* R4 = length of trampoline area */
    /* R5 = function address */
    /* R6 = static chain */

    FUNC_START(__trampoline_setup)

R4 is the area that we have available to store the trampoline.  Then
the unpatched comparison and branch:

            li	r8,__trampoline_size	/* verify that the trampoline is big enough */
            cmpw	cr1,r8,r4
            srwi	r4,r4,2			/* # words to move */
            addi	r9,r3,-4		/* adjust pointer for lwzu */
            mtctr	r4
            blt	cr1,.Labort

will branch to the abort code if

    r8 < r4
	=>  abort if the actual trampoline size is less than the
	    the available trampoline area

That seems backwards, hence the patch

            cmpw	cr1,r4,r8

seems correct:

    r4 < r8
	=> abort if the available trampoline area is smaller than
	   the actual trampoline size

This, of course, assumes that the comments are correct.  But this usage
does make sense to me, as the caller is responsible for allocating the
trampoline area.

SECOND PATCH (trampoline size tweaking)
=======================================

I don't have an opinion on this, as I don't know the SVR4 ABI for PPC.
(Is it online somewhere?)

As it turns out, I never applied to second patch to my egcs 1.1b
build-- only the first one.  That seemed to work fine on some small
test programs that invoked the glibc functions that used nested
functions, but I haven't tried it on anything substantial.

--Elgin

-----------------------------

    /* Set up trampolines */

            .file	"tramp.asm"
            .section ".text"
            #include "ppc-asm.h"

            .globl	__trampoline_initial
            .type	__trampoline_initial,@object
            .align	2
    __trampoline_initial:
            mflr	r0
            bl	1f
    .Lfunc = .-__trampoline_initial
            .long	0			/* will be replaced with function address */
    .Lchain = .-__trampoline_initial
            .long	0			/* will be replaced with static chain */
    1:	mflr	r11
            mtlr	r0
            lwz	r0,0(r11)		/* function address */
            lwz	r11,4(r11)		/* static chain */
            mtctr	r0
            bctr

    __trampoline_size = .-__trampoline_initial
            .size	__trampoline_initial,__trampoline_size

            .section ".got2","aw"
    .LCTOC1 = .+32768
    .Ltramp = .-.LCTOC1
            .long __trampoline_initial-4

            .section ".text"
    .LCL0:
            .long .LCTOC1-.LCF0

    /* R3 = stack address to store trampoline */
    /* R4 = length of trampoline area */
    /* R5 = function address */
    /* R6 = static chain */

    FUNC_START(__trampoline_setup)
            mflr	r0			/* save return address */
            bl	.LCF0			/* load up __trampoline_initial into r7 */
    .LCF0:
            mflr	r11
            lwz	r12,(.LCL0-.LCF0)(r11)
            add	r11,r12,r11
            lwz	r7,.Ltramp(r11)		/* trampoline address -4 */

            li	r8,__trampoline_size	/* verify that the trampoline is big enough */
            cmpw	cr1,r8,r4
            srwi	r4,r4,2			/* # words to move */
            addi	r9,r3,-4		/* adjust pointer for lwzu */
            mtctr	r4
            blt	cr1,.Labort

            mtlr	r0

            /* Copy the instructions to the stack */
    .Lmove:
            lwzu	r10,4(r7)
            stwu	r10,4(r9)
            bdnz	.Lmove

            /* Store correct function and static chain */
            stw	r5,.Lfunc(r3)
            stw	r6,.Lchain(r3)

            /* Now flush both caches */
            mtctr	r4
    .Lcache:
            icbi	0,r3
            dcbf	0,r3
            addi	r3,r3,4
            bdnz	.Lcache

            /* Finally synchronize things & return */
            sync
            isync
            blr

    .Labort:
            bl	abort
    FUNC_END(__trampoline_setup)
    /* END CYGNUS LOCAL -- waiting for FSF sources to be restored/meissner */


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