[PATCH] PowerPC ldso bug (Was: Re: [uClibc] PowerPC dynamic linking)

Henrik Grindal Bakken hgb at ifi.uio.no
Wed Dec 3 08:58:45 UTC 2003


Robin Gilks <robin.gilks at tait.co.nz> writes:

> Greetings
>
> I'm still trying to find out if mpc8xx 

I don't have MPC8xx, but it's at least ppc.

> dynamic linking works (but avoiding the download of CVS head due to
> the time it will take to rebuild my toolchain/target system using a
> new buildroot structure). It appeared to be OK in 0.9.20 but seems
> to be broken since :-((

I have gotten dynamic linking to work on ppc, but not without some
patch-work.  I still have some problems getting all my applications to
link, but at least I'm making progress.  

There seems to be a (very) subtle bug in ldso.  In ld_sysdeps.h for
powerpc, START() is defined to be:

#define START() \
   __asm__ volatile ( \
               "addi 1,%1,0\n\t" \
               "mtlr %0\n\t" \
               "blrl\n\t"   \
               : : "r" (_dl_elf_main), "r" (args))

However, addi is somewhat magical on powerpc:
addi RT, RA, immediate

If RA != r0, RT is set to the sum of the contents of RA + the
immediate.  If, however, RA is r0, it is instead taken as the value 0.

When I compiled ldso, gcc assigned r0 to %1, and then r1 (stack
pointer) was set to 0 before control was transferred to the program
(and subsequently it segfaulted).

My fix, which at least works for me, is to add r0 to the clobber list
for that asm inline.

Patch below:


--- uClibc/ldso/ldso/powerpc/ld_sysdep.h        2002-05-28 23:33:38.000000000 +0200
+++ /opt/hgb/src/toolchain/gcc-3.3.1/sources/dl/uClibc-0.9.22/ldso/ldso/powerpc/ld_sysdep.h 2003-12-02 13:48:26.000000000 +0100
@@ -97,14 +97,21 @@
  * Transfer control to the user's application, once the dynamic loader
  * is done.  This routine has to exit the current function, then 
  * call the _dl_elf_main function.
  */
+/* hgb at ifi.uio.no:
+ * Adding a clobber list consisting of r0 for %1.  addi on PowerPC
+ * takes a register as the second argument, but if the register is
+ * r0, the value 0 is used instead.  If r0 is used here, the stack
+ * pointer (r1) will be zeroed, and the dynamically linked
+ * application will seg.fault immediatly when receiving control.
+ */
 #define START()                \
        __asm__ volatile ( \
                    "addi 1,%1,0\n\t" \
                    "mtlr %0\n\t" \
                    "blrl\n\t"  \
-                   : : "r" (_dl_elf_main), "r" (args))
+                   : : "r" (_dl_elf_main), "r" (args) \
+                   : "r0")
 
 
 
 /* Here we define the magic numbers that this dynamic loader should
 accept */




-- 
Henrik Grindal Bakken <hgb at ifi.uio.no>
TANDBERG Telecom
PGP ID: 8D436E52
Fingerprint: 131D 9590 F0CF 47EF 7963  02AF 9236 D25A 8D43 6E52



More information about the uClibc mailing list