This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

new ppc32 GOT/PLT support


Here's the new ppc32 non-exec PLT/GOT support, which applies on top of
the previous four cleanup patches.  One problem remains: ppc32 calls
_mcount before the function prologue, so it's not possible to set up
registers to call _mcount via the plt in pic code.  So for now, if you
profile pic code using a dynamic _mcount, the call sequence used will
force the old exec GOT/PLT.  I'm thinking the best thing is to make
_mcount available in libc_nonshared, and only keep _mcount in libc.so
to satisfy explicit versions, but I'm open to suggestions.

2005-05-17  Alan Modra  <amodra@bigpond.net.au>

	* config.h.in (HAVE_ASM_PPC_REL16): Add.
	* elf/elf.h (DT_PPC_GLINK, DT_PPC_NUM): Define.
	* elf/tls-macros.h (PowerPC32): Include config.h.  Add variants of
	TLS_IE, TLS_LD and TLS_GD for new PLT/GOT layout.
	* sysdeps/powerpc/powerpc32/configure.in: New file,
	* sysdeps/powerpc/powerpc32/configure: Generate.
	* sysdeps/powerpc/powerpc32/Makefile (POC-ccflag): Define as -fpic.
	* sysdeps/powerpc/powerpc32/dl-dtprocnum.h: New file.
	* sysdeps/powerpc/powerpc32/dl-machine.h (DT_PPC): Define.
	(ppc_got): New inline function.
	(elf_machine_dynamic): Use ppc_got.  Add attribute const.
	(elf_machine_load_address): Add attribute const.  Don't use int vars.
	Use bcl rather than bl to save trashing branch target stack.  Use
	elf_machine_dynamic rather than duplicating code here.
	(elf_machine_runtime_setup): New inline function replacing define.
	Handle new PLT.
	(elf_machine_fixup_plt): Handle new PLT.
	(elf_machine_rela): Likewise.
	* sysdeps/powerpc/powerpc32/elf/start.S (start_addressesp): Don't
	define when HAVE_ASM_PPC_REL16.
	(_start): Add HAVE_ASM_PPC_REL16 code.
	* sysdeps/powerpc/powerpc32/sysdep.h: Include config.h.
	(CALL_MCOUNT): Avoid bl into the GOT when HAVE_ASM_PPC_REL16.
	* sysdeps/powerpc/powerpc32/dl-start.S (_dl_start_user): Likewise.
	* sysdeps/powerpc/powerpc32/memset.S (memset): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S (__longjmp): Ditto.
	* sysdeps/powerpc/powerpc32/fpu/s_ceil.S (__ceil): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_ceilf.S (__ceilf): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_floor.S (__floor): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_floorf.S (__floorf): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_lround.S (__lround): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_rint.S (__rint): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_rintf.S (__rintf): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_round.S (__round): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_roundf.S (__roundf): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_trunc.S (__trunc): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/s_truncf.S (__truncf): Likewise.
	* sysdeps/powerpc/powerpc32/fpu/setjmp-common.S (__sigsetjmp): Ditto.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S (__brk): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
	(__getcontext): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
	(__setcontext): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
	(__swapcontext): Likewise.

linuxthreads/

2005-05-17  Alan Modra  <amodra@bigpond.net.au>

	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
	(SINGLE_THREAD_P): Add variant for new PLT/GOT layout.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S (__vfork): Avoid
	bl into the GOT when HAVE_ASM_PPC_REL16.

diff -urpN -xCVS libc4/config.h.in libc-current/config.h.in
--- libc4/config.h.in	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/config.h.in	2005-05-14 00:45:30.000000000 +0930
@@ -217,6 +217,9 @@
 /* Define if inlined system calls are available.  */
 #undef HAVE_INLINED_SYSCALLS
 
+/* Define if your assembler and linker support R_PPC_REL16* relocs.  */
+#undef HAVE_ASM_PPC_REL16
+
 /*
  */
 
diff -urpN -xCVS libc4/elf/elf.h libc-current/elf/elf.h
--- libc4/elf/elf.h	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/elf/elf.h	2005-05-14 13:25:38.000000000 +0930
@@ -1980,6 +1980,9 @@ typedef Elf32_Addr Elf32_Conflict;
    that may still be in object files.  */
 #define R_PPC_TOC16		255
 
+/* PowerPC specific values for the Dyn d_tag field.  */
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_NUM		1
 
 /* PowerPC64 relocations defined by the ABIs */
 #define R_PPC64_NONE		R_PPC_NONE
