* 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:
parent
c843e065a1
commit
1d0ad77362
14
ChangeLog
14
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
17
elf/elf.h
17
elf/elf.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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) \
|
||||
{ \
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue