* elf/dl-lookup.c (_dl_debug_bindings): Print TLS lookups always.

* elf/elf.h (R_386_TLS_TPOFF, R_386_TLS_IE, R_386_TLS_GOTIE,
	R_386_TLS_LE): Define.
	(R_386_TLS_IE_32, R_386_TLS_LE_32, R_386_TLS_TPOFF32): Update
	comments.
	* sysdeps/i386/dl-machine.h (elf_machine_type_class): Return
	ELF_RTYPE_CLASS_PLT for R_386_TLS_TPOFF.
	(elf_machine_rel): Handle R_386_TLS_TPOFF.
	(elf_machine_rela): Likewise.
	Remove unnecessary RTLD_BOOTSTRAP #ifdefs.
This commit is contained in:
Roland McGrath 2002-09-18 01:18:08 +00:00
parent c843e065a1
commit 1d0ad77362
7 changed files with 82 additions and 44 deletions

View File

@ -1,3 +1,17 @@
2002-09-17 Jakub Jelinek <jakub@redhat.com>
* elf/dl-lookup.c (_dl_debug_bindings): Print TLS lookups always.
* elf/elf.h (R_386_TLS_TPOFF, R_386_TLS_IE, R_386_TLS_GOTIE,
R_386_TLS_LE): Define.
(R_386_TLS_IE_32, R_386_TLS_LE_32, R_386_TLS_TPOFF32): Update
comments.
* sysdeps/i386/dl-machine.h (elf_machine_type_class): Return
ELF_RTYPE_CLASS_PLT for R_386_TLS_TPOFF.
(elf_machine_rel): Handle R_386_TLS_TPOFF.
(elf_machine_rela): Likewise.
Remove unnecessary RTLD_BOOTSTRAP #ifdefs.
2002-09-17 Roland McGrath <roland@redhat.com>
* malloc/Makefile ($(objpfx)memusagestat.o: sysincludes): Define

View File

@ -647,9 +647,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
conflict = 1;
}
#ifdef USE_TLS
if (value->s
&& (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
== STT_TLS, 0)))
type_class = 4;
#endif
if (conflict
|| GL(dl_trace_prelink_map) == undef_map
|| GL(dl_trace_prelink_map) == NULL)
|| GL(dl_trace_prelink_map) == NULL
|| type_class == 4)
{
_dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ",
conflict ? "conflict" : "lookup",
@ -668,12 +676,6 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
(int) sizeof (ElfW(Addr)) * 2,
(ElfW(Addr)) (val.s ? val.s->st_value : 0));
#ifdef USE_TLS
if (value->s
&& (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
== STT_TLS, 0)))
type_class = 4;
#endif
_dl_printf ("/%x %s\n", type_class, undef_name);
}
}

View File

@ -1073,6 +1073,13 @@ typedef struct
#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
#define R_386_32PLT 11
#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */
#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS
block offset */
#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block
offset */
#define R_386_TLS_LE 17 /* Offset relative to static TLS
block */
#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of
general dynamic thread local data */
#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of
@ -1095,13 +1102,13 @@ typedef struct
__tls_get_addr() in LDM code */
#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */
#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */
#define R_386_TLS_IE_32 33 /* GOT entry for static TLS block
offset */
#define R_386_TLS_LE_32 34 /* Offset relative to static TLS
block */
#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS
block offset */
#define R_386_TLS_LE_32 34 /* Negated offset relative to static
TLS block */
#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
#define R_386_TLS_TPOFF32 37 /* Offset in static TLS block */
#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
/* Keep this the last entry. */
#define R_386_NUM 38

View File

@ -1,3 +1,10 @@
2002-09-17 Roland McGrath <roland@redhat.com>
* sysdeps/i386/tls.h (TLS_DO_MODIFY_LDT, TLS_DO_SET_THREAD_AREA):
Set the descriptor limit to the full 4GB, so %gs:OFFSET works for any
offset (positive or negative) relative to the thread struct.
* sysdeps/i386/useldt.h (DO_MODIFY_LDT, DO_SET_THREAD_AREA): Likewise.
2002-09-12 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/sparc/sparc64/Makefile: Move...

View File