diff -urpN -xCVS libc4/elf/tls-macros.h libc-current/elf/tls-macros.h
--- libc4/elf/tls-macros.h	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/elf/tls-macros.h	2005-05-14 00:51:47.000000000 +0930
@@ -703,6 +703,8 @@ register void *__gp __asm__("$29");
 
 #elif defined __powerpc__ && !defined __powerpc64__
 
+#include "config.h"
+
 # define __TLS_CALL_CLOBBERS						\
 	"0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",	\
 	"lr", "ctr", "cr0", "cr1", "cr5", "cr6", "cr7"
@@ -715,7 +717,20 @@ register void *__gp __asm__("$29");
      __result; })
 
 /* PowerPC32 Initial Exec TLS access.  */
-# define TLS_IE(x)					\
+# ifdef HAVE_ASM_PPC_REL16
+#  define TLS_IE(x)					\
+  ({ int *__result;					\
+     asm ("bcl 20,31,1f\n1:\t"				\
+	  "mflr %0\n\t"					\
+	  "addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t"	\
+	  "addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n\t"	\
+	  "lwz %0," #x "@got@tprel(%0)\n\t"		\
+	  "add %0,%0," #x "@tls"			\
+	  : "=b" (__result) :				\
+	  : "lr");					\
+     __result; })
+# else
+#  define TLS_IE(x)					\
   ({ int *__result;					\
      asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t"	\
 	  "mflr %0\n\t"					\
@@ -724,9 +739,24 @@ register void *__gp __asm__("$29");
 	  : "=b" (__result) :				\
 	  : "lr");					\
      __result; })
+# endif
 
 /* PowerPC32 Local Dynamic TLS access.  */
-# define TLS_LD(x)					\
+# ifdef HAVE_ASM_PPC_REL16
+#  define TLS_LD(x)					\
+  ({ int *__result;					\
+     asm ("bcl 20,31,1f\n1:\t"				\
+	  "mflr 3\n\t"					\
+	  "addis 3,3,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t"	\
+	  "addi 3,3,_GLOBAL_OFFSET_TABLE_-1b@l\n\t"	\
+	  "addi 3,3," #x "@got@tlsld\n\t"		\
+	  "bl __tls_get_addr@plt\n\t"			\
+	  "addi %0,3," #x "@dtprel"			\
+	  : "=r" (__result) :				\
+	  : __TLS_CALL_CLOBBERS);			\
+     __result; })
+# else
+#  define TLS_LD(x)					\
   ({ int *__result;					\
      asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t"	\
 	  "mflr 3\n\t"					\
@@ -736,9 +766,23 @@ register void *__gp __asm__("$29");
 	  : "=r" (__result) :				\
 	  : __TLS_CALL_CLOBBERS);			\
      __result; })
+# endif
 
 /* PowerPC32 General Dynamic TLS access.  */
-# define TLS_GD(x)					\
+# ifdef HAVE_ASM_PPC_REL16
+#  define TLS_GD(x)					\
+  ({ register int *__result __asm__ ("r3");		\
+     asm ("bcl 20,31,1f\n1:\t"				\
+	  "mflr 3\n\t"					\
+	  "addis 3,3,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t"	\
+	  "addi 3,3,_GLOBAL_OFFSET_TABLE_-1b@l\n\t"	\
+	  "addi 3,3," #x "@got@tlsgd\n\t"		\
+	  "bl __tls_get_addr@plt"			\
+	  : :						\
+	  : __TLS_CALL_CLOBBERS);			\
+     __result; })
+# else
+#  define TLS_GD(x)					\
   ({ register int *__result __asm__ ("r3");		\
      asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t"	\
 	  "mflr 3\n\t"					\
@@ -747,6 +791,7 @@ register void *__gp __asm__("$29");
 	  : :						\
 	  : __TLS_CALL_CLOBBERS);			\
      __result; })
