[parisc-linux] [PATCH] Fixup dl-machine for HPPA

Carlos O'Donell carlos@baldric.uwo.ca
Tue, 19 Nov 2002 01:06:42 -0500


--l5oECiFRo5dp+2y7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


libc-alpha,

The following fixes dl-machine.h for hppa.

These fixes have been in debian-glibc for a long time
and have received heavy testing.

Cheers,
Carlos.

Round 2...

 sysdeps/hppa/dl-machine.h |  193 +++++++++++++++++++++++++++++------------------------------
 1 files changed, 97 insertions(+), 96 deletions(-)

--

2000-07-31  David Huggins-Daines  <dhd@debian.org>

	* sysdeps/hppa/dl-machine.h:
	Cleanup assembly, define VALID_ELF_*,
	(elf_machine_dynamic): Cleanup assembly.
	(elf_machine_load_address): Likewise.
	(elf_machine_runtime_setup): Fix relocations.
	(set_dp): Cleanup assembly.
	(elf_machine_rela): Likewise.


--l5oECiFRo5dp+2y7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=01-glibc23-hppa-dl-machine

diff -urN libc/sysdeps/hppa/dl-machine.h libc/sysdeps/hppa/dl-machine.h
--- libc/sysdeps/hppa/dl-machine.h	Wed Nov 14 09:47:09 2001
+++ libc/sysdeps/hppa/dl-machine.h	Wed Nov 14 09:46:02 2001
@@ -28,8 +28,15 @@
 #include <link.h>
 #include <assert.h>
 
+# define VALID_ELF_OSABI(osabi)		((osabi == ELFOSABI_SYSV) || (osabi == ELFOSABI_LINUX))
+# define VALID_ELF_ABIVERSION(ver)	(ver == 0)
+# define VALID_ELF_HEADER(hdr,exp,size) \
+  memcmp (hdr,exp,size-2) == 0 \
+  && VALID_ELF_OSABI (hdr[EI_OSABI]) \
+  && VALID_ELF_ABIVERSION (hdr[EI_ABIVERSION])
+
 /* These must match the definition of the stub in bfd/elf32-hppa.c. */
-#define SIZEOF_PLT_STUB (4*4)
+#define SIZEOF_PLT_STUB (7*4)
 #define GOT_FROM_PLT_STUB (4*4)
 
 /* A PLABEL is a function descriptor.  Properly they consist of just
@@ -66,45 +73,41 @@
   return ehdr->e_machine == EM_PARISC;
 }
 
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline Elf32_Addr
+elf_machine_dynamic (void) __attribute__ ((const));
+
+static inline Elf32_Addr
 elf_machine_dynamic (void)
 {
   Elf32_Addr dynamic;
 
-#if 0
-  /* Use this method if GOT address not yet set up.  */
-  asm (
-"	b,l	1f,%0\n"
+  asm ("b,l	1f,%0\n"
 "	depi	0,31,2,%0\n"
 "1:	addil	L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n"
 "	ldw	R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
-      : "=r" (dynamic) : : "r1");
-#else
-  /* This works because we already have our GOT address available.  */
-  dynamic = (Elf32_Addr) &_DYNAMIC;
-#endif
+       : "=r" (dynamic) : : "r1");
 
   return dynamic;
 }
 
 /* Return the run-time load address of the shared object.  */
 static inline Elf32_Addr
+elf_machine_load_address (void) __attribute__ ((const));
+
+static inline Elf32_Addr
 elf_machine_load_address (void)
 {
-  Elf32_Addr dynamic, dynamic_linkaddress;
+  Elf32_Addr dynamic;
 
   asm (
 "	b,l	1f,%0\n"
 "	depi	0,31,2,%0\n"
 "1:	addil	L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n"
-"	ldo	R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%1\n"
-"	addil	L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%0\n"
-"	ldw	R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%%r1),%0\n"
-   : "=r" (dynamic_linkaddress), "=r" (dynamic) : : "r1");
+"	ldo	R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
+   : "=r" (dynamic) : : "r1");
 
