[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH] glibc 2.2.94 - hppa - revised plt relocation patch



libc-alpha,

This is a revised version of the previously posted plt relocation
patch. While Jakub has posted some comments about the semantic
correctness of the types of relocations, I still believe that this
patch is a good start. The implementation is still open to change 
when the required work in binutils is completed.

Thanks to H. J. Lu for a similar idea:
http://sources.redhat.com/ml/libc-alpha/2002-09/msg00451.html

Cheers,

c.

---

2002-09-25  Alan Modra  <amodra@bigpond.net.au>

	* elf/do-rel.h:
	Define macro DO_ELF_MACHINE_REL_RELATIVE
	for 'elf_machine_rel_relative' 
	(elf_dynamic_do_rel): Call DO_ELF_MACHINE_REL_RELATIVE
	macro instead of 'elf_machine_rel_relative'
	* sysdeps/hppa/dl-machine.h:
	Define macro DO_ELF_MACHINE_REL_RELATIVE for
	'elf_machine_rel_relative' with extra map parameter
	required by HPPA.
	(elf_machine_rela_relative): Add plt relocation 
	changes.

diff -urN  libc/elf/do-rel.h libc/elf/do-rel.h
--- libc/elf/do-rel.h	18 Sep 2002 18:28:43 -0000
+++ libc/elf/do-rel.h	23 Sep 2002 11:35:14 -0000
@@ -30,6 +30,12 @@
 # define RELCOUNT_IDX			VERSYMIDX (DT_RELCOUNT)
 #endif
 
+#ifndef DO_ELF_MACHINE_REL_RELATIVE
+#define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, reloc)			\
+  elf_machine_rel_relative (l_addr, reloc,				\
+			    (void *) (l_addr + relative->r_offset))
+#endif
+
 #ifndef VERSYMIDX
 # define VERSYMIDX(sym)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
 #endif
@@ -96,8 +102,7 @@ elf_dynamic_do_rel (struct link_map *map
 # endif
 #endif
 	  for (; relative < r; ++relative)
-	    elf_machine_rel_relative (l_addr, relative,
-				      (void *) (l_addr + relative->r_offset));
+	    DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
 
 #ifdef RTLD_BOOTSTRAP
       /* The dynamic linker always uses versioning.  */
@@ -130,4 +135,5 @@ elf_dynamic_do_rel (struct link_map *map
 #undef Rel
 #undef elf_machine_rel
 #undef elf_machine_rel_relative
+#undef DO_ELF_MACHINE_REL_RELATIVE
 #undef RELCOUNT_IDX
diff -urN libc/sysdeps/hppa/dl-machine.h libc/sysdeps/hppa/dl-machine.h
--- libc/sysdeps/hppa/dl-machine.h	20 Jun 2002 06:23:14 -0000
+++ libc/sysdeps/hppa/dl-machine.h	23 Sep 2002 11:35:15 -0000
@@ -628,11 +628,55 @@ elf_machine_rela (struct link_map *map, 
   *reloc_addr = value;
 }
 
+#define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, reloc)			\
+  elf_machine_rel_relative (map, l_addr, reloc,				\
+			    (void *) (l_addr + relative->r_offset))
+
+/* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with
+   ELF32_R_SYM (info) == 0 for a similar purpose.  */
 static inline void
-elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
+elf_machine_rela_relative (struct link_map *map, Elf32_Addr l_addr,
+			   const Elf32_Rela *reloc,
 			   Elf32_Addr *const reloc_addr)
 {
-  /* XXX Nothing to do.  There is no relative relocation, right?  */
+  unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
+  Elf32_Addr value;
+
+  value = l_addr + reloc->r_addend;
+
+  if (ELF32_R_SYM (reloc->r_info) != 0)
+    asm volatile ("iitlbp	%r0,(%r0)");  /* Crash. */
+
+  switch (r_type)
+    {
+    case R_PARISC_DIR32:
+      /* .eh_frame can have unaligned relocs.  */
+      if ((unsigned long) reloc_addr & 3)
+	{
+	  char *rel_addr = (char *) reloc_addr;
+	  rel_addr[0] = value >> 24;
+	  rel_addr[1] = value >> 16;
+	  rel_addr[2] = value >> 8;
+	  rel_addr[3] = value;
+	  return;
+	}
+      break;
+
+    case R_PARISC_PLABEL32:
+      break;
+
+    case R_PARISC_IPLT:
+      elf_machine_fixup_plt (NULL, map, reloc, reloc_addr, value);
+      return;
+
+    case R_PARISC_NONE:
+      return;
+
+    default:
+      _dl_reloc_bad_type (map, r_type, 0);
+    }
+
+  *reloc_addr = value;
 }
 
 static inline void


Reply to: