* elf/dl-lookup.c (_dl_debug_bindings): Print TLS lookups always.
authorRoland McGrath <roland@gnu.org>
Wed, 18 Sep 2002 01:18:08 +0000 (01:18 +0000)
committerRoland McGrath <roland@gnu.org>
Wed, 18 Sep 2002 01:18:08 +0000 (01:18 +0000)
* 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.

ChangeLog
elf/dl-lookup.c
elf/elf.h
linuxthreads/ChangeLog
linuxthreads/sysdeps/i386/tls.h
linuxthreads/sysdeps/i386/useldt.h
sysdeps/i386/dl-machine.h

index e54b612..ca3ebb7 100644 (file)
--- 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
index 6f14aaf..e2f5506 100644 (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);
        }
     }
index 2edf8e0..b664c5d 100644 (file)
--- 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
 
index fd23cff..40913b6 100644 (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...
index a0c8227..7715303 100644 (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;                                     \
index 2b30caf..31893b4 100644 (file)
 
    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)                                          \
        {                                                                     \
index 8f17441..1784a3a 100644 (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
@@ -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: