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

[commits] r1546 - in /branches/eglibc-2_5/ports: ChangeLog.eglibc sysdeps/mips/dl-machine.h



Author: richard
Date: Thu Feb 22 06:39:25 2007
New Revision: 1546

Log:
	Backport from mainline:

	2007-01-08  Richard Sandiford  <richard@xxxxxxxxxxxxxxxx>

	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NO_RELA): Delete.
	(elf_machine_reloc): New function, retaining the body of
	elf_machine_rel.  Take the reloc's r_info field as an argument,
	not the reloc itself.  Add extra r_addend and inplace_p arguments.
	When inplace_p is false, use r_addend as the addend, not the contents
	of the relocation field.  Hoist the conversion of reloc_addr to
	"ELFW(Addr) *".  Don't try to apply TLS relocations against
	undefined symbols.  Add R_MIPS_GLOB_DAT support.
	(elf_machine_rel, elf_machine_rela): Use elf_machine_reloc.
	(elf_machine_lazy_rel): Change the reloc type from ElfW(Rel)
	to ElfW(Rela).

Modified:
    branches/eglibc-2_5/ports/ChangeLog.eglibc
    branches/eglibc-2_5/ports/sysdeps/mips/dl-machine.h

Modified: branches/eglibc-2_5/ports/ChangeLog.eglibc
==============================================================================
--- branches/eglibc-2_5/ports/ChangeLog.eglibc (original)
+++ branches/eglibc-2_5/ports/ChangeLog.eglibc Thu Feb 22 06:39:25 2007
@@ -1,3 +1,21 @@
+2007-02-22  Richard Sandiford  <richard@xxxxxxxxxxxxxxxx>
+
+	Backport from mainline:
+
+	2007-01-08  Richard Sandiford  <richard@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/mips/dl-machine.h (ELF_MACHINE_NO_RELA): Delete.
+	(elf_machine_reloc): New function, retaining the body of
+	elf_machine_rel.  Take the reloc's r_info field as an argument,
+	not the reloc itself.  Add extra r_addend and inplace_p arguments.
+	When inplace_p is false, use r_addend as the addend, not the contents
+	of the relocation field.  Hoist the conversion of reloc_addr to
+	"ELFW(Addr) *".  Don't try to apply TLS relocations against
+	undefined symbols.  Add R_MIPS_GLOB_DAT support.
+	(elf_machine_rel, elf_machine_rela): Use elf_machine_reloc.
+	(elf_machine_lazy_rel): Change the reloc type from ElfW(Rel)
+	to ElfW(Rela).
+
 2007-02-05  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
 
 	Backport from trunk:

Modified: branches/eglibc-2_5/ports/sysdeps/mips/dl-machine.h
==============================================================================
--- branches/eglibc-2_5/ports/sysdeps/mips/dl-machine.h (original)
+++ branches/eglibc-2_5/ports/sysdeps/mips/dl-machine.h Thu Feb 22 06:39:25 2007
@@ -282,9 +282,6 @@
 	".previous"\
 );
 
-/* The MIPS never uses Elfxx_Rela relocations.  */
-#define ELF_MACHINE_NO_RELA 1
-
 /* Names of the architecture-specific auditing callback functions.  */
 # if _MIPS_SIM == _ABIO32
 #  define ARCH_LA_PLTENTER mips_o32_gnu_pltenter
@@ -301,16 +298,18 @@
 
 #ifdef RESOLVE_MAP
 
-/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+/* Perform a relocation described by R_INFO at the location pointed to
+   by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
    MAP is the object containing the reloc.  */
 
 auto inline void
 __attribute__ ((always_inline))