+# endif
 
 #elif defined __powerpc__ && defined __powerpc64__
 
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/configure.in libc-current/sysdeps/powerpc/powerpc32/configure.in
--- libc4/sysdeps/powerpc/powerpc32/configure.in	1970-01-01 09:30:00.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/configure.in	2005-05-13 20:51:27.000000000 +0930
@@ -0,0 +1,18 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc/powerpc32.
+
+# See whether gas has R_PPC_REL16 relocs.
+AC_CACHE_CHECK(for R_PPC_REL16 gas support, libc_cv_ppc_rel16, [dnl
+cat > conftest.s <<\EOF
+	.text
+	addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha
+EOF
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  libc_cv_ppc_rel16=yes
+else
+  libc_cv_ppc_rel16=no
+fi
+rm -f conftest*])
+if test $libc_cv_ppc_rel16 = yes; then
+  AC_DEFINE(HAVE_ASM_PPC_REL16)
+fi
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/Makefile libc-current/sysdeps/powerpc/powerpc32/Makefile
--- libc4/sysdeps/powerpc/powerpc32/Makefile	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/Makefile	2005-05-16 13:27:03.000000000 +0930
@@ -15,6 +15,8 @@ endif
 # we want to use -fpic, because this generates fewer relocs.
 ifeq (yes,$(build-shared))
 pic-ccflag = -fpic
+# At the moment, -fPIC and -mdata-plt don't work together.
+PIC-ccflag = -fpic
 endif
 
 ifeq ($(subdir),csu)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/dl-dtprocnum.h libc-current/sysdeps/powerpc/powerpc32/dl-dtprocnum.h
--- libc4/sysdeps/powerpc/powerpc32/dl-dtprocnum.h	1970-01-01 09:30:00.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/dl-dtprocnum.h	2005-05-13 16:04:21.000000000 +0930
@@ -0,0 +1,3 @@
+/* Number of extra dynamic section entries for this architecture.  By
+   default there are none.  */
+#define DT_THISPROCNUM	DT_PPC_NUM
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/dl-machine.h libc-current/sysdeps/powerpc/powerpc32/dl-machine.h
--- libc4/sysdeps/powerpc/powerpc32/dl-machine.h	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/dl-machine.h	2005-05-16 15:25:29.000000000 +0930
@@ -25,6 +25,10 @@
 #include <assert.h>
 #include <dl-tls.h>
 
+/* Translate a processor specific dynamic tag to the index
+   in l_info array.  */
+#define DT_PPC(x) (DT_PPC_##x - DT_LOPROC + DT_NUM)
+
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int
 elf_machine_matches_host (const Elf32_Ehdr *ehdr)
@@ -32,24 +36,38 @@ elf_machine_matches_host (const Elf32_Eh
   return ehdr->e_machine == EM_PPC;
 }
 
+/* Return the value of the GOT pointer.  */
+static inline Elf32_Addr * __attribute__ ((const))
+ppc_got (void)
+{
+  Elf32_Addr *got;
+#ifdef HAVE_ASM_PPC_REL16
+  asm ("bcl 20,31,1f\n"
+       "1:	mflr %0\n"
+       "	addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+       "	addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+       : "=b" (got) : : "lr");
+#else
+  asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
+       : "=l" (got));
+#endif
+  return got;
+}
 
 /* Return the link-time address of _DYNAMIC, stored as
    the first value in the GOT. */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
 elf_machine_dynamic (void)
 {
-  Elf32_Addr *got;
-  asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
-       : "=l"(got));
-  return *got;
+  return *ppc_got ();
 }
 
 /* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
 elf_machine_load_address (void)
 {
-  unsigned int *got;
-  unsigned int *branchaddr;
+  Elf32_Addr *branchaddr;
+  Elf32_Addr runtime_dynamic;
 
   /* This is much harder than you'd expect.  Possibly I'm missing something.
      The 'obvious' way:
@@ -80,19 +98,17 @@ elf_machine_load_address (void)
      the address ourselves. That gives us the following code: */
 
   /* Get address of the 'b _DYNAMIC@local'...  */
-  asm ("bl 0f ;"
+  asm ("bcl 20,31,0f;"
        "b _DYNAMIC@local;"
        "0:"
-       : "=l"(branchaddr));
-
-  /* ... and the address of the GOT.  */
-  asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
-       : "=l"(got));
+       : "=l" (branchaddr));
 
   /* So now work out the difference between where the branch actually points,
      and the offset of that location in memory from the start of the file.  */
-  return ((Elf32_Addr)branchaddr - *got
-	  + ((int)(*branchaddr << 6 & 0xffffff00) >> 6));
+  runtime_dynamic = ((Elf32_Addr) branchaddr
+		     + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6));
+
+  return runtime_dynamic - elf_machine_dynamic ();
 }
 
 #define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