-  return dynamic - dynamic_linkaddress;
+  return dynamic - elf_machine_dynamic ();
 }
 
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
@@ -167,41 +170,39 @@
 	      fptr = (struct hppa_fptr *) (reloc->r_offset + l_addr);
 	      if (r_sym != 0)
 		{
-		  /* Relocate the pointer to the stub.  */
-		  fptr->func += l_addr;
-		  /* Instead of the LTP value, we put the reloc offset
-		     here.  The trampoline code will load the proper
-		     LTP and pass the reloc offset to the fixup
-		     function.  */
-		  fptr->gp = iplt - jmprel;
 		  if (!got)
 		    {
 		      static union {
 			unsigned char c[8];
 			Elf32_Addr i[2];
 		      } sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
+		      const Elf32_Rela *last_rel;
+
+		      last_rel = (const Elf32_Rela *) end_jmprel - 1;
+
+		      /* The stub is immediately after the last .plt
+			 entry.  Rely on .plt relocs being ordered.  */
+		      if (last_rel->r_offset == 0)
+			return 0;
 
 		      /* Find our .got section.  It's right after the
 			 stub.  */
-		      got = (Elf32_Addr *) (fptr->func + GOT_FROM_PLT_STUB);
+		      got = (Elf32_Addr *) (last_rel->r_offset + l_addr
+					    + 8 + SIZEOF_PLT_STUB);
 
-		      /* Sanity check to see if the address we are
-                         going to check below is within a reasonable
-                         approximation of the bounds of the PLT (or,
-                         at least, is at an address that won't fault
-                         on read).  Then check for the magic signature
-                         above. */
-		      if (fptr->func < (Elf32_Addr) fptr + sizeof(*fptr))
-			  return 0;
-		      if (fptr->func >
-			  ((Elf32_Addr) fptr
-			   + SIZEOF_PLT_STUB
-			   + ((l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeof (Elf32_Rela))
-			      * 8)))
-			return 0;
+		      /* Check the magic signature.  */
 		      if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
 			return 0; /* No lazy linking for you! */
 		    }
+
+		  /* Relocate the pointer to the stub.  */
+		  fptr->func = (Elf32_Addr) got - GOT_FROM_PLT_STUB;
+
+		  /* Instead of the LTP value, we put the reloc offset
+		     here.  The trampoline code will load the proper
+		     LTP and pass the reloc offset to the fixup
+		     function.  */
+		  fptr->gp = iplt - jmprel;
 		}
 	      else
 		{
@@ -271,22 +272,24 @@
 "	stw	%r25,-40(%sp)\n" /* argc */				\
 "	stw	%r24,-44(%sp)\n" /* argv */				\
 									\
-	/* We need the LTP, and we need it now. */			\
-	/* $PIC_pcrel$0 points 8 bytes past the current instruction,	\
-	   just like a branch reloc.  This sequence gets us the runtime	\
-	   address of _DYNAMIC. */					\
+	/* We need the LTP, and we need it now.				\
+	   $PIC_pcrel$0 points 8 bytes past the current instruction,	\
+	   just like a branch reloc.  This sequence gets us the		\
+	   runtime address of _DYNAMIC. */				\
 "	bl	0f,%r19\n"						\
 "	depi	0,31,2,%r19\n"	/* clear priviledge bits */		\
 "0:	addil	L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n"			\
 "	ldo	R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n"		\
 									\
-	/* Also get the link time address from the first entry of the GOT.  */ \
+	/* The link time address is stored in the first entry of the	\
+	   GOT.  */							\
 "	addil	L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n"	\
 "	ldw	R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \
 									\
 "	sub	%r26,%r20,%r20\n"	/* Calculate load offset */	\
 									\
-	/* Rummage through the dynamic entries, looking for DT_PLTGOT.  */ \
+	/* Rummage through the dynamic entries, looking for		\
+	   DT_PLTGOT.  */						\
 "	ldw,ma	8(%r26),%r19\n"						\
 "1:	cmpib,=,n 3,%r19,2f\n"	/* tag == DT_PLTGOT? */			\
 "	cmpib,<>,n 0,%r19,1b\n"						\
@@ -306,8 +309,8 @@
 	   |         32 bytes of magic       |				\
 	   |---------------------------------|				\
 	   | 32 bytes argument/sp save area  |				\
-	   |---------------------------------|  ((current->mm->env_end) + 63 & ~63) \
-	   |         N bytes of slack        |				\
+	   |---------------------------------|  ((current->mm->env_end)	\
+	   |         N bytes of slack        |	 + 63 & ~63)		\
 	   |---------------------------------|				\
 	   |      envvar and arg strings     |				\
 	   |---------------------------------|				\
@@ -375,7 +378,7 @@
 "	bl	_dl_init,%r2\n"						\
 "	ldo	4(%r23),%r23\n"	/* delay slot */			\
 									\
-	/* Reload argc, argv  to the registers start.S expects them in (feh) */ \
+	/* Reload argc, argv to the registers start.S expects.  */	\
 "	ldw	-40(%sp),%r25\n"					\
 "	ldw	-44(%sp),%r24\n"					\
 									\
@@ -387,8 +390,8 @@
 "	.word	0xdeadbeef\n"						\
 "	.previous\n"							\
 									\
-	/* %r3 contains a function pointer, we need to mask out the lower \
-	 * bits and load the gp and jump address. */			\
+	/* %r3 contains a function pointer, we need to mask out the	\
+	   lower bits and load the gp and jump address. */		\
 "	depi	0,31,2,%r3\n"						\
 "	ldw	0(%r3),%r2\n"						\
 "	addil	LT'__dl_fini_plabel,%r19\n"				\
@@ -409,43 +409,41 @@
    Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp.  */
 #define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
   extern void tramp_name (void);		    \
-  asm ( "\
-	/* Trampoline for " #tramp_name " */				    \n\
-	.globl " #tramp_name "						    \n\
-	.type " #tramp_name ",@function					    \n\
-" #tramp_name ":							    \n\
-	/* Save return pointer */					    \n\
-	stw	%r2,-20(%sp)						    \n\
-	/* Save argument registers in the call stack frame. */		    \n\
-	stw	%r26,-36(%sp)						    \n\
-	stw	%r25,-40(%sp)						    \n\
-	stw	%r24,-44(%sp)						    \n\
-	stw	%r23,-48(%sp)						    \n\
-	/* Build a call frame. */					    \n\
-	stwm	%sp,64(%sp)						    \n\
-									    \n\
-	/* Set up args to fixup func.  */				    \n\
-	ldw	8+4(%r20),%r26	/* got[1] == struct link_map *  */	    \n\
-	copy	%r19,%r25	/* reloc offset  */			    \n\
-									    \n\
-	/* Call the real address resolver. */				    \n\
-	bl	" #fixup_name ",%r2					    \n\
-	copy	%r21,%r19	/* delay slot, set fixup func ltp */	    \n\
-									    \n\
-	ldwm	-64(%sp),%sp						    \n\
-	/* Arguments. */						    \n\
-	ldw	-36(%sp),%r26						    \n\
-	ldw	-40(%sp),%r25						    \n\
-	ldw	-44(%sp),%r24						    \n\
-	ldw	-48(%sp),%r23						    \n\
-	/* Return pointer. */						    \n\
-	ldw	-20(%sp),%r2						    \n\
-	/* Call the real function. */					    \n\
-	ldw	0(%r28),%r22						    \n\
-	bv	%r0(%r22)						    \n\
-	ldw	4(%r28),%r19						    \n\
-");
-
+  asm (".globl " #tramp_name "\n"					\
+ "	.type " #tramp_name ",@function\n"				\
+  #tramp_name ":\n"							\
+ 	/* Save return pointer */					\
+ "	stw	%r2,-20(%sp)\n"						\
+ 	/* Save argument registers in the call stack frame. */		\
+ "	stw	%r26,-36(%sp)\n"					\
+ "	stw	%r25,-40(%sp)\n"					\
+ "	stw	%r24,-44(%sp)\n"					\
+ "	stw	%r23,-48(%sp)\n"					\
+ 	/* Build a call frame, and save structure pointer. */		\
+ "	stwm	%r28,64(%sp)\n"						\
+ 									\
+ 	/* Set up args to fixup func.  */				\
+ "	ldw	8+4(%r20),%r26\n" /* got[1] == struct link_map *  */	\
+ "	copy	%r19,%r25\n"	  /* reloc offset  */			\
+ 									\
+ 	/* Call the real address resolver. */				\
+ "	bl	" #fixup_name ",%r2\n"					\
+ "	copy	%r21,%r19\n"	  /* delay slot, set fixup func ltp */	\
+ 									\
+ "	ldw	0(%r28),%r22\n"	  /* load up the returned func ptr */	\
+ "	ldw	4(%r28),%r19\n"						\
+ "	ldwm	-64(%sp),%r28\n"					\
+ 	/* Arguments. */						\
+ "	ldw	-36(%sp),%r26\n"					\
+ "	ldw	-40(%sp),%r25\n"					\
+ "	ldw	-44(%sp),%r24\n"					\
+ "	ldw	-48(%sp),%r23\n"					\
+ 	/* Call the real function. */					\
+ "	bv	%r0(%r22)\n"						\
+ 	/* Return pointer. */						\
+ "	ldw	-20(%sp),%r2\n"						\
+        );
+  
 #ifndef PROF
 #define ELF_MACHINE_RUNTIME_TRAMPOLINE			\
   TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);	\
@@ -570,15 +568,15 @@
 	   probably haven't relocated the necessary values by this
 	   point so we have to find them ourselves. */
 
-	asm ("bl	0f,%0						    \n\
-	      depi	0,31,2,%0					    \n\
-0:	      addil	L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0	    \n\
-	      ldo	R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1   \n\
-	      addil	L'__fptr_root - ($PIC_pcrel$0 - 16),%0		    \n\
-	      ldo	R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2	    \n\
-	      addil	L'__fptr_count - ($PIC_pcrel$0 - 24),%0		    \n\
-	      ldo	R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
-	     :
+ 	asm ("bl	0f,%0\n\t"
+ 	     "depi	0,31,2,%0\n\t"
+ 	     "0:\taddil	L'__boot_ldso_fptr - ($PIC_pcrel$0 - 8),%0\n\t"
+ 	     "ldo	R'__boot_ldso_fptr - ($PIC_pcrel$0 - 12)(%%r1),%1\n\t"
+ 	     "addil	L'__fptr_root - ($PIC_pcrel$0 - 16),%0\n\t"
+ 	     "ldo	R'__fptr_root - ($PIC_pcrel$0 - 20)(%%r1),%2\n\t"
+ 	     "addil	L'__fptr_count - ($PIC_pcrel$0 - 24),%0\n\t"
+ 	     "ldo	R'__fptr_count - ($PIC_pcrel$0 - 28)(%%r1),%3"
+  	     :
 	     "=r" (dot),
 	     "=r" (p_boot_ldso_fptr),
 	     "=r" (p_fptr_root),

--l5oECiFRo5dp+2y7--