Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Oct 2017 15:46:47 -0700
From:      Mark Millard <markmi@dsl-only.net>
To:        Justin Hibbits <chmeeedalf@gmail.com>
Cc:        FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, freebsd-hackers <freebsd-hackers@freebsd.org>
Subject:   Re: Question for powerpc64 lib32 (powerpc) support: what ABI is the powerpc code supposed to be using?
Message-ID:  <68CE11EB-1C94-4F3F-B593-162E0B9E0537@dsl-only.net>
In-Reply-To: <67C51163-D178-4CAC-AA3C-1178EDD22E01@dsl-only.net>
References:  <618F5419-0BB7-496E-B1B8-DA8BE6D54A58@dsl-only.net> <CAHSQbTD8RGw6FBA0Uz2vrgOndJcvuLQZjTe_rsOSmqf9UMca=g@mail.gmail.com> <299784B1-55F3-4C39-B07B-CE6C9E9BB2A8@dsl-only.net> <67C51163-D178-4CAC-AA3C-1178EDD22E01@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
[I add notes about what I see in the SysVR4
powerpc ABI document about r30 vs.
_GLOBAL_OFFSET_TABLE_ use --and some notes about
more modern Power Architecture=C2=AE 32-bit Application
Binary Interface Supplement 1.0 material that does,
by contrast, specify a type of context where r30
must be used for the purpose. Bugzilla 206123 now
has this material as well.]

On 2017-Oct-29, at 6:50 AM, Mark Millard <markmi at dsl-only.net> wrote:

> [Message history removed as this does not flow well with
> the prior material.]
>=20
> I've figured out the mismatch and, so, why/how lib32
> fails for devel/powerpc64-gcc based builds: the
> .init code generation for devel/powerpc64-gcc is tied
> to the glibc crti.S for powerpc and that does not
> match what FreeBSD has for the interface between
> the two parts.
>=20
> As of 6 years ago or so glibc has code like (I'm
> only dealing with the init side of things as an
> example):
>=20
> .section .init,"ax",@progbits
> stwu r1, -16(r1)
> . . .
> bcl 29,31,.LMAGIC_LABEL
> .LMAGIC_LABEL:
> mflr r30
> addis r30, r30, _GLOBAL_OFFSET_TABLE_-.LMAGIC_LABEL@ha
> addi  r30, r30, _GLOBAL_OFFSET_TABLE_-.LMAGIC_LABEL@l
> . . . (some pre-init function code) . . .
>=20
> that comes before code that is from frame_dummy
> and __do_global_ctors_aux (that are from
> =
/wrkdirs/usr/ports/devel/powerpc64-gcc/work/gcc-6.3.0/libgcc/crtstuff.c =
).
>=20
> The code generated for frame_dummy and
> __do_global_ctors_aux expects r30 to already
> be set up for _GLOBAL_OFFSET_TABLE_ related
> use by the kind of code that I showed above.
>=20
>=20
> Instead FreeBSD has for powerpc just:
> (things are configured for devel/powerpc64-gcc
> to use it)
>=20
> #include <machine/asm.h>
> __FBSDID("$FreeBSD: head/lib/csu/powerpc/crti.S 217399 2011-01-14 =
11:34:58Z kib $");
>=20
>        .section .init,"ax",@progbits
>        .align  2
>        .globl  _init
>        .type   _init,@function
> _init:
>        stwu 1,-16(1)
>        mflr 0
>        stw 31,12(1)
>        stw 0,20(1)
>        mr 31,1
>=20
> The overall result ends up being (from
> an example .so):
>=20
> 0000214c <_init> stwu    r1,-16(r1)
> 00002150 <_init+0x4> mflr    r0
> 00002154 <_init+0x8> stw     r31,12(r1)
> 00002158 <_init+0xc> stw     r0,20(r1)
> 0000215c <_init+0x10> mr      r31,r1
> (The above is the FreeBSD crti.S code.)
> (Note the lack of initialization of r30
> to the _GLOBAL_OFFSET_TABLE_ related value.)
>=20
> (The below is the crtstuff.c frame_dummy code
> inlined in a way that the function prolog code
> is not present here.)
> (Note the dependence on r30 having already been
> initialized.)
> 00002160 <_init+0x14> lwz     r3,-712(r30)
> 00002164 <_init+0x18> lwz     r9,0(r3)
> 00002168 <_init+0x1c> cmpwi   cr7,r9,0
> 0000216c <_init+0x20> beq-    cr7,00002184 <_init+0x38>
> 00002170 <_init+0x24> lwz     r9,-16(r30)
> 00002174 <_init+0x28> cmpwi   cr7,r9,0
> 00002178 <_init+0x2c> beq-    cr7,00002184 <_init+0x38>
> 0000217c <_init+0x30> mtctr   r9
> 00002180 <_init+0x34> bctrl
>=20
> (The below is the crtstuff.c __do_global_ctors_aux
> loop code but inlined. . .)
> 00002184 <_init+0x38> lwz     r29,-36(r30)
> 00002188 <_init+0x3c> lwzu    r9,-4(r29)
> 0000218c <_init+0x40> cmpwi   cr7,r9,-1
> 00002190 <_init+0x44> beq-    cr7,000021a8 <_init+0x5c>
> 00002194 <_init+0x48> mtctr   r9
> 00002198 <_init+0x4c> bctrl
> 0000219c <_init+0x50> lwzu    r9,-4(r29)
> 000021a0 <_init+0x54> cmpwi   cr7,r9,-1
> 000021a4 <_init+0x58> bne+    cr7,00002194 <_init+0x48>
>=20
> (The rest of the .init code follows.)
> 000021a8 <_init+0x5c> lwz     r11,0(r1)
> 000021ac <_init+0x60> lwz     r0,4(r11)
> 000021b0 <_init+0x64> mtlr    r0
> 000021b4 <_init+0x68> lwz     r31,-4(r11)
> 000021b8 <_init+0x6c> mr      r1,r11
> 000021bc <_init+0x70> blr
>=20
> The way the compiler's source code is structured
> and works it looks to me like the crti.S used needs
> to have the initialization code for r30.

I've looked an a copy of the 1995 Sun Microsystems
PPC SYSVR4 ABI document and its table 3-3 about
processor register usage is not explicit about
a specific register being used relative to
_GLOBAL_OFFSET_TABLE_ handling.

There are examples that say things like:

Assumes GOT pointer in r31

but as far as I can tell no place requires that.
In fact there is wording like:

Combining the offset with the global offset table address in a general =
register (for example, r31 loaded in the sample prologue in Figure 3-33) =
gives the absolute address of the table entry holding the desired =
address.

which explicitly indicates "in a general register".

It appears that crti.S type code for share
libraries requires a local convention for
the choice of register that the compiler and
library must agree on.

So r30 looks to be a valid choice but possibly
compiler specific for a FreeBSD context.

But there may be a reason to stick with r30. . .

Looking in Power-Arch-32-bit-ABI-supp-1.0-Linux.pdf
reports that:

Under the Secure-PLT ABI, when using the Position-Independent Code (PIC) =
addressing model, register r30 is used (by convention between compiler & =
link editor) in nonleaf functions to hold the Global Offset Table (GOT) =
pointer.

. . .

Using r30 to hold the address of the _GLOBAL_OFFSET_TABLE_ symbol is the =
current convention used
by the compiler and link-editor and is only required for nonleaf =
routines which use the PIC addressing model. Leaf routines or code not =
using the PIC addressing model may use any available unreserved =
general-purpose register to hold the address of the =
_GLOBAL_OFFSET_TABLE_ symbol.

. . .

The PIC call stub sequence requires that the compiler ensure that the =
register used to hold the _GLOBAL_OFFSET_TABLE_ pointer is set before =
any calls are made from the PLT. The current convention between the =
compiler and link editor is that r30 be used for this purpose. This is a =
change from the BSS-PLT ABI which only required GOT addressing to access =
static storage.

. . .

For non-PIC code, r30 will not hold the GOT pointer; so the stubs must =
be different, as shown in the following implementation.

. . .

Note: This ABI does not require a fixed GOT register, or even one =
register used throughout a binary. Non-PIC code does not set the =
_GLOBAL_OFFSET_TABLE_ pointer and does not need to reserve a register =
for that purpose. Code under the PIC addressing model that accesses =
static storage or calls nonlocal functions will need a register to hold =
the _GLOBAL_OFFSET_TABLE_ pointer. However, leaf functions or functions =
that only call other functions which are static (@local) may use any =
general-purpose register within the constraints for the existing ABI.

[End quotes.]

By contrast Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
does not say much about r30 use, including not specifying
the Secure-PLT ABI material.

The referenced documents are examples of:

Power Architecture=C2=AE 32-bit Application Binary Interface Supplement =
1.0

documents published in, for example, 2011 (Power.org
copyright for that date but various other copyrights
for various earlier dates).


=3D=3D=3D
Mark Millard
markmi at dsl-only.net





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?68CE11EB-1C94-4F3F-B593-162E0B9E0537>