@@ -144,13 +160,56 @@ __elf_preferred_address(struct link_map 
 /* The PowerPC never uses REL relocations.  */
 #define ELF_MACHINE_NO_REL 1
 
-/* Set up the loaded object described by L so its unrelocated PLT
+/* Set up the loaded object described by MAP so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.
    Also install a small trampoline to be used by entries that have
    been relocated to an address too far away for a single branch.  */
 extern int __elf_machine_runtime_setup (struct link_map *map,
 					int lazy, int profile);
-#define elf_machine_runtime_setup __elf_machine_runtime_setup
+
+static inline int
+elf_machine_runtime_setup (struct link_map *map,
+			   int lazy, int profile)
+{
+  if (map->l_info[DT_JMPREL] == 0)
+    return lazy;
+
+  if (map->l_info[DT_PPC(GOT)] == 0)
+    /* Handle old style PLT.  */
+    return __elf_machine_runtime_setup (map, lazy, profile);
+
+  /* New style non-exec PLT consisting of an array of addresses.  */
+  map->l_info[DT_PPC(GOT)]->d_un.d_ptr += map->l_addr;
+  if (lazy)
+    {
+      Elf32_Addr *plt, *got;
+      Elf32_Word num_plt_entries;
+      void (*dlrr) (void);
+      extern void _dl_runtime_resolve (void);
+      extern void _dl_prof_resolve (void);
+
+      if (__builtin_expect (!profile, 1))
+	dlrr = _dl_runtime_resolve;
+      else
+	{
+	  if (GLRO(dl_profile) != NULL
+	      &&_dl_name_match_p (GLRO(dl_profile), map))
+	    GL(dl_profile_map) = map;
+	  dlrr = _dl_prof_resolve;
+	}
+      got = (Elf32_Addr *) map->l_info[DT_PPC(GOT)]->d_un.d_ptr;
+      got[1] = (Elf32_Addr) dlrr;
+      got[2] = (Elf32_Addr) map;
+
+      /* Relocate everything in .plt by the load address offset.  */
+      plt = (Elf32_Addr *) D_PTR (map, l_info[DT_PLTGOT]);
+      num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+			 / sizeof (Elf32_Rela));
+      while (num_plt_entries-- != 0)
+	*plt++ += map->l_addr;
+    }
+  return lazy;
+}
 
 /* Change the PLT entry whose reloc is 'reloc' to call the actual routine.  */
 extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map,
@@ -163,7 +222,12 @@ elf_machine_fixup_plt (struct link_map *
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf64_Addr finaladdr)
 {
-  return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr);
+  if (map->l_info[DT_PPC(GOT)] == 0)
+    /* Handle old style PLT.  */
+    return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr);
+
+  *reloc_addr = finaladdr;
+  return finaladdr;
 }
 
 /* Return the final value of a plt relocation.  */