@ -99,8 +99,8 @@ typedef struct
# define TLS_DO_MODIFY_LDT(descr, nr) \
({ \
struct modify_ldt_ldt_s ldt_entry = \
{ nr, (unsigned long int) (descr), sizeof (struct _pthread_descr_struct), \
1, 0, 0, 0, 0, 1, 0 }; \
{ nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
int result; \
asm volatile (TLS_LOAD_EBX \
"int $0x80\n\t" \
@ -118,8 +118,8 @@ typedef struct
# define TLS_DO_SET_THREAD_AREA(descr, secondcall) \
({ \
struct modify_ldt_ldt_s ldt_entry = \
{ -1, (unsigned long int) (descr), sizeof (struct _pthread_descr_struct), \
1, 0, 0, 0, 0, 1, 0 }; \
{ -1, (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
int result; \
if (secondcall) \
ldt_entry.entry_number = ({ int _gs; \

View File

@ -11,22 +11,22 @@
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
Boston, MA 02111-1307, USA. */
#ifndef __ASSEMBLER__
#include <stddef.h> /* For offsetof. */
#include <stdlib.h> /* For abort(). */
#include <sysdep.h> /* For INLINE_SYSCALL. */
#include <stdlib.h> /* For abort(). */
#include <sysdep.h> /* For INLINE_SYSCALL. */
/* We don't want to include the kernel header. So duplicate the
information. */
/* We don't want to include the kernel header. So duplicate the
information. */
/* Structure passed on `modify_ldt' call. */
struct modify_ldt_ldt_s
@ -63,13 +63,13 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
})
/* Initialize the thread-unique value. Two possible ways to do it. */
/* Initialize the thread-unique value. Two possible ways to do it. */
#define DO_MODIFY_LDT(descr, nr) \
({ \
struct modify_ldt_ldt_s ldt_entry = \
{ nr, (unsigned long int) descr, sizeof (struct _pthread_descr_struct), \
1, 0, 0, 0, 0, 1, 0 }; \
{ nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
if (__modify_ldt (1, &ldt_entry, sizeof (ldt_entry)) != 0) \
abort (); \
asm ("movw %w0, %%gs" : : "q" (nr * 8 + 7)); \
@ -93,8 +93,8 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
asm ("movw %%gs, %w0" : "=q" (__gs)); \
struct modify_ldt_ldt_s ldt_entry = \
{ (__gs & 0xffff) >> 3, \
(unsigned long int) descr, sizeof (struct _pthread_descr_struct), \
1, 0, 0, 0, 0, 1, 0 }; \
(unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry), \
0) == 0) \
asm ("movw %w0, %%gs" :: "q" (__gs)); \
@ -105,8 +105,8 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
{ \
struct modify_ldt_ldt_s ldt_entry = \
{ -1, \
(unsigned long int) descr, sizeof (struct _pthread_descr_struct), \
1, 0, 0, 0, 0, 1, 0 }; \
(unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry), \
0) == 0) \
{ \

View File

@ -302,7 +302,8 @@ _dl_start_user:\n\
#ifdef USE_TLS
# define elf_machine_type_class(type) \
((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32 \
|| (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32) \
|| (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32 \
|| (type) == R_386_TLS_TPOFF) \
* ELF_RTYPE_CLASS_PLT) \
| (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY))
#else
@ -444,6 +445,18 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
block we subtract the offset from that of the TLS block. */
if (sym != NULL)
*reloc_addr += sym_map->l_tls_offset - sym->st_value;
# endif
break;
case R_386_TLS_TPOFF:
/* The offset is negative, forward from the thread pointer. */
# ifdef RTLD_BOOTSTRAP
*reloc_addr += sym->st_value - map->l_tls_offset;
# else
/* We know the offset of object the symbol is contained in.
It is a negative value which will be added to the
thread pointer. */
if (sym != NULL)
*reloc_addr += sym->st_value - sym_map->l_tls_offset;
# endif
break;
#endif /* use TLS */
@ -517,31 +530,18 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
#ifdef USE_TLS
case R_386_TLS_DTPMOD32:
# ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always the module
with index 1.
XXX If this relocation is necessary move before RESOLVE
call. */
*reloc_addr = 1;
# else
/* Get the information from the link map returned by the
resolv function. */
if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid;
# endif
break;
case R_386_TLS_DTPOFF32:
# ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */
*reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
# endif
break;
case R_386_TLS_TPOFF32:
/* The offset is positive, backward from the thread pointer. */
# ifdef RTLD_BOOTSTRAP
*reloc_addr = map->l_tls_offset - sym->st_value + reloc->r_addend;
# else
/* We know the offset of object the symbol is contained in.
It is a positive value which will be subtracted from the
thread pointer. To get the variable position in the TLS
@ -549,7 +549,15 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
*reloc_addr
= (sym == NULL ? 0 : sym_map->l_tls_offset - sym->st_value)
+ reloc->r_addend;
# endif
break;
case R_386_TLS_TPOFF:
/* The offset is negative, forward from the thread pointer. */
/* We know the offset of object the symbol is contained in.
It is a negative value which will be added to the
thread pointer. */
*reloc_addr
= (sym == NULL ? 0 : sym->st_value - sym_map->l_tls_offset)
+ reloc->r_addend;
break;
#endif /* use TLS */
default: