aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/powerpc32
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-04-24 17:10:52 +0000
committerRoland McGrath <roland@gnu.org>2003-04-24 17:10:52 +0000
commit545dbc9345c81963ee3b48b0104807f06fda7b28 (patch)
treea881f7258fe383ddf1c20e0ca4f1e28f28f70ad1 /sysdeps/powerpc/powerpc32
parent345d920835ed818a09cf242da31adf7e9981f614 (diff)
downloadglibc-545dbc9345c81963ee3b48b0104807f06fda7b28.tar
glibc-545dbc9345c81963ee3b48b0104807f06fda7b28.tar.gz
glibc-545dbc9345c81963ee3b48b0104807f06fda7b28.tar.bz2
glibc-545dbc9345c81963ee3b48b0104807f06fda7b28.zip
2003-04-24 Jakub Jelinek <jakub@redhat.com>
* elf/dl-reloc.c (allocate_static_tls): Rename to... (_dl_allocate_static_tls): ... this function. No longer static. (CHECK_STATIC_TLS): Adjust. * sysdeps/generic/ldsodefs.h (_dl_allocate_static_tls): New prototype. * sysdeps/powerpc/powerpc32/dl-machine.h (__process_machine_rela): Add SYM_MAP argument. (elf_machine_rela): Adjust caller. Declare SYM_MAP unconditionally. Check if SYM_MAP != NULL for R_PPC_DTPREL32. Only handle 32-bit TLS relocs here. #ifdef out relocs which never appear in .gnu.conflict section from dl-conflict.c processing. * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela): Add SYM_MAP argument. Handle 16-bit TLS relocs here.
Diffstat (limited to 'sysdeps/powerpc/powerpc32')
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c48
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h87
2 files changed, 74 insertions, 61 deletions
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 866380a940..2e071c85af 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -397,6 +397,7 @@ _dl_reloc_overflow (struct link_map *map,
void
__process_machine_rela (struct link_map *map,
const Elf32_Rela *reloc,
+ struct link_map *sym_map,
const Elf32_Sym *sym,
const Elf32_Sym *refsym,
Elf32_Addr *const reloc_addr,
@@ -541,6 +542,53 @@ __process_machine_rela (struct link_map *map,
}
break;
+#ifdef USE_TLS
+#define CHECK_STATIC_TLS(map, sym_map) \
+ do { \
+ if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0)) \
+ _dl_allocate_static_tls (sym_map); \
+ } while (0)
+# define DO_TLS_RELOC(suffix) \
+ case R_PPC_DTPREL##suffix: \
+ /* During relocation all TLS symbols are defined and used. \
+ Therefore the offset is already correct. */ \
+ if (sym_map != NULL) \
+ do_reloc##suffix ("R_PPC_DTPREL"#suffix, \
+ TLS_DTPREL_VALUE (sym, reloc)); \
+ break; \
+ case R_PPC_TPREL##suffix: \
+ if (sym_map != NULL) \
+ { \
+ CHECK_STATIC_TLS (map, sym_map); \
+ do_reloc##suffix ("R_PPC_TPREL"#suffix, \
+ TLS_TPREL_VALUE (sym_map, sym, reloc)); \
+ } \
+ break;
+
+ inline void do_reloc16 (const char *r_name, Elf32_Addr value)
+ {
+ if (__builtin_expect (value > 0x7fff && value < 0xffff8000, 0))
+ _dl_reloc_overflow (map, r_name, reloc_addr, sym, refsym);
+ *(Elf32_Half *) reloc_addr = value;
+ }
+ inline void do_reloc16_LO (const char *r_name, Elf32_Addr value)
+ {
+ *(Elf32_Half *) reloc_addr = value;
+ }
+ inline void do_reloc16_HI (const char *r_name, Elf32_Addr value)
+ {
+ *(Elf32_Half *) reloc_addr = value >> 16;
+ }
+ inline void do_reloc16_HA (const char *r_name, Elf32_Addr value)
+ {
+ *(Elf32_Half *) reloc_addr = (value + 0x8000) >> 16;
+ }
+ DO_TLS_RELOC (16)
+ DO_TLS_RELOC (16_LO)
+ DO_TLS_RELOC (16_HI)
+ DO_TLS_RELOC (16_HA)
+#endif
+
default:
_dl_reloc_bad_type (map, rinfo, 0);
return;
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 2f35275af9..e26c2d544b 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -336,6 +336,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
has been determined. */
extern void __process_machine_rela (struct link_map *map,
const Elf32_Rela *reloc,
+ struct link_map *sym_map,
const Elf32_Sym *sym,
const Elf32_Sym *refsym,
Elf32_Addr *const reloc_addr,
@@ -361,9 +362,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
const Elf32_Sym *const refsym = sym;
Elf32_Addr value;
const int r_type = ELF32_R_TYPE (reloc->r_info);
-#if defined USE_TLS && !defined RTLD_BOOTSTRAP
- struct link_map *sym_map;
-#endif
+ struct link_map *sym_map = NULL;
#ifndef RESOLVE_CONFLICT_FIND_MAP
if (r_type == R_PPC_RELATIVE)
@@ -411,71 +410,37 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
*reloc_addr = value;
break;
-#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
- case R_PPC_DTPMOD32:
-# ifdef RTLD_BOOTSTRAP
- /* During startup the dynamic linker is always index 1. */
- *reloc_addr = 1;
-# else
- /* Get the information from the link map returned by the
- RESOLVE_MAP function. */
- if (sym_map != NULL)
- *reloc_addr = sym_map->l_tls_modid;
-# endif
- break;
-
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
+ && !defined RESOLVE_CONFLICT_FIND_MAP
# ifdef RTLD_BOOTSTRAP
# define NOT_BOOTSTRAP 0
# else
# define NOT_BOOTSTRAP 1
# endif
-# define DO_TLS_RELOC(suffix) \
- case R_PPC_DTPREL##suffix: \
- /* During relocation all TLS symbols are defined and used. \
- Therefore the offset is already correct. */ \
- if (NOT_BOOTSTRAP) \
- do_reloc##suffix ("R_PPC_DTPREL"#suffix, \
- TLS_DTPREL_VALUE (sym, reloc)); \
- break; \
- case R_PPC_TPREL##suffix: \
- if (!NOT_BOOTSTRAP || sym_map) \
- { \
- if (NOT_BOOTSTRAP) \
- CHECK_STATIC_TLS (map, sym_map); \
- do_reloc##suffix ("R_PPC_TPREL"#suffix, \
- TLS_TPREL_VALUE (sym_map, sym, reloc)); \
- } \
- break;
- inline void do_reloc32 (const char *r_name, Elf32_Addr value)
+ case R_PPC_DTPMOD32:
+ if (!NOT_BOOTSTRAP)
+ /* During startup the dynamic linker is always index 1. */
+ *reloc_addr = 1;
+ else if (sym_map != NULL)
+ /* Get the information from the link map returned by the
+ RESOLVE_MAP function. */
+ *reloc_addr = sym_map->l_tls_modid;
+ break;
+ case R_PPC_DTPREL32:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (NOT_BOOTSTRAP && sym_map != NULL)
+ *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+ break;
+ case R_PPC_TPREL32:
+ if (!NOT_BOOTSTRAP || sym_map != NULL)
{
- *reloc_addr = value;
+ if (NOT_BOOTSTRAP)
+ CHECK_STATIC_TLS (map, sym_map);
+ *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
}
- DO_TLS_RELOC (32)
-# ifndef RTLD_BOOTSTRAP /* PIC code like ld.so doesn't use these. */
- inline void do_reloc16 (const char *r_name, Elf32_Addr value)
- {
- if (__builtin_expect (value > 0x7fff && value < 0xffff8000, 0))
- _dl_reloc_overflow (map, "R_PPC_ADDR16", reloc_addr, sym, refsym);
- *(Elf32_Half *) reloc_addr = value;
- }
- inline void do_reloc16_LO (const char *r_name, Elf32_Addr value)
- {
- *(Elf32_Half *) reloc_addr = value;
- }
- inline void do_reloc16_HI (const char *r_name, Elf32_Addr value)
- {
- *(Elf32_Half *) reloc_addr = value >> 16;
- }
- inline void do_reloc16_HA (const char *r_name, Elf32_Addr value)
- {
- *(Elf32_Half *) reloc_addr = (value + 0x8000) >> 16;
- }
- DO_TLS_RELOC (16)
- DO_TLS_RELOC (16_LO)
- DO_TLS_RELOC (16_HI)
- DO_TLS_RELOC (16_HA)
-# endif
+ break;
#endif /* USE_TLS etc. */
#ifdef RESOLVE_CONFLICT_FIND_MAP
@@ -485,7 +450,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
#endif
default:
- __process_machine_rela (map, reloc, sym, refsym,
+ __process_machine_rela (map, reloc, sym_map, sym, refsym,
reloc_addr, value, r_type);
}
}