Subject: Re: PowerPC assembl question
To: None <port-powerpc@netbsd.org, p99dreyf@criens.u-psud.fr>
From: Wolfgang Solfrank <ws@tools.de>
List: port-powerpc
Date: 01/17/2001 16:55:26
Hi,

> Well, here is my piece of code:
> 
> .globl   _C_LABEL(linux_execcode_start)
> .globl   _C_LABEL(linux_execcode_end)
> .globl   _C_LABEL(linux_execcode_target)
> _C_LABEL(linux_execcode_start):
>    addi     1,1,0x10
>    lis      11, _C_LABEL(linux_execcode_target)@ha
>    lwz      12, _C_LABEL(linux_execcode_target)@l(11)
>    mtctr    12
>    bctr
> _C_LABEL(linux_execcode_target):
> .long    0      /* Setup at run time by kernel */
> _C_LABEL(linux_execcode_end):
> 
> 
> When I try to run it, I get a SIGSEGV. Disassembling in gdb produces
> this:
> (gdb) x/10xi 0x7fffe930
> 0x7fffe930:     addi    r1,r1,16
> 0x7fffe934:     lis     r11,46
> 0x7fffe938:     lwz     r12,-1664(r11)
> 0x7fffe93c:     mtctr   r12
> 0x7fffe940:     bctr
> 0x7fffe944:     .long 0x1800514

Hmm, I'm not sure what you are trying to do here.  However, from
the type of failure, I assume that this code fragment gets copied to
its final location from somewhere else (either by the kernel, or ld.so
or ...).  How did you find the 0x7fffe930 anyway?

Your problem is that the code contains an absolute reference to the
linux_execcode_target label.  Since this reference isn't relocated,
it points to the address where the code was linked at, not its final
destination.  That's why it fails.

> It's the lwz instruction that causes the SIGSEGV. Obviously, I did not
> get what I expected at link time. I think I should have had something
> like this:
>         addi    r1,r1,16
>         lis     r11,16(pc)
>         lwz     r12,0(r11)
>         mtctr   r12
>         bctr
>         .long   0x1800514

The equivalent of this in PowerPC assembly is something like this
(note untested):

_C_LABEL(linux_execcode_start):
	addi	1,1,0x10
	mflr	12
	bl	1f
1:
	mflr	11
	mtlr	12
	lwz	12, _C_LABEL(linux_execcode_target)-1b(11)
	mtctr	12
	bctr
_C_LABEL(linux_execcode_target):
	.long	0	/* Setup at run time by kernel */
_C_LABEL(linux_execcode_end):

Hope it helps.

Ciao,
Wolfgang
-- 
ws@TooLs.DE     Wolfgang Solfrank, TooLs GmbH 	+49-228-985800