[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
- To: commits@xxxxxxxxxx
- Subject: [commits] r1546 - in /branches/eglibc-2_5/ports: ChangeLog.eglibc sysdeps/mips/dl-machine.h
- From: richard@xxxxxxxxxx
- Date: Thu, 22 Feb 2007 14:39:25 -0000
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