-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
-		 const ElfW(Sym) *sym, const struct r_found_version *version,
-		 void *const reloc_addr)
-{
-  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
+elf_machine_reloc (struct link_map *map, ElfW(Word) r_info,
+		   const ElfW(Sym) *sym, const struct r_found_version *version,
+		   void *reloc_addr, ElfW(Addr) r_addend, int inplace_p)
+{
+  const unsigned long int r_type = ELFW(R_TYPE) (r_info);
+  ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
 
 #if !defined RTLD_BOOTSTRAP && !defined SHARED
   /* This is defined in rtld.c, but nowhere in the static libc.a;
@@ -342,18 +341,28 @@
 	  case R_MIPS_TLS_DTPMOD64:
 	  case R_MIPS_TLS_DTPMOD32:
 	    if (sym_map)
-	      *(ElfW(Addr) *)reloc_addr = sym_map->l_tls_modid;
+	      *addr_field = sym_map->l_tls_modid;
 	    break;
 
 	  case R_MIPS_TLS_DTPREL64:
 	  case R_MIPS_TLS_DTPREL32:
-	    *(ElfW(Addr) *)reloc_addr += TLS_DTPREL_VALUE (sym);
+	    if (sym)
+	      {
+		if (inplace_p)
+		  r_addend = *addr_field;
+		*addr_field = r_addend + TLS_DTPREL_VALUE (sym);
+	      }
 	    break;
 
 	  case R_MIPS_TLS_TPREL32:
 	  case R_MIPS_TLS_TPREL64:
-	    CHECK_STATIC_TLS (map, sym_map);
-	    *(ElfW(Addr) *)reloc_addr += TLS_TPREL_VALUE (sym_map, sym);
+	    if (sym)
+	      {
+		CHECK_STATIC_TLS (map, sym_map);
+		if (inplace_p)
+		  r_addend = *addr_field;
+		*addr_field = r_addend + TLS_TPREL_VALUE (sym_map, sym);
+	      }
 	    break;
 	  }
 
@@ -367,13 +376,14 @@
     case R_MIPS_REL32:
 #endif
       {
-	int symidx = ELFW(R_SYM) (reloc->r_info);
+	int symidx = ELFW(R_SYM) (r_info);
 	ElfW(Addr) reloc_value;
 
-	/* Support relocations on mis-aligned offsets.  Should we ever
-	   implement RELA, this should be replaced with an assignment
-	   from reloc->r_addend.  */
-	__builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value));
+	if (inplace_p)
+	  /* Support relocations on mis-aligned offsets.  */
+	  __builtin_memcpy (&reloc_value, reloc_addr, sizeof (reloc_value));
+	else
+	  reloc_value = r_addend;
 
 	if (symidx)
 	  {
@@ -424,6 +434,31 @@
 	__builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
       }
       break;
+#ifndef RTLD_BOOTSTRAP
+#if _MIPS_SIM == _ABI64
+    case (R_MIPS_64 << 8) | R_MIPS_GLOB_DAT:
+#else
+    case R_MIPS_GLOB_DAT:
+#endif
+      {
+	int symidx = ELFW(R_SYM) (r_info);
+	const ElfW(Word) gotsym
+	  = (const ElfW(Word)) map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
+
+	if (__builtin_expect ((ElfW(Word)) symidx >= gotsym, 1))
+	  {
+	    const ElfW(Addr) *got
+	      = (const ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
+	    const ElfW(Word) local_gotno
+	      = ((const ElfW(Word))
+		 map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val);
+
+	    ElfW(Addr) reloc_value = got[symidx + local_gotno - gotsym];
+	    __builtin_memcpy (reloc_addr, &reloc_value, sizeof (reloc_value));
+	  }
+      }
+      break;
+#endif
     case R_MIPS_NONE:		/* Alright, Wilbur.  */
       break;
 #if _MIPS_SIM == _ABI64
@@ -436,7 +471,7 @@
 	 itself.  For ABI compliance, we ignore such _64 dummy
 	 relocations.  For RELA, this may be simply removed, since
 	 it's totally unnecessary.  */
-      if (ELFW(R_SYM) (reloc->r_info) == 0)
+      if (ELFW(R_SYM) (r_info) == 0)
 	break;
       /* Fall through.  */
 #endif
@@ -446,6 +481,18 @@
     }
 }
 
+/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
+   MAP is the object containing the reloc.  */
+
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
+		 const ElfW(Sym) *sym, const struct r_found_version *version,
+		 void *const reloc_addr)
+{
+  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1);
+}
+
 auto inline void
 __attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
@@ -457,7 +504,7 @@
 auto inline void
 __attribute__((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc)
+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc)
 {
   /* Do nothing.  */
 }
@@ -468,6 +515,8 @@
 		  const ElfW(Sym) *sym, const struct r_found_version *version,
 		 void *const reloc_addr)
 {
+  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr,
+		     reloc->r_addend, 0);
 }
 
 auto inline void