aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--elf/dl-lookup.c16
-rw-r--r--elf/elf.h17
-rw-r--r--linuxthreads/ChangeLog7
-rw-r--r--linuxthreads/sysdeps/i386/tls.h8
-rw-r--r--linuxthreads/sysdeps/i386/useldt.h26
-rw-r--r--sysdeps/i386/dl-machine.h38
7 files changed, 82 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index e54b612eab..ca3ebb7cbf 100644
--- a/ChangeLog
+++ b/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
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 6f14aaf498..e2f5506030 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -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);
}
}
diff --git a/elf/elf.h b/elf/elf.h
index 2edf8e081b..b664c5d279 100644
--- a/elf/elf.h
+++ b/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
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index fd23cfff66..40913b630b 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -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...
diff --git a/linuxthreads/sysdeps/i386/tls.h b/linuxthreads/sysdeps/i386/tls.h
index a0c822759f..7715303d95 100644
--- a/linuxthreads/sysdeps/i386/tls.h
+++ b/linuxthreads/sysdeps/i386/tls.h
@@ -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; \
diff --git a/linuxthreads/sysdeps/i386/useldt.h b/linuxthreads/sysdeps/i386/useldt.h
index 2b30cafa9e..31893b4013 100644
--- a/linuxthreads/sysdeps/i386/useldt.h
+++ b/linuxthreads/sysdeps/i386/useldt.h
@@ -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) \
{ \
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 8f17441dd8..1784a3a737 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -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
@@ -446,6 +447,18 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
*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 */
#ifndef RTLD_BOOTSTRAP
@@ -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: