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.
This commit is contained in:
Roland McGrath 2003-04-24 17:10:52 +00:00
parent 345d920835
commit 545dbc9345
4 changed files with 80 additions and 64 deletions

View file

@ -41,8 +41,8 @@
the static TLS area already allocated for each running thread. If this
object's TLS segment is too big to fit, we fail. If it fits,
we set MAP->l_tls_offset and return. */
static void __attribute_noinline__
allocate_static_tls (struct link_map *map)
void __attribute_noinline__
_dl_allocate_static_tls (struct link_map *map)
{
size_t offset, used, check;
@ -209,7 +209,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
#define CHECK_STATIC_TLS(map, sym_map) \
do { \
if (__builtin_expect ((sym_map)->l_tls_offset == 0, 0)) \
allocate_static_tls (sym_map); \
_dl_allocate_static_tls (sym_map); \
} while (0)
#include "dynamic-link.h"

View file

@ -795,6 +795,9 @@ rtld_hidden_proto (_dl_allocate_tls)
extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
internal_function;
extern void _dl_allocate_static_tls (struct link_map *map)
internal_function attribute_hidden;
/* These are internal entry points to the two halves of _dl_allocate_tls,
only used within rtld.c itself at startup time. */
extern void *_dl_allocate_tls_storage (void)

View file

@ -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;

View file

@ -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);
}
}