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]

Re: new ppc32 GOT/PLT support for mcount


Corrects ppc _mcount handling in previous patch.  I haven't merged
http://sources.redhat.com/ml/libc-alpha/2005-06/msg00001.html from Jakub
into this.

2005-06-14  Alan Modra  <amodra@bigpond.net.au>

	* config.h.in (HAVE_ASM_PPC_REL16): Add.
	* elf/elf.h (DT_PPC_GOT, 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/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/sysdep.h: Include config.h.
	(CALL_MCOUNT): Don't set up counter vars.
	* sysdeps/powerpc/powerpc32/ppc-mcount.S: Correct comment.
	* 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/dl-start.S (_dl_start_user): Don't bl
	into the GOT when HAVE_ASM_PPC_REL16.
	* 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.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S (stackblock):
	Comment.
	(__socket): Bomb if NARGS >= 7.  Invoke CGOTSETUP and CGOTRESTORE.

linuxthreads/

2005-06-14  Alan Modra  <amodra@bigpond.net.au>

	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
	Invoke CGOTSETUP and CGOTRESTORE.
	(CGOTSETUP, CGOTRESTORE): Define.
	(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.

nptl/

2005-06-14  Alan Modra  <amodra@bigpond.net.au>

	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
	Invoke CGOTSETUP and CGOTRESTORE.
	(CGOTSETUP, CGOTRESTORE): Define.


diff -urpN -xCVS -x'*~' -x'.#*' libc-virgin/config.h.in libc-current/config.h.in
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/elf/elf.h libc-current/elf/elf.h
--- libc-virgin/elf/elf.h	2005-06-13 13:30:09.000000000 +0930
+++ libc-current/elf/elf.h	2005-05-30 11:27:51.000000000 +0930
@@ -1983,6 +1983,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 -x'*~' -x'.#*' libc-virgin/elf/tls-macros.h libc-current/elf/tls-macros.h
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/configure.in libc-current/sysdeps/powerpc/powerpc32/configure.in
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/configure libc-current/sysdeps/powerpc/powerpc32/configure
--- libc-virgin/sysdeps/powerpc/powerpc32/configure	1970-01-01 09:30:00.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/configure	2005-05-13 20:53:28.000000000 +0930
@@ -0,0 +1,33 @@
+# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc/powerpc32.
+
+# See whether gas has R_PPC_REL16 relocs.
+echo "$as_me:$LINENO: checking for R_PPC_REL16 gas support" >&5
+echo $ECHO_N "checking for R_PPC_REL16 gas support... $ECHO_C" >&6
+if test "${libc_cv_ppc_rel16+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	.text
+	addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  libc_cv_ppc_rel16=yes
+else
+  libc_cv_ppc_rel16=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ppc_rel16" >&5
+echo "${ECHO_T}$libc_cv_ppc_rel16" >&6
+if test $libc_cv_ppc_rel16 = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASM_PPC_REL16 1
+_ACEOF
+
+fi
diff -urpN -xCVS -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/dl-dtprocnum.h libc-current/sysdeps/powerpc/powerpc32/dl-dtprocnum.h
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/dl-machine.h libc-current/sysdeps/powerpc/powerpc32/dl-machine.h
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/sysdep.h libc-current/sysdeps/powerpc/powerpc32/sysdep.h
--- libc-virgin/sysdeps/powerpc/powerpc32/sysdep.h	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/sysdep.h	2005-06-13 13:00:59.000000000 +0930
@@ -29,31 +30,10 @@
 /* The mcount code relies on a the return address being on the stack
    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";    							      \
-  .align ALIGNARG(2);							      \
-0:.long 0;								      \
-  .previous;								      \
-  mflr  r0;								      \
-  stw   r0,4(r1);	       						      \
-  bl    _GLOBAL_OFFSET_TABLE_@local-4;					      \
-  mflr  r11;								      \
-  lwz   r0,0b@got(r11);							      \
-  bl    JUMPTARGET(_mcount);
-# else  /* PIC */
-#  define CALL_MCOUNT							      \
-  .section ".data";							      \
-  .align ALIGNARG(2);							      \
-0:.long 0;								      \
-  .previous;								      \
+# define CALL_MCOUNT							      \
   mflr  r0;								      \
-  lis   r11,0b@ha;		       					      \
   stw   r0,4(r1);	       						      \
-  addi  r0,r11,0b@l;							      \
   bl    JUMPTARGET(_mcount);
-# endif /* PIC */
 #else  /* PROF */
 # define CALL_MCOUNT		/* Do nothing.  */
 #endif /* PROF */
diff -urpN -xCVS -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/ppc-mcount.S libc-current/sysdeps/powerpc/powerpc32/ppc-mcount.S
--- libc-virgin/sysdeps/powerpc/powerpc32/ppc-mcount.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/ppc-mcount.S	2005-06-13 13:03:58.000000000 +0930
@@ -1,5 +1,5 @@
 /* PowerPC-specific implementation of profiling support.
-   Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -24,25 +24,19 @@
 
 #include <sysdep.h>
 
-/* We do profiling as described in the SYSV ELF ABI, _mcount is called
-   with the address of a data word in r0 (that is different for every
-   routine, initialised to 0, and otherwise unused).  The caller has put
-   the address the caller will return to in the usual place on the stack,
-   4(r1).  _mcount is responsible for ensuring that when it returns no
-   argument-passing registers are disturbed, and that the LR is set back
-   to (what the caller sees as) 4(r1).
+/* We do profiling as described in the SYSV ELF ABI, except that glibc
+   _mcount manages its own counters.  The caller has put the address the
+   caller will return to in the usual place on the stack, 4(r1).  _mcount
+   is responsible for ensuring that when it returns no argument-passing
+   registers are disturbed, and that the LR is set back to (what the
+   caller sees as) 4(r1).
 
    This is intended so that the following code can be inserted at the
    front of any routine without changing the routine:
 
 	.data
-	.align	2
-   0:	.long	0
-	.previous
 	mflr	r0
-	lis	r11,0b@ha
 	stw	r0,4(r1)
-	addi	r0,r11,0b@l
 	bl	_mcount
 */
 
diff -urpN -xCVS -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/elf/start.S libc-current/sysdeps/powerpc/powerpc32/elf/start.S
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/dl-start.S libc-current/sysdeps/powerpc/powerpc32/dl-start.S
--- libc-virgin/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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/memset.S libc-current/sysdeps/powerpc/powerpc32/memset.S
--- libc-virgin/sysdeps/powerpc/powerpc32/memset.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/memset.S	2005-05-23 15:02:55.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S libc-current/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S	2005-05-27 16:53:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S	2005-05-27 16:53:37.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_ceil.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_ceil.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceil.S	2005-05-23 15:02:42.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S	2005-05-23 14:51:12.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_floor.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_floor.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_floor.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_floor.S	2005-05-23 15:02:37.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_floorf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_floorf.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_floorf.S	2005-05-23 14:51:12.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_lround.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_lround.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_lround.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_lround.S	2005-05-23 14:51:12.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_rint.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_rint.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_rint.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_rint.S	2005-05-23 15:02:30.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_rintf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_rintf.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_rintf.S	2005-05-23 14:51: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
 
@@ -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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_round.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_round.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_round.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_round.S	2005-05-23 14:51:13.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_roundf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_roundf.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_roundf.S	2005-05-23 14:51:13.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_trunc.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_trunc.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_trunc.S	2005-05-23 15:02:19.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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_truncf.S libc-current/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/s_truncf.S	2005-05-25 21:52:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/s_truncf.S	2005-05-23 14:51: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
 
@@ -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 -x'*~' -x'.#*' libc-virgin/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S libc-current/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
--- libc-virgin/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S	2005-05-27 16:53:37.000000000 +0930
+++ libc-current/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S	2005-05-27 16:54:57.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 -x'*~' -x'.#*' libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S
--- libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S	2005-05-25 21:52:54.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/brk.S	2005-05-23 14:51:18.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 -x'*~' -x'.#*' libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
--- libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S	2005-05-25 21:52:54.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S	2005-05-23 14:51:19.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 -x'*~' -x'.#*' libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
--- libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S	2005-05-25 21:52:55.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S	2005-05-23 14:51:19.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 -x'*~' -x'.#*' libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S
--- libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S	2003-07-14 14:44:28.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/socket.S	2005-05-24 14:04:23.000000000 +0930
@@ -39,6 +39,8 @@
 #define NARGS 3
 #endif
 
+/* 0(r1) and 4(r1) are reserved by the ABI, 8(r1), 12(r1), 16(r1) are used
+   for temp saves.  44(r1) is used to save r30.  */
 #define stackblock 20
 
 #ifndef __socket
@@ -69,12 +71,6 @@ ENTRY(__socket)
 	stw  r8,20+stackblock(r1)
 #endif
 #if NARGS >= 7
-	stw  r9,24+stackblock(r1)
-#endif
-#if NARGS >= 8
-	stw  r10,28+stackblock(r1)
-#endif
-#if NARGS >= 9
 #error too many arguments!
 #endif
 
@@ -94,6 +90,7 @@ ENTRY(__socket)
 	mflr	r9
 	stw	r9,52(r1)
 	cfi_offset (lr, 4)
+	CGOTSETUP
 	CENABLE
 	stw	r3,16(r1)
 	li	r3,P(SOCKOP_,socket)
@@ -107,6 +104,7 @@ ENTRY(__socket)
 	lwz	r4,52(r1)
 	lwz	r0,12(r1)
 	lwz	r3,8(r1)
+	CGOTRESTORE
 	mtlr	r4
 	mtcr	r0
 	addi	r1,r1,48
diff -urpN -xCVS -x'*~' -x'.#*' libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
--- libc-virgin/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S	2005-05-25 21:52:55.000000000 +0930
+++ libc-current/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S	2005-05-23 14:51:19.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 -x'*~' -x'.#*' libc-virgin/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
--- libc-virgin/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	2005-05-25 21:51:58.000000000 +0930
+++ libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	2005-05-24 14:17:11.000000000 +0930
@@ -37,6 +37,7 @@
     stwu 1,-48(1);							\
     mflr 9;								\
     stw 9,52(1);							\
+    CGOTSETUP;								\
     DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
     CENABLE;								\
     stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
@@ -50,6 +51,7 @@
     lwz 4,52(1);							\
     lwz 0,12(1);	/* restore CR/R3. */				\
     lwz 3,8(1);								\
+    CGOTRESTORE;							\
     mtlr 4;								\
     mtcr 0;								\
     addi 1,1,48;
@@ -75,6 +77,9 @@
 # define DOCARGS_6	stw 8,40(1); DOCARGS_5
 # define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
 
+# define CGOTSETUP
+# define CGOTRESTORE
+
 # ifdef IS_IN_libpthread
 #  define CENABLE	bl __pthread_enable_asynccancel@local
 #  define CDISABLE	bl __pthread_disable_asynccancel@local
@@ -84,6 +89,18 @@
 # else
 #  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel)
 #  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel)
+#  if defined HAVE_AS_REL16 && defined PIC
+#   undef CGOTSETUP
+#   define CGOTSETUP							\
+    bcl 20,31,1f;							\
+ 1: stw 30,44(1);							\
+    mflr 30;								\
+    addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;				\
+    addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l
+#   undef CGOTRESTORE
+#   define CGOTRESTORE							\
+    lwz 30,44(1)
+#  endif
 # endif
 
 # ifdef HAVE_TLS_SUPPORT
@@ -111,7 +128,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 +146,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 -x'*~' -x'.#*' libc-virgin/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
--- libc-virgin/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S	2005-05-25 21:51:58.000000000 +0930
+++ libc-current/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S	2005-05-23 14:51: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
diff -urpN -xCVS -x'*~' -x'.#*' libc-virgin/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h libc-current/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
--- libc-virgin/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	2005-05-25 21:52:11.000000000 +0930
+++ libc-current/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h	2005-05-24 14:17:11.000000000 +0930
@@ -45,6 +45,7 @@
     mflr 9;								\
     stw 9,52(1);							\
     cfi_offset (lr, 4);							\
+    CGOTSETUP;								\
     DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
     CENABLE;								\
     stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
@@ -58,6 +59,7 @@
     lwz 4,52(1);							\
     lwz 0,12(1);	/* restore CR/R3. */				\
     lwz 3,8(1);								\
+    CGOTRESTORE;							\
     mtlr 4;								\
     mtcr 0;								\
     addi 1,1,48;							\
@@ -84,6 +86,9 @@
 # define DOCARGS_6	stw 8,40(1); DOCARGS_5
 # define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
 
+# define CGOTSETUP
+# define CGOTRESTORE
+
 # ifdef IS_IN_libpthread
 #  define CENABLE	bl __pthread_enable_asynccancel@local
 #  define CDISABLE	bl __pthread_disable_asynccancel@local
@@ -93,6 +98,18 @@
 # elif defined IS_IN_librt
 #  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel)
 #  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel)
+#  if defined HAVE_AS_REL16 && defined PIC
+#   undef CGOTSETUP
+#   define CGOTSETUP							\
+    bcl 20,31,1f;							\
+ 1: stw 30,44(1);							\
+    mflr 30;								\
+    addis 30,30,_GLOBAL_OFFSET_TABLE-1b@ha;				\
+    addi 30,30,_GLOBAL_OFFSET_TABLE-1b@l
+#   undef CGOTRESTORE
+#   define CGOTRESTORE							\
+    lwz 30,44(1)
+#  endif
 # else
 #  error Unsupported library
 # endif

-- 
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]