@@ -286,11 +350,16 @@ elf_machine_rela (struct link_map *map, 
       break;
 #endif /* USE_TLS etc. */
 
-#ifdef RESOLVE_CONFLICT_FIND_MAP
     case R_PPC_JMP_SLOT:
+#ifdef RESOLVE_CONFLICT_FIND_MAP
       RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
-      /* FALLTHROUGH */
 #endif
+      if (map->l_info[DT_PPC(GOT)] != 0)
+	{
+	  *reloc_addr = value;
+	  break;
+	}
+      /* FALLTHROUGH */
 
     default:
       __process_machine_rela (map, reloc, sym_map, sym, refsym,
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/elf/start.S libc-current/sysdeps/powerpc/powerpc32/elf/start.S
--- libc4/sysdeps/powerpc/powerpc32/elf/start.S	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/elf/start.S	2005-05-14 22:17:20.000000000 +0930
@@ -52,7 +52,7 @@ L(start_addresses):
 	ASM_SIZE_DIRECTIVE(L(start_addresses))
 
 	.section ".text"
-#ifdef PIC
+#if defined PIC && !defined HAVE_ASM_PPC_REL16
 L(start_addressesp):
 	.long	L(start_addresses)-L(branch)
 #endif
@@ -73,11 +73,19 @@ L(branch):
 	mtlr	r0
 	stw	r0,0(r1)
  /* Set r13 to point at the 'small data area', and put the address of
-    start_addresses in r8...  */
+    start_addresses in r8.  Also load the GOT pointer so that new PLT
+    calls work, like the one to __libc_start_main.  */
 #ifdef PIC
+# ifdef HAVE_ASM_PPC_REL16
+	addis	r30,r13,_GLOBAL_OFFSET_TABLE_-L(branch)@ha
+	addis	r8,r13,L(start_addresses)-L(branch)@ha
+	addi	r30,r30,_GLOBAL_OFFSET_TABLE_-L(branch)@l
+	lwzu	r13,L(start_addresses)-L(branch)@l(r8)
+# else
 	lwz	r8,L(start_addressesp)-L(branch)(r13)
 	add	r8,r13,r8
 	lwz	r13,0(r8)
+# endif
 #else
 	lis	r8,L(start_addresses)@ha
 	lwzu	r13,L(start_addresses)@l(r8)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/sysdep.h libc-current/sysdeps/powerpc/powerpc32/sysdep.h
--- libc4/sysdeps/powerpc/powerpc32/sysdep.h	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/sysdep.h	2005-05-14 01:02:28.000000000 +0930
@@ -20,6 +20,7 @@
 #include <sysdeps/powerpc/sysdep.h>
 
 #ifdef __ASSEMBLER__
+#include "config.h"
 
 #ifdef __ELF__
 
@@ -30,9 +31,24 @@
    to locate our caller and so it can restore it; so store one just
    for its benefit.  */
 # ifdef PIC
-#  define CALL_MCOUNT							      \
-  .pushsection;								      \
-  .section ".data";    							      \
+#  if 0 /* def HAVE_ASM_PPC_REL16 */
+/* Unfortunately this doesn't work, because new plt calls require r30 to
+   hold the GOT pointer.  FIXME.  */
+#   define CALL_MCOUNT							      \
+  .section ".data";							      \
+  .align ALIGNARG(2);							      \
+0:.long 0;								      \
+  .previous;								      \
+  mflr  r0;								      \
+  bcl   20,31,1f;							      \
+1:mflr  r11;								      \
+  stw   r0,4(r1);	       						      \
+  addis r11,r11,0b-1b@ha;						      \
+  addi  r0,r11,0b-1b@l;							      \
+  bl    JUMPTARGET(_mcount);
+#  else
+#   define CALL_MCOUNT							      \
+  .section ".data";							      \
   .align ALIGNARG(2);							      \
 0:.long 0;								      \
   .previous;								      \
@@ -42,6 +58,7 @@
   mflr  r11;								      \
   lwz   r0,0b@got(r11);							      \
   bl    JUMPTARGET(_mcount);
+#  endif
 # else  /* PIC */
 #  define CALL_MCOUNT							      \
   .section ".data";							      \
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/dl-start.S libc-current/sysdeps/powerpc/powerpc32/dl-start.S
--- libc4/sysdeps/powerpc/powerpc32/dl-start.S	2005-05-16 21:21:10.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/dl-start.S	2005-05-13 20:51:27.000000000 +0930
@@ -47,8 +47,15 @@ ENTRY(_dl_start_user)
    passed by value!).  */
 
 /*  Put our GOT pointer in r31, */
+#ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r31
+	addis	r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l
+#else
 	bl	_GLOBAL_OFFSET_TABLE_-4@local
 	mflr	r31
+#endif
 /*  the address of _start in r30, */
 	mr	r30,r3
 /*  &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28.  */
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/memset.S libc-current/sysdeps/powerpc/powerpc32/memset.S
--- libc4/sysdeps/powerpc/powerpc32/memset.S	2005-05-16 22:00:59.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/memset.S	2005-05-13 20:51:27.000000000 +0930
@@ -264,10 +264,17 @@ L(checklinesize):
 	beq	L(medium)
 /* Establishes GOT addressability so we can load __cache_line_size
    from static. This value was set from the aux vector during startup.  */
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	rGOT
+	addis	rGOT,rGOT,__cache_line_size-1b@ha
+	lwz	rCLS,__cache_line_size-1b@l(rGOT)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	rGOT
 	lwz	rGOT,__cache_line_size@got(rGOT)
 	lwz	rCLS,0(rGOT)
+# endif
 	mtlr	rTMP
 #else
 /* Load __cache_line_size from static. This value was set from the
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S libc-current/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S	2005-05-17 10:25:55.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S	2005-05-14 01:59:01.000000000 +0930
@@ -34,8 +34,15 @@ ENTRY (BP_SYM (__longjmp))
 #ifndef __NO_VMX__
 # ifdef PIC
 	mflr    r6
+#  ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r5
+	addis	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+#  else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r5
+#  endif
 #  ifdef SHARED
 	lwz     r5,_rtld_global_ro@got(r5)
 	mtlr    r6
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_ceil.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_ceil.S	2005-05-17 09:38:38.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceil.S	2005-05-17 10:09:44.000000000 +0930
@@ -29,11 +29,19 @@ ENTRY (__ceil)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S	2005-05-17 09:53:38.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S	2005-05-17 10:10:13.000000000 +0930
@@ -20,7 +20,7 @@
 #include <sysdep.h>
 
 	.section	.rodata.cst4,"aM",@progbits,4
-	.align 2
+	.align	2
 .LC0:	/* 2**23 */
 	.long 0x4b000000
 
@@ -29,11 +29,19 @@ ENTRY (__ceilf)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_floor.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_floor.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_floor.S	2005-05-17 09:38:17.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_floor.S	2005-05-17 10:10:38.000000000 +0930
@@ -29,11 +29,19 @@ ENTRY (__floor)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_floorf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_floorf.S	2005-05-17 09:53:39.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_floorf.S	2005-05-17 10:11:02.000000000 +0930
@@ -20,7 +20,7 @@
 #include <sysdep.h>
 
 	.section	.rodata.cst4,"aM",@progbits,4
-	.align 2
+	.align	2
 .LC0:	/* 2**23 */
 	.long 0x4b000000
 
@@ -29,11 +29,19 @@ ENTRY (__floorf)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_lround.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_lround.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_lround.S	2005-05-17 09:37:58.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_lround.S	2005-05-17 10:11:31.000000000 +0930
@@ -41,9 +41,16 @@
 ENTRY (__lround)
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	addi	r9,r9,.LC0-1b@l
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+# endif
 	mtlr	r11
 	lfs	fp12,0(r9)
 #else
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_rint.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_rint.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_rint.S	2005-05-17 09:37:07.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_rint.S	2005-05-17 10:12:45.000000000 +0930
@@ -31,11 +31,19 @@
 ENTRY (__rint)
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_rintf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_rintf.S	2005-05-17 09:53:39.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_rintf.S	2005-05-17 10:13:16.000000000 +0930
@@ -20,7 +20,7 @@
 #include <sysdep.h>
 
 	.section	.rodata.cst4,"aM",@progbits,4
-	.align 2
+	.align	2
 .LC0:	/* 2**23 */
 	.long 0x4b000000
 
@@ -28,11 +28,19 @@
 ENTRY (__rintf)
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_round.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_round.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_round.S	2005-05-17 09:36:50.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_round.S	2005-05-17 10:13:38.000000000 +0930
@@ -41,9 +41,16 @@ ENTRY (__round)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	addi	r9,r9,.LC0-1b@l
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+# endif
 	mtlr	r11
 	lfs	fp13,0(r9)
 #else
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_roundf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_roundf.S	2005-05-17 09:36:30.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_roundf.S	2005-05-17 10:13:55.000000000 +0930
@@ -41,9 +41,16 @@ ENTRY (__roundf )
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	addi	r9,r9,.LC0-1b@l
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+# endif
 	mtlr	r11
 	lfs	fp13,0(r9)
 #else
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_trunc.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_trunc.S	2005-05-17 10:24:31.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_trunc.S	2005-05-17 10:14:12.000000000 +0930
@@ -36,11 +36,19 @@ ENTRY (__trunc)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/s_truncf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/s_truncf.S	2005-05-17 09:53:39.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_truncf.S	2005-05-17 10:14:26.000000000 +0930
@@ -20,7 +20,7 @@
 #include <sysdep.h>
 
 	.section	.rodata.cst4,"aM",@progbits,4
-	.align 2
+	.align	2
 .LC0:	/* 2**23 */
 	.long 0x4b000000
 
@@ -36,11 +36,19 @@ ENTRY (__truncf)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	mtlr	r11
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
 	mtlr	r11
 	lfs	fp13,0(r9)
+# endif
 #else
 	lis	r9,.LC0@ha
 	lfs	fp13,.LC0@l(r9)
diff -urpN -xCVS libc4/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S libc-current/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
--- libc4/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S	2005-05-17 10:37:16.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S	2005-05-17 10:36:39.000000000 +0930
@@ -76,8 +76,15 @@ ENTRY (BP_SYM (__sigsetjmp))
 #ifndef __NO_VMX__
 # ifdef PIC
 	mflr    r6
+#  ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r5
+	addis	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+#  else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r5
+#  endif
 #  ifdef SHARED
 	lwz     r5,_rtld_global_ro@got(r5)
 	mtlr    r6
diff -urpN -xCVS libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
--- libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S	2005-05-13 23:02:37.000000000 +0930
@@ -34,11 +34,19 @@ ENTRY (BP_SYM (__brk))
 	lwz     r6,8(r1)
 #ifdef PIC
 	mflr    r4
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r5
+	addis	r5,r5,__curbrk-1b@ha
+	mtlr	r4
+	stw	r3,__curbrk-1b@l(r5)
+# else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r5
 	lwz     r5,__curbrk@got(r5)
 	mtlr    r4
 	stw     r3,0(r5)
+# endif
 #else
 	lis     r4,__curbrk@ha
 	stw     r3,__curbrk@l(r4)
diff -urpN -xCVS libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
--- libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S	2005-05-14 01:58:59.000000000 +0930
@@ -129,8 +129,15 @@ ENTRY(__getcontext)
 
 #ifdef PIC
 	mflr    r8
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r7
+	addis	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r7
+# endif
 # ifdef SHARED
 	lwz     r7,_rtld_global_ro@got(r7)
 	mtlr    r8
diff -urpN -xCVS libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
--- libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S	2005-05-14 01:58:58.000000000 +0930
@@ -58,8 +58,15 @@ ENTRY(__setcontext)
 
 #ifdef PIC
 	mflr    r8
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r7
+	addis	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r7
+# endif
 # ifdef SHARED
 	lwz     r7,_rtld_global_ro@got(r7)
 	mtlr    r8
diff -urpN -xCVS libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
--- libc4/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S	2005-05-14 01:58:57.000000000 +0930
@@ -130,8 +130,15 @@ ENTRY(__swapcontext)
 	stfd	fp0,_UC_FREGS+(32*8)(r3)
 #ifdef PIC
 	mflr    r8
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r7
+	addis	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r7
+# endif
 # ifdef SHARED
 	lwz     r7,_rtld_global_ro@got(r7)
 	mtlr    r8
@@ -272,8 +279,15 @@ L(no_vec):
 
 #ifdef PIC
 	mflr    r8
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r7
+	addis	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r7
+# endif
 # ifdef SHARED
 	lwz     r7,_rtld_global_ro@got(r7)
 	mtlr    r8
diff -urpN -xCVS libc4/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
--- libc4/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	2005-05-13 23:11:11.000000000 +0930
@@ -111,7 +111,17 @@ extern int __local_multiple_threads attr
   lwz 10,__local_multiple_threads@l(10);				\
   cmpwi 10,0
 #   else
-#    define SINGLE_THREAD_P						\
+#    ifdef HAVE_ASM_PPC_REL16
+#     define SINGLE_THREAD_P						\
+  mflr 9;								\
+  bcl 20,31,1f;								\
+1:mflr 10;								\
+  addis 10,10,__local_multiple_threads-1b@ha;				\
+  lwz 10,__local_multiple_threads-1b@l(10);				\
+  mtlr 9;								\
+  cmpwi 10,0
+#    else
+#     define SINGLE_THREAD_P						\
   mflr 9;								\
   bl _GLOBAL_OFFSET_TABLE_@local-4;					\
   mflr 10;								\
@@ -119,6 +129,7 @@ extern int __local_multiple_threads attr
   lwz 10,__local_multiple_threads@got(10);				\
   lwz 10,0(10);								\
   cmpwi 10,0
+#    endif
 #   endif
 #  endif
 # endif
diff -urpN -xCVS libc4/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
--- libc4/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S	2005-05-17 10:33:46.000000000 +0930
+++ libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S	2005-05-13 23:19:01.000000000 +0930
@@ -31,11 +31,19 @@ ENTRY (__vfork)
 #ifdef __NR_vfork
 # ifdef SHARED
 	mflr	9
+#  ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	10
+	addis	10,10,__libc_pthread_functions-1b@ha
+	lwz	10,__libc_pthread_functions-1b@l(10)
+	mtlr	9
+#  else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	10
 	mtlr	9
 	lwz	10,__libc_pthread_functions@got(10)
 	lwz	10,0(10)
+#  endif
 # else
 	.weak	pthread_create
 	lis	10,pthread_create@ha

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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