From 37e55690c4f22ba8d0a24fb9a3ccbb1515e49790 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 19 Sep 2002 19:01:18 +0000 Subject: [PATCH] bfd/ * reloc.c (BFD_RELOC_386_TLS_TPOFF, BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE): Add. * bfd-in2.h, libbfd.h: Rebuilt. * elf32-i386.c (elf_howto_table): Add R_386_TLS_TPOFF, R_386_TLS_IE and R_386_TLS_GOTIE. (elf_i386_reloc_type_lookup): Handle it. (struct elf_i386_link_hash_entry): Change tls_type type to unsigned char instead of enum, change GOT_* into defines. (GOT_TLS_IE_POS, GOT_TLS_IE_NEG, GOT_TLS_IE_BOTH): Define. (elf_i386_tls_transition): Handle R_386_TLS_IE and R_386_TLS_GOTIE. (elf_i386_check_relocs): Likewise. Avoid crash if local symbol is accessed both as normal and TLS symbol. Move R_386_TLS_LDM and R_386_PLT32 cases so that R_386_TLS_IE can fall through. Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs. (elf_i386_gc_sweep_hook): Handle R_386_TLS_IE and R_386_TLS_GOTIE. Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs. (allocate_dynrelocs): Allocate 2 .got and 2 .rel.got entries if tls_type is GOT_TLS_IE_BOTH. (elf_i386_size_dynamic_sections): Likewise. (elf_i386_relocate_section): Handle R_386_TLS_IE and R_386_TLS_GOTIE. Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs. (elf_i386_finish_dynamic_symbol): Use tls_type & GOT_TLS_IE to catch all 4 GOT_TLS_* TLS types. gas/ * config/tc-i386.c (tc_i386_fix_adjustable): Handle BFD_RELOC_386_TLS_IE and BFD_RELOC_386_TLS_GOTIE. (BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE): Define to 0 if not defined. (lex_got): Handle @GOTNTPOFF and @INDNTPOFF. (md_apply_fix3, tc_gen_reloc): Handle BFD_RELOC_386_TLS_IE and BFD_RELOC_386_TLS_GOTIE. gas/testsuite/ * gas/i386/tlspic.s: Add tests. * gas/i386/tlspic.d: Regenerated. * gas/i386/tlsnopic.s: Add tests. * gas/i386/tlsnopic.d: Regenerated. include/ * elf/i386.h (R_386_TLS_TPOFF, R_386_TLS_IE, R_386_TLS_GOTIE): Define. ld/testsuite/ * ld-i386/i386.exp: New. * ld-i386/tlsbin.dd: New test. * ld-i386/tlsbinpic.s: New test. * ld-i386/tlsbin.rd: New test. * ld-i386/tlsbin.s: New test. * ld-i386/tlsbin.sd: New test. * ld-i386/tlsbin.td: New test. * ld-i386/tlslib.s: New test. * ld-i386/tlsnopic1.s: New test. * ld-i386/tlsnopic2.s: New test. * ld-i386/tlsnopic.dd: New test. * ld-i386/tlsnopic.rd: New test. * ld-i386/tlsnopic.sd: New test. * ld-i386/tlspic1.s: New test. * ld-i386/tlspic2.s: New test. * ld-i386/tlspic.dd: New test. * ld-i386/tlspic.rd: New test. * ld-i386/tlspic.sd: New test. * ld-i386/tlspic.td: New test. --- bfd/ChangeLog | 26 ++ bfd/bfd-in2.h | 3 + bfd/elf32-i386.c | 371 +++++++++++++++++++----- bfd/libbfd.h | 3 + bfd/reloc.c | 6 + gas/ChangeLog | 10 + gas/config/tc-i386.c | 10 + gas/testsuite/ChangeLog | 7 + gas/testsuite/gas/i386/tlsnopic.d | 8 +- gas/testsuite/gas/i386/tlsnopic.s | 31 +- gas/testsuite/gas/i386/tlspic.d | 13 +- gas/testsuite/gas/i386/tlspic.s | 14 +- include/ChangeLog | 5 + include/elf/i386.h | 5 +- ld/testsuite/ChangeLog | 22 ++ ld/testsuite/ld-i386/i386.exp | 181 ++++++++++++ ld/testsuite/ld-i386/tlsbin.dd | 456 ++++++++++++++++++++++++++++++ ld/testsuite/ld-i386/tlsbin.rd | 167 +++++++++++ ld/testsuite/ld-i386/tlsbin.s | 165 +++++++++++ ld/testsuite/ld-i386/tlsbin.sd | 14 + ld/testsuite/ld-i386/tlsbin.td | 16 ++ ld/testsuite/ld-i386/tlsbinpic.s | 168 +++++++++++ ld/testsuite/ld-i386/tlslib.s | 17 ++ ld/testsuite/ld-i386/tlsnopic.dd | 161 +++++++++++ ld/testsuite/ld-i386/tlsnopic.rd | 133 +++++++++ ld/testsuite/ld-i386/tlsnopic.sd | 13 + ld/testsuite/ld-i386/tlsnopic1.s | 107 +++++++ ld/testsuite/ld-i386/tlsnopic2.s | 7 + ld/testsuite/ld-i386/tlspic.dd | 411 +++++++++++++++++++++++++++ ld/testsuite/ld-i386/tlspic.rd | 174 ++++++++++++ ld/testsuite/ld-i386/tlspic.sd | 19 ++ ld/testsuite/ld-i386/tlspic.td | 16 ++ ld/testsuite/ld-i386/tlspic1.s | 282 ++++++++++++++++++ ld/testsuite/ld-i386/tlspic2.s | 11 + 34 files changed, 2960 insertions(+), 92 deletions(-) create mode 100644 ld/testsuite/ld-i386/i386.exp create mode 100644 ld/testsuite/ld-i386/tlsbin.dd create mode 100644 ld/testsuite/ld-i386/tlsbin.rd create mode 100644 ld/testsuite/ld-i386/tlsbin.s create mode 100644 ld/testsuite/ld-i386/tlsbin.sd create mode 100644 ld/testsuite/ld-i386/tlsbin.td create mode 100644 ld/testsuite/ld-i386/tlsbinpic.s create mode 100644 ld/testsuite/ld-i386/tlslib.s create mode 100644 ld/testsuite/ld-i386/tlsnopic.dd create mode 100644 ld/testsuite/ld-i386/tlsnopic.rd create mode 100644 ld/testsuite/ld-i386/tlsnopic.sd create mode 100644 ld/testsuite/ld-i386/tlsnopic1.s create mode 100644 ld/testsuite/ld-i386/tlsnopic2.s create mode 100644 ld/testsuite/ld-i386/tlspic.dd create mode 100644 ld/testsuite/ld-i386/tlspic.rd create mode 100644 ld/testsuite/ld-i386/tlspic.sd create mode 100644 ld/testsuite/ld-i386/tlspic.td create mode 100644 ld/testsuite/ld-i386/tlspic1.s create mode 100644 ld/testsuite/ld-i386/tlspic2.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cb06a25bc26..e697ce3b3d6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,29 @@ +2002-09-19 Jakub Jelinek + + * reloc.c (BFD_RELOC_386_TLS_TPOFF, BFD_RELOC_386_TLS_IE, + BFD_RELOC_386_TLS_GOTIE): Add. + * bfd-in2.h, libbfd.h: Rebuilt. + * elf32-i386.c (elf_howto_table): Add R_386_TLS_TPOFF, R_386_TLS_IE + and R_386_TLS_GOTIE. + (elf_i386_reloc_type_lookup): Handle it. + (struct elf_i386_link_hash_entry): Change tls_type type to unsigned + char instead of enum, change GOT_* into defines. + (GOT_TLS_IE_POS, GOT_TLS_IE_NEG, GOT_TLS_IE_BOTH): Define. + (elf_i386_tls_transition): Handle R_386_TLS_IE and R_386_TLS_GOTIE. + (elf_i386_check_relocs): Likewise. Avoid crash if local symbol is + accessed both as normal and TLS symbol. Move R_386_TLS_LDM and + R_386_PLT32 cases so that R_386_TLS_IE can fall through. + Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs. + (elf_i386_gc_sweep_hook): Handle R_386_TLS_IE and R_386_TLS_GOTIE. + Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs. + (allocate_dynrelocs): Allocate 2 .got and 2 .rel.got entries if + tls_type is GOT_TLS_IE_BOTH. + (elf_i386_size_dynamic_sections): Likewise. + (elf_i386_relocate_section): Handle R_386_TLS_IE and R_386_TLS_GOTIE. + Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs. + (elf_i386_finish_dynamic_symbol): Use tls_type & GOT_TLS_IE to catch + all 4 GOT_TLS_* TLS types. + 2002-09-19 Nick Clifton * elflink.h (elf_fix_symbol_flags): When examining weak symbols, diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index b6edd0a04c9..05255941090 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2264,6 +2264,9 @@ to compensate for the borrow when the low bits are added. */ BFD_RELOC_386_RELATIVE, BFD_RELOC_386_GOTOFF, BFD_RELOC_386_GOTPC, + BFD_RELOC_386_TLS_TPOFF, + BFD_RELOC_386_TLS_IE, + BFD_RELOC_386_TLS_GOTIE, BFD_RELOC_386_TLS_LE, BFD_RELOC_386_TLS_GD, BFD_RELOC_386_TLS_LDM, diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index ef22e68e235..d52d5a7db4d 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -133,9 +133,18 @@ static reloc_howto_type elf_howto_table[]= R_386_ext_offset is the value to subtract from a reloc type of R_386_16 thru R_386_PC8 to form an index into this table. */ #define R_386_standard ((unsigned int) R_386_GOTPC + 1) -#define R_386_ext_offset ((unsigned int) R_386_TLS_LE - R_386_standard) +#define R_386_ext_offset ((unsigned int) R_386_TLS_TPOFF - R_386_standard) - /* The remaining relocs are a GNU extension. */ + /* These relocs are a GNU extension. */ + HOWTO(R_386_TLS_TPOFF, 0, 2, 32, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_386_TLS_TPOFF", + true, 0xffffffff, 0xffffffff, false), + HOWTO(R_386_TLS_IE, 0, 2, 32, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_386_TLS_IE", + true, 0xffffffff, 0xffffffff, false), + HOWTO(R_386_TLS_GOTIE, 0, 2, 32, false, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_386_TLS_GOTIE", + true, 0xffffffff, 0xffffffff, false), HOWTO(R_386_TLS_LE, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_386_TLS_LE", true, 0xffffffff, 0xffffffff, false), @@ -279,7 +288,19 @@ elf_i386_reloc_type_lookup (abfd, code) TRACE ("BFD_RELOC_386_GOTPC"); return &elf_howto_table[(unsigned int) R_386_GOTPC ]; - /* The remaining relocs are a GNU extension. */ + /* These relocs are a GNU extension. */ + case BFD_RELOC_386_TLS_TPOFF: + TRACE ("BFD_RELOC_386_TLS_TPOFF"); + return &elf_howto_table[(unsigned int) R_386_TLS_TPOFF - R_386_ext_offset]; + + case BFD_RELOC_386_TLS_IE: + TRACE ("BFD_RELOC_386_TLS_IE"); + return &elf_howto_table[(unsigned int) R_386_TLS_IE - R_386_ext_offset]; + + case BFD_RELOC_386_TLS_GOTIE: + TRACE ("BFD_RELOC_386_TLS_GOTIE"); + return &elf_howto_table[(unsigned int) R_386_TLS_GOTIE - R_386_ext_offset]; + case BFD_RELOC_386_TLS_LE: TRACE ("BFD_RELOC_386_TLS_LE"); return &elf_howto_table[(unsigned int) R_386_TLS_LE - R_386_ext_offset]; @@ -564,9 +585,14 @@ struct elf_i386_link_hash_entry /* Track dynamic relocs copied for this symbol. */ struct elf_i386_dyn_relocs *dyn_relocs; - enum { - GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE - } tls_type; +#define GOT_UNKNOWN 0 +#define GOT_NORMAL 1 +#define GOT_TLS_GD 2 +#define GOT_TLS_IE 4 +#define GOT_TLS_IE_POS 5 +#define GOT_TLS_IE_NEG 6 +#define GOT_TLS_IE_BOTH 7 + unsigned char tls_type; }; #define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent)) @@ -836,6 +862,11 @@ elf_i386_tls_transition (info, r_type, is_local) if (is_local) return R_386_TLS_LE_32; return R_386_TLS_IE_32; + case R_386_TLS_IE: + case R_386_TLS_GOTIE: + if (is_local) + return R_386_TLS_LE_32; + return r_type; case R_386_TLS_LDM: return R_386_TLS_LE_32; } @@ -897,10 +928,34 @@ elf_i386_check_relocs (abfd, info, sec, relocs) switch (r_type) { + case R_386_TLS_LDM: + htab->tls_ldm_got.refcount += 1; + goto create_got; + + case R_386_PLT32: + /* This symbol requires a procedure linkage table entry. We + actually build the entry in adjust_dynamic_symbol, + because this might be a case of linking PIC code which is + never referenced by a dynamic object, in which case we + don't need to generate a procedure linkage table entry + after all. */ + + /* If this is a local symbol, we resolve it directly without + creating a procedure linkage table entry. */ + if (h == NULL) + continue; + + h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->plt.refcount += 1; + break; + case R_386_TLS_IE_32: + case R_386_TLS_IE: + case R_386_TLS_GOTIE: if (info->shared) info->flags |= DF_STATIC_TLS; - /* FALLTHROUGH */ + /* Fall through */ + case R_386_GOT32: case R_386_TLS_GD: /* This symbol requires a global offset table entry. */ @@ -912,7 +967,17 @@ elf_i386_check_relocs (abfd, info, sec, relocs) default: case R_386_GOT32: tls_type = GOT_NORMAL; break; case R_386_TLS_GD: tls_type = GOT_TLS_GD; break; - case R_386_TLS_IE_32: tls_type = GOT_TLS_IE; break; + case R_386_TLS_IE_32: + if (ELF32_R_TYPE (rel->r_info) == r_type) + tls_type = GOT_TLS_IE_NEG; + else + /* If this is a GD->IE transition, we may use either of + R_386_TLS_TPOFF and R_386_TLS_TPOFF32. */ + tls_type = GOT_TLS_IE; + break; + case R_386_TLS_IE: + case R_386_TLS_GOTIE: + tls_type = GOT_TLS_IE_POS; break; } if (h != NULL) @@ -944,18 +1009,22 @@ elf_i386_check_relocs (abfd, info, sec, relocs) old_tls_type = elf_i386_local_got_tls_type (abfd) [r_symndx]; } + if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE)) + tls_type |= old_tls_type; /* If a TLS symbol is accessed using IE at least once, there is no point to use dynamic model for it. */ - if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN - && (old_tls_type != GOT_TLS_GD || tls_type != GOT_TLS_IE)) + else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN + && (old_tls_type != GOT_TLS_GD + || (tls_type & GOT_TLS_IE) == 0)) { - if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD) - tls_type = GOT_TLS_IE; + if ((old_tls_type & GOT_TLS_IE) && tls_type == GOT_TLS_GD) + tls_type = old_tls_type; else { (*_bfd_error_handler) (_("%s: `%s' accessed both as normal and thread local symbol"), - bfd_archive_filename (abfd), h->root.root.string); + bfd_archive_filename (abfd), + h ? h->root.root.string : ""); return false; } } @@ -980,28 +1049,15 @@ elf_i386_check_relocs (abfd, info, sec, relocs) if (!create_got_section (htab->elf.dynobj, info)) return false; } - break; - - case R_386_TLS_LDM: - htab->tls_ldm_got.refcount += 1; - goto create_got; - - case R_386_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; + if (r_type != R_386_TLS_IE) + break; + /* Fall through */ - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - h->plt.refcount += 1; - break; + case R_386_TLS_LE_32: + case R_386_TLS_LE: + if (!info->shared) + break; + /* Fall through */ case R_386_32: case R_386_PC32: @@ -1161,16 +1217,6 @@ elf_i386_check_relocs (abfd, info, sec, relocs) return false; break; - case R_386_TLS_LE_32: - case R_386_TLS_LE: - if (info->shared) - { - (*_bfd_error_handler) (_("%s: TLS local exec code cannot be linked into shared objects"), - bfd_archive_filename (abfd)); - return false; - } - break; - default: break; } @@ -1233,6 +1279,7 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs) bfd_signed_vma *local_got_refcounts; const Elf_Internal_Rela *rel, *relend; unsigned long r_symndx; + int r_type; struct elf_link_hash_entry *h; elf_section_data (sec)->local_dynrel = NULL; @@ -1243,9 +1290,10 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs) relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; rel++) - switch (elf_i386_tls_transition (info, ELF32_R_TYPE (rel->r_info), - ELF32_R_SYM (rel->r_info) - >= symtab_hdr->sh_info)) + switch ((r_type = elf_i386_tls_transition (info, + ELF32_R_TYPE (rel->r_info), + ELF32_R_SYM (rel->r_info) + >= symtab_hdr->sh_info))) { case R_386_TLS_LDM: if (elf_i386_hash_table (info)->tls_ldm_got.refcount > 0) @@ -1254,6 +1302,8 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs) case R_386_TLS_GD: case R_386_TLS_IE_32: + case R_386_TLS_IE: + case R_386_TLS_GOTIE: case R_386_GOT32: r_symndx = ELF32_R_SYM (rel->r_info); if (r_symndx >= symtab_hdr->sh_info) @@ -1267,7 +1317,15 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs) if (local_got_refcounts[r_symndx] > 0) local_got_refcounts[r_symndx] -= 1; } - break; + if (r_type != R_386_TLS_IE) + break; + /* Fall through */ + + case R_386_TLS_LE_32: + case R_386_TLS_LE: + if (!info->shared) + break; + /* Fall through */ case R_386_32: case R_386_PC32: @@ -1553,12 +1611,12 @@ allocate_dynrelocs (h, inf) h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; } - /* If R_386_TLS_IE_32 symbol is now local to the binary, + /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary, make it a R_386_TLS_LE_32 requiring no TLS entry. */ if (h->got.refcount > 0 && !info->shared && h->dynindx == -1 - && elf_i386_hash_entry(h)->tls_type == GOT_TLS_IE) + && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE)) h->got.offset = (bfd_vma) -1; else if (h->got.refcount > 0) { @@ -1579,13 +1637,18 @@ allocate_dynrelocs (h, inf) h->got.offset = s->_raw_size; s->_raw_size += 4; /* R_386_TLS_GD needs 2 consecutive GOT slots. */ - if (tls_type == GOT_TLS_GD) + if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE_BOTH) s->_raw_size += 4; dyn = htab->elf.dynamic_sections_created; /* R_386_TLS_IE_32 needs one dynamic relocation, - R_386_TLS_GD needs one if local symbol and two if global. */ - if ((tls_type == GOT_TLS_GD && h->dynindx == -1) - || tls_type == GOT_TLS_IE) + R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation, + (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we + need two), R_386_TLS_GD needs one if local symbol and two if + global. */ + if (tls_type == GOT_TLS_IE_BOTH) + htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel); + else if ((tls_type == GOT_TLS_GD && h->dynindx == -1) + || (tls_type & GOT_TLS_IE)) htab->srelgot->_raw_size += sizeof (Elf32_External_Rel); else if (tls_type == GOT_TLS_GD) htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel); @@ -1786,12 +1849,18 @@ elf_i386_size_dynamic_sections (output_bfd, info) { *local_got = s->_raw_size; s->_raw_size += 4; - if (*local_tls_type == GOT_TLS_GD) + if (*local_tls_type == GOT_TLS_GD + || *local_tls_type == GOT_TLS_IE_BOTH) s->_raw_size += 4; if (info->shared || *local_tls_type == GOT_TLS_GD - || *local_tls_type == GOT_TLS_IE) - srel->_raw_size += sizeof (Elf32_External_Rel); + || (*local_tls_type & GOT_TLS_IE)) + { + if (*local_tls_type == GOT_TLS_IE_BOTH) + srel->_raw_size += 2 * sizeof (Elf32_External_Rel); + else + srel->_raw_size += sizeof (Elf32_External_Rel); + } } else *local_got = (bfd_vma) -1; @@ -2422,8 +2491,29 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, } break; + case R_386_TLS_IE: + if (info->shared) + { + Elf_Internal_Rel outrel; + asection *sreloc; + Elf32_External_Rel *loc; + + outrel.r_offset = rel->r_offset + + input_section->output_section->vma + + input_section->output_offset; + outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); + sreloc = elf_section_data (input_section)->sreloc; + if (sreloc == NULL) + abort (); + loc = (Elf32_External_Rel *) sreloc->contents; + loc += sreloc->reloc_count++; + bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); + } + /* Fall through */ + case R_386_TLS_GD: case R_386_TLS_IE_32: + case R_386_TLS_GOTIE: r_type = elf_i386_tls_transition (info, r_type, h == NULL); tls_type = GOT_UNKNOWN; if (h == NULL && local_got_offsets) @@ -2431,11 +2521,18 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, else if (h != NULL) { tls_type = elf_i386_hash_entry(h)->tls_type; - if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE) + if (!info->shared && h->dynindx == -1 && (tls_type & GOT_TLS_IE)) r_type = R_386_TLS_LE_32; } - if (r_type == R_386_TLS_GD && tls_type == GOT_TLS_IE) - r_type = R_386_TLS_IE_32; + if (tls_type == GOT_TLS_IE) + tls_type = GOT_TLS_IE_NEG; + if (r_type == R_386_TLS_GD) + { + if (tls_type == GOT_TLS_IE_POS) + r_type = R_386_TLS_GOTIE; + else if (tls_type & GOT_TLS_IE) + r_type = R_386_TLS_IE_32; + } if (r_type == R_386_TLS_LE_32) { @@ -2503,27 +2600,77 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, rel++; continue; } - else + else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE) { unsigned int val, type; /* IE->LE transition: - Originally it can be either: + Originally it can be one of: + movl foo, %eax + movl foo, %reg + addl foo, %reg + We change it into: + movl $foo, %eax + movl $foo, %reg + addl $foo, %reg. */ + BFD_ASSERT (rel->r_offset >= 1); + val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); + BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size); + if (val != 0xa1) + { + BFD_ASSERT (rel->r_offset >= 2); + type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); + } + if (val == 0xa1) + { + /* movl foo, %eax. */ + bfd_put_8 (output_bfd, 0xb8, contents + rel->r_offset - 2); + } + else if (type == 0x8b) + { + /* movl */ + BFD_ASSERT ((val & 0xc7) == 0x05); + bfd_put_8 (output_bfd, 0xc7, + contents + rel->r_offset - 2); + bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), + contents + rel->r_offset - 1); + } + else if (type == 0x03) + { + /* addl */ + BFD_ASSERT ((val & 0xc7) == 0x05); + bfd_put_8 (output_bfd, 0x81, + contents + rel->r_offset - 2); + bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), + contents + rel->r_offset - 1); + } + else + BFD_FAIL (); + bfd_put_32 (output_bfd, -tpoff (info, relocation), + contents + rel->r_offset); + continue; + } + else + { + unsigned int val, type; + + /* {IE_32,GOTIE}->LE transition: + Originally it can be one of: subl foo(%reg1), %reg2 - or movl foo(%reg1), %reg2 + addl foo(%reg1), %reg2 We change it into: subl $foo, %reg2 - or - movl $foo, %reg2 (6 byte form) */ + movl $foo, %reg2 (6 byte form) + addl $foo, %reg2. */ BFD_ASSERT (rel->r_offset >= 2); type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size); + BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4); if (type == 0x8b) { /* movl */ - BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4); bfd_put_8 (output_bfd, 0xc7, contents + rel->r_offset - 2); bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), @@ -2532,16 +2679,27 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, else if (type == 0x2b) { /* subl */ - BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4); bfd_put_8 (output_bfd, 0x81, contents + rel->r_offset - 2); bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7), contents + rel->r_offset - 1); } + else if (type == 0x03) + { + /* addl */ + bfd_put_8 (output_bfd, 0x81, + contents + rel->r_offset - 2); + bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), + contents + rel->r_offset - 1); + } else BFD_FAIL (); - bfd_put_32 (output_bfd, tpoff (info, relocation), - contents + rel->r_offset); + if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE) + bfd_put_32 (output_bfd, -tpoff (info, relocation), + contents + rel->r_offset); + else + bfd_put_32 (output_bfd, tpoff (info, relocation), + contents + rel->r_offset); continue; } } @@ -2576,9 +2734,14 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, indx = h && h->dynindx != -1 ? h->dynindx : 0; if (r_type == R_386_TLS_GD) dr_type = R_386_TLS_DTPMOD32; + else if (tls_type == GOT_TLS_IE_POS) + dr_type = R_386_TLS_TPOFF; else dr_type = R_386_TLS_TPOFF32; - if (dr_type == R_386_TLS_TPOFF32 && indx == 0) + if (dr_type == R_386_TLS_TPOFF && indx == 0) + bfd_put_32 (output_bfd, relocation - dtpoff_base (info), + htab->sgot->contents + off); + else if (dr_type == R_386_TLS_TPOFF32 && indx == 0) bfd_put_32 (output_bfd, dtpoff_base (info) - relocation, htab->sgot->contents + off); else @@ -2611,6 +2774,17 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, loc); } } + else if (tls_type == GOT_TLS_IE_BOTH) + { + bfd_put_32 (output_bfd, + indx == 0 ? relocation - dtpoff_base (info) : 0, + htab->sgot->contents + off + 4); + outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF); + outrel.r_offset += 4; + htab->srelgot->reloc_count++; + loc++; + bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); + } if (h != NULL) h->got.offset |= 1; @@ -2623,6 +2797,11 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, if (r_type == ELF32_R_TYPE (rel->r_info)) { relocation = htab->sgot->output_offset + off; + if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE) + && tls_type == GOT_TLS_IE_BOTH) + relocation += 4; + if (r_type == R_386_TLS_IE) + relocation += htab->sgot->output_section->vma; unresolved_reloc = false; } else @@ -2668,6 +2847,17 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, memcpy (contents + roff, "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12); contents[roff + 7] = 0x80 | (val & 7); + /* If foo is used only with foo@gotntpoff(%reg) and + foo@indntpoff, but not with foo@gottpoff(%reg), change + subl $foo@gottpoff(%reg), %eax + into: + addl $foo@gotntpoff(%reg), %eax. */ + if (r_type == R_386_TLS_GOTIE) + { + contents[roff + 6] = 0x03; + if (tls_type == GOT_TLS_IE_BOTH) + off += 4; + } bfd_put_32 (output_bfd, htab->sgot->output_offset + off, contents + roff + 8); /* Skip R_386_PLT32. */ @@ -2743,11 +2933,42 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, break; case R_386_TLS_LE_32: - relocation = tpoff (info, relocation); - break; - case R_386_TLS_LE: - relocation = -tpoff (info, relocation); + if (info->shared) + { + Elf_Internal_Rel outrel; + asection *sreloc; + Elf32_External_Rel *loc; + int indx; + + outrel.r_offset = rel->r_offset + + input_section->output_section->vma + + input_section->output_offset; + if (h != NULL && h->dynindx != -1) + indx = h->dynindx; + else + indx = 0; + if (r_type == R_386_TLS_LE_32) + outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32); + else + outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF); + sreloc = elf_section_data (input_section)->sreloc; + if (sreloc == NULL) + abort (); + loc = (Elf32_External_Rel *) sreloc->contents; + loc += sreloc->reloc_count++; + bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc); + if (indx) + continue; + else if (r_type == R_386_TLS_LE_32) + relocation = dtpoff_base (info) - relocation; + else + relocation -= dtpoff_base (info); + } + else if (r_type == R_386_TLS_LE_32) + relocation = tpoff (info, relocation); + else + relocation = -tpoff (info, relocation); break; default: @@ -2907,7 +3128,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym) if (h->got.offset != (bfd_vma) -1 && elf_i386_hash_entry(h)->tls_type != GOT_TLS_GD - && elf_i386_hash_entry(h)->tls_type != GOT_TLS_IE) + && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0) { Elf_Internal_Rel rel; Elf32_External_Rel *loc; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index e855db196a1..3971ea6aa62 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -799,6 +799,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_386_RELATIVE", "BFD_RELOC_386_GOTOFF", "BFD_RELOC_386_GOTPC", + "BFD_RELOC_386_TLS_TPOFF", + "BFD_RELOC_386_TLS_IE", + "BFD_RELOC_386_TLS_GOTIE", "BFD_RELOC_386_TLS_LE", "BFD_RELOC_386_TLS_GD", "BFD_RELOC_386_TLS_LDM", diff --git a/bfd/reloc.c b/bfd/reloc.c index e60c26e0512..504359f2af1 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2122,6 +2122,12 @@ ENUMX BFD_RELOC_386_GOTOFF ENUMX BFD_RELOC_386_GOTPC +ENUMX + BFD_RELOC_386_TLS_TPOFF +ENUMX + BFD_RELOC_386_TLS_IE +ENUMX + BFD_RELOC_386_TLS_GOTIE ENUMX BFD_RELOC_386_TLS_LE ENUMX diff --git a/gas/ChangeLog b/gas/ChangeLog index a4cc1f1574b..17a9ce0f987 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2002-09-19 Jakub Jelinek + + * config/tc-i386.c (tc_i386_fix_adjustable): Handle + BFD_RELOC_386_TLS_IE and BFD_RELOC_386_TLS_GOTIE. + (BFD_RELOC_386_TLS_IE, BFD_RELOC_386_TLS_GOTIE): Define to 0 + if not defined. + (lex_got): Handle @GOTNTPOFF and @INDNTPOFF. + (md_apply_fix3, tc_gen_reloc): Handle BFD_RELOC_386_TLS_IE and + BFD_RELOC_386_TLS_GOTIE. + 2002-09-19 Richard Henderson * config/tc-alpha.c (md_pcrel_from): Only adjust special for diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 1a9a30e7c58..8bc88f77ef4 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1228,6 +1228,8 @@ tc_i386_fix_adjustable (fixP) || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32 || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32 + || fixP->fx_r_type == BFD_RELOC_386_TLS_IE + || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32 || fixP->fx_r_type == BFD_RELOC_386_TLS_LE || fixP->fx_r_type == BFD_RELOC_X86_64_PLT32 @@ -1254,6 +1256,8 @@ tc_i386_fix_adjustable (fixP) #define BFD_RELOC_386_TLS_LDM 0 #define BFD_RELOC_386_TLS_LDO_32 0 #define BFD_RELOC_386_TLS_IE_32 0 +#define BFD_RELOC_386_TLS_IE 0 +#define BFD_RELOC_386_TLS_GOTIE 0 #define BFD_RELOC_386_TLS_LE_32 0 #define BFD_RELOC_386_TLS_LE 0 #define BFD_RELOC_X86_64_PLT32 0 @@ -3485,6 +3489,8 @@ lex_got (reloc, adjust) { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, 0 } }, { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } }, { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, 0 } }, + { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 } }, + { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 } }, { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } } }; char *cp; @@ -4658,6 +4664,8 @@ md_apply_fix3 (fixP, valP, seg) case BFD_RELOC_386_TLS_GD: case BFD_RELOC_386_TLS_LDM: case BFD_RELOC_386_TLS_IE_32: + case BFD_RELOC_386_TLS_IE: + case BFD_RELOC_386_TLS_GOTIE: case BFD_RELOC_X86_64_GOT32: value = 0; /* Fully resolved at runtime. No addend. */ break; @@ -5138,6 +5146,8 @@ tc_gen_reloc (section, fixp) case BFD_RELOC_386_TLS_LDM: case BFD_RELOC_386_TLS_LDO_32: case BFD_RELOC_386_TLS_IE_32: + case BFD_RELOC_386_TLS_IE: + case BFD_RELOC_386_TLS_GOTIE: case BFD_RELOC_386_TLS_LE_32: case BFD_RELOC_386_TLS_LE: case BFD_RELOC_X86_64_32S: diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index a9490153cb3..5707887f494 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2002-09-19 Jakub Jelinek + + * gas/i386/tlspic.s: Add tests. + * gas/i386/tlspic.d: Regenerated. + * gas/i386/tlsnopic.s: Add tests. + * gas/i386/tlsnopic.d: Regenerated. + 2002-09-19 Richard Henderson * gas/alpha/elf-reloc-7.s: New. diff --git a/gas/testsuite/gas/i386/tlsnopic.d b/gas/testsuite/gas/i386/tlsnopic.d index 64ec6e60d2c..68a25838f6b 100644 --- a/gas/testsuite/gas/i386/tlsnopic.d +++ b/gas/testsuite/gas/i386/tlsnopic.d @@ -28,4 +28,10 @@ Disassembly of section .text: 40: 90 [ ]*nop 41: 8d 91 00 00 00 00 lea 0x0\(%ecx\),%edx [ ]+43: R_386_TLS_LE var2 - 47: c3 [ ]*ret[ ]* + 47: a1 00 00 00 00 [ ]*mov 0x0,%eax +[ ]+48: R_386_TLS_IE foo + 4c: 65 8b 00 [ ]*mov %gs:\(%eax\),%eax + 4f: 65 a1 00 00 00 00 [ ]*mov %gs:0x0,%eax + 55: 03 05 00 00 00 00 [ ]*add 0x0,%eax + 57: R_386_TLS_IE foo + 5b: c3 [ ]*ret[ ]* diff --git a/gas/testsuite/gas/i386/tlsnopic.s b/gas/testsuite/gas/i386/tlsnopic.s index 1b51b3663e8..3a8b794195d 100644 --- a/gas/testsuite/gas/i386/tlsnopic.s +++ b/gas/testsuite/gas/i386/tlsnopic.s @@ -11,35 +11,44 @@ var2: .long 33 .globl fn .type fn,@function fn: - /* Main binary, no PIC */ + /* Main binary, no PIC. */ 1: movl 1b, %edx addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %edx - /* foo can be anywhere in startup TLS */ + /* foo can be anywhere in startup TLS. */ movl %gs:0, %eax subl foo@GOTTPOFF(%edx), %eax - /* %eax now contains &foo */ + /* %eax now contains &foo. */ - /* bar only in the main program */ + /* bar only in the main program. */ movl %gs:0, %eax subl $bar@TPOFF, %eax - /* %eax now contains &bar */ + /* %eax now contains &bar. */ - /* baz only in the main program */ + /* baz only in the main program. */ movl %gs:0, %ecx - /* Arbitrary instructions in between */ + /* Arbitrary instructions in between. */ nop subl $baz@TPOFF, %ecx - /* %ecx now contains &baz */ + /* %ecx now contains &baz. */ - /* var and var2 only in the main program */ + /* var and var2 only in the main program. */ movl %gs:0, %ecx - /* Arbitrary instructions in between */ + /* Arbitrary instructions in between. */ nop nop leal var@NTPOFF(%ecx), %eax - /* Arbitrary instructions in between */ + /* Arbitrary instructions in between. */ nop leal var2@NTPOFF(%ecx), %edx + /* foo can be anywhere in startup TLS. */ + movl foo@INDNTPOFF, %eax + movl %gs:(%eax), %eax + /* %eax now contains foo. */ + + movl %gs:0, %eax + addl foo@INDNTPOFF, %eax + /* %eax now contains &foo. */ + ret diff --git a/gas/testsuite/gas/i386/tlspic.d b/gas/testsuite/gas/i386/tlspic.d index 2444113d7e6..fbe83a47c4a 100644 --- a/gas/testsuite/gas/i386/tlspic.d +++ b/gas/testsuite/gas/i386/tlspic.d @@ -18,6 +18,13 @@ Disassembly of section .text: 17: 8d 76 00 [ ]*lea 0x0\(%esi\),%esi 1a: 2b 83 00 00 00 00 [ ]*sub 0x0\(%ebx\),%eax [ ]+1c: R_386_TLS_IE_32 foo - 20: 8b 5d fc [ ]*mov 0xfffffffc\(%ebp\),%ebx - 23: c9 [ ]*leave[ ]* - 24: c3 [ ]*ret[ ]* + 20: 8b 83 00 00 00 00 [ ]*mov 0x0\(%ebx\),%eax +[ ]+22: R_386_TLS_GOTIE foo + 26: 8d 76 00 [ ]*lea 0x0\(%esi\),%esi + 29: 65 8b 00 [ ]*mov %gs:\(%eax\),%eax + 2c: 65 8b 0d 00 00 00 00 [ ]*mov %gs:0x0,%ecx + 33: 03 8b 00 00 00 00 [ ]*add 0x0\(%ebx\),%ecx +[ ]+35: R_386_TLS_GOTIE foo + 39: 8b 5d fc [ ]*mov 0xfffffffc\(%ebp\),%ebx + 3c: c9 [ ]*leave[ ]* + 3d: c3 [ ]*ret[ ]* diff --git a/gas/testsuite/gas/i386/tlspic.s b/gas/testsuite/gas/i386/tlspic.s index e445ab975f8..c9b97574ab5 100644 --- a/gas/testsuite/gas/i386/tlspic.s +++ b/gas/testsuite/gas/i386/tlspic.s @@ -16,12 +16,24 @@ fn: /* foo can be anywhere in the startup TLS */ movl %gs:0, %eax - /* Arbitrary instructions in between */ + /* Arbitrary instructions in between. */ leal 0(%esi, 1), %esi subl foo@GOTTPOFF(%ebx), %eax /* %eax now contains &foo */ + /* Now the GNU sequence. */ + movl foo@GOTNTPOFF(%ebx), %eax + + /* Arbitrary instructions in between. */ + leal 0(%esi, 1), %esi + + movl %gs:(%eax), %eax + /* %eax now contains foo */ + + movl %gs:0, %ecx + addl foo@GOTNTPOFF(%ebx), %ecx + movl -4(%ebp), %ebx leave ret diff --git a/include/ChangeLog b/include/ChangeLog index d6c4ecb3fde..6f17145d771 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2002-09-19 Jakub Jelinek + + * elf/i386.h (R_386_TLS_TPOFF, R_386_TLS_IE, R_386_TLS_GOTIE): + Define. + 2002-09-19 Nathan Tallent * dis-asm.h: Remove (errant) trailing semicolon (;) from the diff --git a/include/elf/i386.h b/include/elf/i386.h index c6e9709a1fe..95941196c7e 100644 --- a/include/elf/i386.h +++ b/include/elf/i386.h @@ -36,7 +36,10 @@ START_RELOC_NUMBERS (elf_i386_reloc_type) RELOC_NUMBER (R_386_GOTPC, 10) /* 32 bit PC relative offset to GOT */ RELOC_NUMBER (R_386_32PLT, 11) /* Used by Sun */ FAKE_RELOC (FIRST_INVALID_RELOC, 12) - FAKE_RELOC (LAST_INVALID_RELOC, 16) + FAKE_RELOC (LAST_INVALID_RELOC, 13) + RELOC_NUMBER (R_386_TLS_TPOFF,14) + RELOC_NUMBER (R_386_TLS_IE, 15) + RELOC_NUMBER (R_386_TLS_GOTIE,16) RELOC_NUMBER (R_386_TLS_LE, 17) RELOC_NUMBER (R_386_TLS_GD, 18) RELOC_NUMBER (R_386_TLS_LDM, 19) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 6416a8a3d3a..fc82ea0eb5a 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,25 @@ +2002-09-19 Jakub Jelinek + + * ld-i386/i386.exp: New. + * ld-i386/tlsbin.dd: New test. + * ld-i386/tlsbinpic.s: New test. + * ld-i386/tlsbin.rd: New test. + * ld-i386/tlsbin.s: New test. + * ld-i386/tlsbin.sd: New test. + * ld-i386/tlsbin.td: New test. + * ld-i386/tlslib.s: New test. + * ld-i386/tlsnopic1.s: New test. + * ld-i386/tlsnopic2.s: New test. + * ld-i386/tlsnopic.dd: New test. + * ld-i386/tlsnopic.rd: New test. + * ld-i386/tlsnopic.sd: New test. + * ld-i386/tlspic1.s: New test. + * ld-i386/tlspic2.s: New test. + * ld-i386/tlspic.dd: New test. + * ld-i386/tlspic.rd: New test. + * ld-i386/tlspic.sd: New test. + * ld-i386/tlspic.td: New test. + 2002-09-18 Chris Demetriou * ld-mips-elf/branch-misc-1.d: New file. diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp new file mode 100644 index 00000000000..4072dd575a8 --- /dev/null +++ b/ld/testsuite/ld-i386/i386.exp @@ -0,0 +1,181 @@ +# Expect script for ld-i386 tests +# Copyright (C) 2000, 2001, 2002 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# Test i386 linking; all types of relocs. This tests the assembler and +# tools like objdump as well as the linker. + +if ![istarget i?86-*-*] { + return +} + +# FIXME: This isn't set by testsuite/config/default.exp; make it. +if ![info exists readelf] then { + set readelf [findfile $base_dir/../binutils/readelf] +} + +# List contains test-items with 3 items followed by 2 lists: +# 0:name 1:ld options 2:assembler options +# 3:filenames of assembler files 4: action and options. 5: name of output file + +# Actions: +# objdump: Apply objdump options on result. Compare with regex (last arg). +# nm: Apply nm options on result. Compare with regex (last arg). +# readelf: Apply readelf options on result. Compare with regex (last arg). + +set i386tests { + {"TLS -fpic -shared transitions" "-shared -melf_i386" + "--32" {tlspic1.s tlspic2.s} + {{readelf -Ssrl tlspic.rd} {objdump -drj.text tlspic.dd} + {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}} + "libtlspic.so"} + {"Helper shared library" "-shared -melf_i386" + "--32" {tlslib.s} {} "libtlslib.so"} + {"TLS -fpic and -fno-pic exec transitions" + "-melf_i386 tmpdir/libtlslib.so" "--32" {tlsbinpic.s tlsbin.s} + {{readelf -Ssrl tlsbin.rd} {objdump -drj.text tlsbin.dd} + {objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}} + "tlsbin"} + {"TLS -fno-pic -shared" "-shared -melf_i386" + "--32" {tlsnopic1.s tlsnopic2.s} + {{readelf -Ssrl tlsnopic.rd} {objdump -drj.text tlsnopic.dd} + {objdump -sj.got tlsnopic.sd}} "libtlsnopic.so"} +} + +# FIXME: Generalize and move this to ld-lib.exp + +proc run_ld_link_tests { ldtests } { + global ld + global as + global nm + global objdump + global readelf + global srcdir + global subdir + global env + + foreach testitem $ldtests { + set testname [lindex $testitem 0] + set ld_options [lindex $testitem 1] + set as_options [lindex $testitem 2] + set as_files [lindex $testitem 3] + set actions [lindex $testitem 4] + set binfile tmpdir/[lindex $testitem 5] + set objfiles {} + set is_unresolved 0 + set failed 0 + +# verbose -log "Testname is $testname" +# verbose -log "ld_options is $ld_options" +# verbose -log "as_options is $as_options" +# verbose -log "as_files is $as_files" +# verbose -log "actions is $actions" +# verbose -log "binfile is $binfile" + + # Assemble each file in the test. + foreach as_file $as_files { + set objfile "tmpdir/[file rootname $as_file].o" + lappend objfiles $objfile + + if ![ld_assemble $as "$as_options $srcdir/$subdir/$as_file" $objfile] { + set is_unresolved 1 + break + } + } + + # Catch assembler errors. + if { $is_unresolved != 0 } { + unresolved $testname + continue + } + + if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] { + fail $testname + } else { + set failed 0 + foreach actionlist $actions { + set action [lindex $actionlist 0] + set progopts [lindex $actionlist 1] + + # There are actions where we run regexp_diff on the + # output, and there are other actions (presumably). + # Handling of the former look the same. + set dump_prog "" + switch -- $action { + objdump + { set dump_prog $objdump } + nm + { set dump_prog $nm } + readelf + { set dump_prog $readelf } + default + { + perror "Unrecognized action $action" + set is_unresolved 1 + break + } + } + + if { $dump_prog != "" } { + set dumpfile [lindex $actionlist 2] + set binary $dump_prog + + # Ensure consistent sorting of symbols + if {[info exists env(LC_ALL)]} { + set old_lc_all $env(LC_ALL) + } + set env(LC_ALL) "C" + set cmd "$binary $progopts $binfile > dump.out" + send_log "$cmd\n" + catch "exec $cmd" comp_output + if {[info exists old_lc_all]} { + set env(LC_ALL) $old_lc_all + } else { + unset env(LC_ALL) + } + set comp_output [prune_warnings $comp_output] + + if ![string match "" $comp_output] then { + send_log "$comp_output\n" + set failed 1 + break + } + + if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then { + verbose "output is [file_contents "dump.out"]" 2 + set failed 1 + break + } + } + } + + if { $failed != 0 } { + fail $testname + } else { if { $is_unresolved == 0 } { + pass $testname + } } + } + + # Catch action errors. + if { $is_unresolved != 0 } { + unresolved $testname + continue + } + } +} + +run_ld_link_tests $i386tests diff --git a/ld/testsuite/ld-i386/tlsbin.dd b/ld/testsuite/ld-i386/tlsbin.dd new file mode 100644 index 00000000000..9ad0cc3ed32 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsbin.dd @@ -0,0 +1,456 @@ +#source: tlsbinpic.s +#source: tlsbin.s +#as: --32 +#ld: -melf_i386 tmpdir/libtlslib.so +#objdump: -drj.text +#target: i?86-*-* + +# PT_TLS layout is: +# Offset from Offset from Name +# TCB base TCB end +# 0x00 -0xa0 sg1..sg8 +# 0x20 -0x80 sl1..sl8 +# 0x40 -0x60 sh1..sh8 +# 0x60 -0x40 bg1..bg8 +# 0x80 -0x20 bl1..bl8 + +.*: +file format elf32-i386 + +Disassembly of section .text: + +0+8049000 : + 8049000: 55[ ]+push %ebp + 8049001: 89 e5[ ]+mov %esp,%ebp + 8049003: 53[ ]+push %ebx + 8049004: 50[ ]+push %eax + 8049005: e8 00 00 00 00[ ]+call 804900a + 804900a: 5b[ ]+pop %ebx + 804900b: 81 c3 f6 10 00 00[ ]+add \$0x10f6,%ebx + 8049011: 90[ ]+nop * + 8049012: 90[ ]+nop * + 8049013: 90[ ]+nop * + 8049014: 90[ ]+nop * +# GD -> IE because variable is not defined in executable + 8049015: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804901b: 2b 83 2c 00 00 00[ ]+sub 0x2c\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sG1 + 8049021: 90[ ]+nop * + 8049022: 90[ ]+nop * + 8049023: 90[ ]+nop * + 8049024: 90[ ]+nop * +# GD -> IE because variable is not defined in executable where +# the variable is referenced through @gottpoff too + 8049025: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804902b: 2b 83 1c 00 00 00[ ]+sub 0x1c\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sG2 + 8049031: 90[ ]+nop * + 8049032: 90[ ]+nop * + 8049033: 90[ ]+nop * + 8049034: 90[ ]+nop * +# GD -> IE because variable is not defined in executable where +# the variable is referenced through @gotntpoff too + 8049035: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804903b: 2b 83 10 00 00 00[ ]+sub 0x10\(%ebx\),%eax +# ->R_386_TLS_TPOFF sG3 + 8049041: 90[ ]+nop * + 8049042: 90[ ]+nop * + 8049043: 90[ ]+nop * + 8049044: 90[ ]+nop * +# GD -> IE because variable is not defined in executable where +# the variable is referenced through @gottpoff and @gotntpoff too + 8049045: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804904b: 2b 83 20 00 00 00[ ]+sub 0x20\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sG4 + 8049051: 90[ ]+nop * + 8049052: 90[ ]+nop * + 8049053: 90[ ]+nop * + 8049054: 90[ ]+nop * +# GD -> LE with global variable defined in executable + 8049055: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804905b: 81 e8 a0 00 00 00[ ]+sub \$0xa0,%eax +# sg1 + 8049061: 90[ ]+nop * + 8049062: 90[ ]+nop * + 8049063: 90[ ]+nop * + 8049064: 90[ ]+nop * +# GD -> LE with local variable defined in executable + 8049065: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804906b: 81 e8 80 00 00 00[ ]+sub \$0x80,%eax +# sl1 + 8049071: 90[ ]+nop * + 8049072: 90[ ]+nop * + 8049073: 90[ ]+nop * + 8049074: 90[ ]+nop * +# GD -> LE with hidden variable defined in executable + 8049075: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804907b: 81 e8 60 00 00 00[ ]+sub \$0x60,%eax +# sh1 + 8049081: 90[ ]+nop * + 8049082: 90[ ]+nop * + 8049083: 90[ ]+nop * + 8049084: 90[ ]+nop * +# LD + 8049085: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804908b: 90[ ]+nop * + 804908c: 8d 74 26 00[ ]+lea 0x0\(%esi,1\),%esi + 8049090: 90[ ]+nop * + 8049091: 90[ ]+nop * + 8049092: 8d 90 80 ff ff ff[ ]+lea 0xffffff80\(%eax\),%edx +# sl1 + 8049098: 90[ ]+nop * + 8049099: 90[ ]+nop * + 804909a: 8d 88 84 ff ff ff[ ]+lea 0xffffff84\(%eax\),%ecx +# sl2 + 80490a0: 90[ ]+nop * + 80490a1: 90[ ]+nop * + 80490a2: 90[ ]+nop * + 80490a3: 90[ ]+nop * +# LD against hidden variables + 80490a4: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 80490aa: 90[ ]+nop * + 80490ab: 8d 74 26 00[ ]+lea 0x0\(%esi,1\),%esi + 80490af: 90[ ]+nop * + 80490b0: 90[ ]+nop * + 80490b1: 8d 90 a0 ff ff ff[ ]+lea 0xffffffa0\(%eax\),%edx +# sh1 + 80490b7: 90[ ]+nop * + 80490b8: 90[ ]+nop * + 80490b9: 8d 88 a4 ff ff ff[ ]+lea 0xffffffa4\(%eax\),%ecx +# sh2 + 80490bf: 90[ ]+nop * + 80490c0: 90[ ]+nop * + 80490c1: 90[ ]+nop * + 80490c2: 90[ ]+nop * +# @gottpoff IE against global var + 80490c3: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + 80490ca: 90[ ]+nop * + 80490cb: 90[ ]+nop * + 80490cc: 2b 8b 1c 00 00 00[ ]+sub 0x1c\(%ebx\),%ecx +# ->R_386_TLS_TPOFF32 sG2 + 80490d2: 90[ ]+nop * + 80490d3: 90[ ]+nop * + 80490d4: 90[ ]+nop * + 80490d5: 90[ ]+nop * +# @gottpoff IE against global var + 80490d6: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 80490dc: 90[ ]+nop * + 80490dd: 90[ ]+nop * + 80490de: 2b 83 20 00 00 00[ ]+sub 0x20\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sG4 + 80490e4: 90[ ]+nop * + 80490e5: 90[ ]+nop * + 80490e6: 90[ ]+nop * + 80490e7: 90[ ]+nop * +# @gotntpoff IE against global var + 80490e8: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + 80490ef: 90[ ]+nop * + 80490f0: 90[ ]+nop * + 80490f1: 03 8b 10 00 00 00[ ]+add 0x10\(%ebx\),%ecx +# ->R_386_TLS_TPOFF sG3 + 80490f7: 90[ ]+nop * + 80490f8: 90[ ]+nop * + 80490f9: 90[ ]+nop * + 80490fa: 90[ ]+nop * +# @gotntpoff IE against global var + 80490fb: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 8049101: 90[ ]+nop * + 8049102: 90[ ]+nop * + 8049103: 03 83 24 00 00 00[ ]+add 0x24\(%ebx\),%eax +# ->R_386_TLS_TPOFF sG4 + 8049109: 90[ ]+nop * + 804910a: 90[ ]+nop * + 804910b: 90[ ]+nop * + 804910c: 90[ ]+nop * +# @gottpoff IE -> LE against global var defined in exec + 804910d: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + 8049114: 90[ ]+nop * + 8049115: 90[ ]+nop * + 8049116: 81 e9 a0 00 00 00[ ]+sub \$0xa0,%ecx +# sg1 + 804911c: 90[ ]+nop * + 804911d: 90[ ]+nop * + 804911e: 90[ ]+nop * + 804911f: 90[ ]+nop * +# @gotntpoff IE -> LE against local var + 8049120: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + 8049127: 90[ ]+nop * + 8049128: 90[ ]+nop * + 8049129: 81 c0 80 ff ff ff[ ]+add \$0xffffff80,%eax +# sl1 + 804912f: 90[ ]+nop * + 8049130: 90[ ]+nop * + 8049131: 90[ ]+nop * + 8049132: 90[ ]+nop * +# @gottpoff IE -> LE against hidden var + 8049133: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + 804913a: 90[ ]+nop * + 804913b: 90[ ]+nop * + 804913c: 81 e9 60 00 00 00[ ]+sub \$0x60,%ecx +# sh1 + 8049142: 90[ ]+nop * + 8049143: 90[ ]+nop * + 8049144: 90[ ]+nop * + 8049145: 90[ ]+nop * +# Direct access through %gs +# @gotntpoff IE against global var + 8049146: 8b 8b 14 00 00 00[ ]+mov 0x14\(%ebx\),%ecx +# ->R_386_TLS_TPOFF sG5 + 804914c: 90[ ]+nop * + 804914d: 90[ ]+nop * + 804914e: 65 8b 11[ ]+mov %gs:\(%ecx\),%edx + 8049151: 90[ ]+nop * + 8049152: 90[ ]+nop * + 8049153: 90[ ]+nop * + 8049154: 90[ ]+nop * +# @gotntpoff IE->LE against local var + 8049155: c7 c0 90 ff ff ff[ ]+mov \$0xffffff90,%eax +# sl5 + 804915b: 90[ ]+nop * + 804915c: 90[ ]+nop * + 804915d: 65 8b 10[ ]+mov %gs:\(%eax\),%edx + 8049160: 90[ ]+nop * + 8049161: 90[ ]+nop * + 8049162: 90[ ]+nop * + 8049163: 90[ ]+nop * +# @gotntpoff IE->LE against hidden var + 8049164: c7 c2 b0 ff ff ff[ ]+mov \$0xffffffb0,%edx +# sh5 + 804916a: 90[ ]+nop * + 804916b: 90[ ]+nop * + 804916c: 65 8b 12[ ]+mov %gs:\(%edx\),%edx + 804916f: 90[ ]+nop * + 8049170: 90[ ]+nop * + 8049171: 90[ ]+nop * + 8049172: 90[ ]+nop * + 8049173: 8b 5d fc[ ]+mov 0xfffffffc\(%ebp\),%ebx + 8049176: c9[ ]+leave * + 8049177: c3[ ]+ret * + +08049178 <_start>: + 8049178: 55[ ]+push %ebp + 8049179: 89 e5[ ]+mov %esp,%ebp + 804917b: e8 00 00 00 00[ ]+call 8049180 <_start\+0x8> + 8049180: 59[ ]+pop %ecx + 8049181: 81 c1 80 0f 00 00[ ]+add \$0xf80,%ecx + 8049187: 90[ ]+nop * + 8049188: 90[ ]+nop * + 8049189: 90[ ]+nop * + 804918a: 90[ ]+nop * +# @gottpoff IE against global var + 804918b: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 8049192: 90[ ]+nop * + 8049193: 90[ ]+nop * + 8049194: 2b 91 28 00 00 00[ ]+sub 0x28\(%ecx\),%edx +# ->R_386_TLS_TPOFF32 sG6 + 804919a: 90[ ]+nop * + 804919b: 90[ ]+nop * + 804919c: 90[ ]+nop * + 804919d: 90[ ]+nop * +# @indntpoff IE against global var + 804919e: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 80491a4: 90[ ]+nop * + 80491a5: 90[ ]+nop * + 80491a6: 03 05 18 a1 04 08[ ]+add 0x804a118,%eax +# ->R_386_TLS_TPOFF sG7 + 80491ac: 90[ ]+nop * + 80491ad: 90[ ]+nop * + 80491ae: 90[ ]+nop * + 80491af: 90[ ]+nop * +# @indntpoff direct %gs access IE against global var + 80491b0: 8b 15 30 a1 04 08[ ]+mov 0x804a130,%edx +# ->R_386_TLS_TPOFF sG8 + 80491b6: 90[ ]+nop * + 80491b7: 90[ ]+nop * + 80491b8: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 80491bb: 90[ ]+nop * + 80491bc: 90[ ]+nop * + 80491bd: 90[ ]+nop * + 80491be: 90[ ]+nop * +# @gottpoff IE -> LE against global var defined in exec + 80491bf: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 80491c6: 90[ ]+nop * + 80491c7: 90[ ]+nop * + 80491c8: 81 ea 2c 00 00 00[ ]+sub \$0x2c,%edx +# bg6 + 80491ce: 90[ ]+nop * + 80491cf: 90[ ]+nop * + 80491d0: 90[ ]+nop * + 80491d1: 90[ ]+nop * +# @indntpoff IE -> LE against global var defined in exec + 80491d2: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 80491d8: 90[ ]+nop * + 80491d9: 90[ ]+nop * + 80491da: 81 c0 d8 ff ff ff[ ]+add \$0xffffffd8,%eax +# bg7 + 80491e0: 90[ ]+nop * + 80491e1: 90[ ]+nop * + 80491e2: 90[ ]+nop * + 80491e3: 90[ ]+nop * +# @indntpoff direct %gs access IE -> LE against global var defined +# in exec + 80491e4: c7 c2 dc ff ff ff[ ]+mov \$0xffffffdc,%edx +# bg8 + 80491ea: 90[ ]+nop * + 80491eb: 90[ ]+nop * + 80491ec: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 80491ef: 90[ ]+nop * + 80491f0: 90[ ]+nop * + 80491f1: 90[ ]+nop * + 80491f2: 90[ ]+nop * +# @gottpoff IE -> LE against local var + 80491f3: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 80491fa: 90[ ]+nop * + 80491fb: 90[ ]+nop * + 80491fc: 81 ea 0c 00 00 00[ ]+sub \$0xc,%edx +# bl6 + 8049202: 90[ ]+nop * + 8049203: 90[ ]+nop * + 8049204: 90[ ]+nop * + 8049205: 90[ ]+nop * +# @indntpoff IE -> LE against local var + 8049206: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 804920c: 90[ ]+nop * + 804920d: 90[ ]+nop * + 804920e: 81 c0 f8 ff ff ff[ ]+add \$0xfffffff8,%eax +# bl7 + 8049214: 90[ ]+nop * + 8049215: 90[ ]+nop * + 8049216: 90[ ]+nop * + 8049217: 90[ ]+nop * +# @indntpoff direct %gs access IE -> LE against local var + 8049218: c7 c2 fc ff ff ff[ ]+mov \$0xfffffffc,%edx +# bl8 + 804921e: 90[ ]+nop * + 804921f: 90[ ]+nop * + 8049220: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 8049223: 90[ ]+nop * + 8049224: 90[ ]+nop * + 8049225: 90[ ]+nop * + 8049226: 90[ ]+nop * +# @gottpoff IE -> LE against hidden but not local var + 8049227: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 804922e: 90[ ]+nop * + 804922f: 90[ ]+nop * + 8049230: 81 ea 4c 00 00 00[ ]+sub \$0x4c,%edx +# sh6 + 8049236: 90[ ]+nop * + 8049237: 90[ ]+nop * + 8049238: 90[ ]+nop * + 8049239: 90[ ]+nop * +# @indntpoff IE -> LE against hidden but not local var + 804923a: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 8049240: 90[ ]+nop * + 8049241: 90[ ]+nop * + 8049242: 81 c0 b8 ff ff ff[ ]+add \$0xffffffb8,%eax +# sh7 + 8049248: 90[ ]+nop * + 8049249: 90[ ]+nop * + 804924a: 90[ ]+nop * + 804924b: 90[ ]+nop * +# @indntpoff direct %gs access IE -> LE against hidden but not +# local var + 804924c: c7 c2 bc ff ff ff[ ]+mov \$0xffffffbc,%edx +# sh8 + 8049252: 90[ ]+nop * + 8049253: 90[ ]+nop * + 8049254: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 8049257: 90[ ]+nop * + 8049258: 90[ ]+nop * + 8049259: 90[ ]+nop * + 804925a: 90[ ]+nop * +# LE @tpoff, global var defined in exec + 804925b: ba a0 00 00 00[ ]+mov \$0xa0,%edx +# sg1 + 8049260: 90[ ]+nop * + 8049261: 90[ ]+nop * + 8049262: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 8049268: 90[ ]+nop * + 8049269: 90[ ]+nop * + 804926a: 29 d0[ ]+sub %edx,%eax + 804926c: 90[ ]+nop * + 804926d: 90[ ]+nop * + 804926e: 90[ ]+nop * + 804926f: 90[ ]+nop * +# LE @tpoff, local var + 8049270: b8 1f 00 00 00[ ]+mov \$0x1f,%eax +# bl1+1 + 8049275: 90[ ]+nop * + 8049276: 90[ ]+nop * + 8049277: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 804927e: 90[ ]+nop * + 804927f: 90[ ]+nop * + 8049280: 29 c2[ ]+sub %eax,%edx + 8049282: 90[ ]+nop * + 8049283: 90[ ]+nop * + 8049284: 90[ ]+nop * + 8049285: 90[ ]+nop * +# LE @tpoff, hidden var defined in exec + 8049286: b8 5d 00 00 00[ ]+mov \$0x5d,%eax +# sh1+3 + 804928b: 90[ ]+nop * + 804928c: 90[ ]+nop * + 804928d: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 8049294: 90[ ]+nop * + 8049295: 90[ ]+nop * + 8049296: 29 c2[ ]+sub %eax,%edx + 8049298: 90[ ]+nop * + 8049299: 90[ ]+nop * + 804929a: 90[ ]+nop * + 804929b: 90[ ]+nop * +# LE @ntpoff, global var defined in exec + 804929c: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 80492a2: 90[ ]+nop * + 80492a3: 90[ ]+nop * + 80492a4: 8d 90 64 ff ff ff[ ]+lea 0xffffff64\(%eax\),%edx +# sg2 + 80492aa: 90[ ]+nop * + 80492ab: 90[ ]+nop * + 80492ac: 90[ ]+nop * + 80492ad: 90[ ]+nop * +# LE @ntpoff, local var, non-canonical sequence + 80492ae: b8 e6 ff ff ff[ ]+mov \$0xffffffe6,%eax +# bl2+2 + 80492b3: 90[ ]+nop * + 80492b4: 90[ ]+nop * + 80492b5: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 80492bc: 90[ ]+nop * + 80492bd: 90[ ]+nop * + 80492be: 01 c2[ ]+add %eax,%edx + 80492c0: 90[ ]+nop * + 80492c1: 90[ ]+nop * + 80492c2: 90[ ]+nop * + 80492c3: 90[ ]+nop * +# LE @ntpoff, hidden var defined in exec, non-canonical sequence + 80492c4: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 80492cb: 90[ ]+nop * + 80492cc: 90[ ]+nop * + 80492cd: 81 c2 a5 ff ff ff[ ]+add \$0xffffffa5,%edx +# sh2+1 + 80492d3: 90[ ]+nop * + 80492d4: 90[ ]+nop * + 80492d5: 90[ ]+nop * + 80492d6: 90[ ]+nop * +# LE @ntpoff, global var defined in exec + 80492d7: 65 a1 68 ff ff ff[ ]+mov %gs:0xffffff68,%eax +# sg3 + 80492dd: 90[ ]+nop * + 80492de: 90[ ]+nop * + 80492df: 90[ ]+nop * + 80492e0: 90[ ]+nop * +# LE @ntpoff, local var + 80492e1: 65 8b 15 eb ff ff ff mov %gs:0xffffffeb,%edx +# bl3+3 + 80492e8: 90[ ]+nop * + 80492e9: 90[ ]+nop * + 80492ea: 90[ ]+nop * + 80492eb: 90[ ]+nop * +# LE @ntpoff, hidden var defined in exec + 80492ec: 65 8b 15 a9 ff ff ff mov %gs:0xffffffa9,%edx +# sh3+1 + 80492f3: 90[ ]+nop * + 80492f4: 90[ ]+nop * + 80492f5: 90[ ]+nop * + 80492f6: 90[ ]+nop * + 80492f7: 8b 5d fc[ ]+mov 0xfffffffc\(%ebp\),%ebx + 80492fa: c9[ ]+leave * + 80492fb: c3[ ]+ret * diff --git a/ld/testsuite/ld-i386/tlsbin.rd b/ld/testsuite/ld-i386/tlsbin.rd new file mode 100644 index 00000000000..a7fb1448ba0 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsbin.rd @@ -0,0 +1,167 @@ +#source: tlsbinpic.s +#source: tlsbin.s +#as: --32 +#ld: -melf_i386 tmpdir/libtlslib.so +#readelf: -Ssrl +#target: i?86-*-* + +There are 18 section headers, starting at offset 0x[0-9a-f]+: + +Section Headers: + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al + \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0 + \[ 1\] \.interp +.* + \[ 2\] \.hash +.* + \[ 3\] \.dynsym +.* + \[ 4\] \.dynstr +.* + \[ 5\] \.rel.dyn +.* + \[ 6\] \.rel.plt +.* + \[ 7\] \.plt +.* + \[ 8\] \.text +PROGBITS +0+8049000 .* + \[ 9\] \.data +.* + \[10\] .tdata +PROGBITS +0+804a000 [0-9a-f]+ 000060 00 WAT 0 0 1 + \[11\] .tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000040 00 WAT 0 0 1 + \[12\] \.dynamic +DYNAMIC +0+804a060 .* + \[13\] \.got +PROGBITS +0+804a100 .* + \[14\] \.bss +.* + \[15\] \.shstrtab +.* + \[16\] \.symtab +.* + \[17\] \.strtab +.* +Key to Flags: +.* +.* +.* + +Elf file type is EXEC \(Executable file\) +Entry point 0x8049178 +There are 6 program headers, starting at offset [0-9]+ + +Program Headers: + Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align + PHDR.* + INTERP.* +.*Requesting program interpreter.* + LOAD.* + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+a0 R +0x1 + + Section to Segment mapping: + Segment Sections... + 00 + + 01 +.interp * + 02 +.interp .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text * + 03 +.tdata .tbss .dynamic .got * + 04 +.tbss .dynamic * + 05 +.tdata .tbss * + +Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 9 entries: + Offset +Info +Type +Sym.Value +Sym. Name +0+804a110 0000010e R_386_TLS_TPOFF +0+ +sG3 +0+804a114 0000020e R_386_TLS_TPOFF +0+ +sG5 +0+804a118 0000040e R_386_TLS_TPOFF +0+ +sG7 +0+804a11c 00000525 R_386_TLS_TPOFF32 0+ +sG2 +0+804a120 00000625 R_386_TLS_TPOFF32 0+ +sG4 +0+804a124 0000060e R_386_TLS_TPOFF +0+ +sG4 +0+804a128 00000825 R_386_TLS_TPOFF32 0+ +sG6 +0+804a12c 00000925 R_386_TLS_TPOFF32 0+ +sG1 +0+804a130 00000d0e R_386_TLS_TPOFF +0+ +sG8 + +Relocation section '.rel.plt' at offset 0x30c contains 1 entries: + Offset +Info +Type +Sym.Value Sym. Name +0+804a10c 00000e07 R_386_JUMP_SLOT +[0-9a-f]+ +___tls_get_addr + +Symbol table '.dynsym' contains 15 entries: + +Num: +Value Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 NOTYPE LOCAL DEFAULT UND * + +1: 0+ +0 TLS +GLOBAL DEFAULT UND sG3 + +2: 0+ +0 TLS +GLOBAL DEFAULT UND sG5 + +3: 0+804a060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + +4: 0+ +0 TLS +GLOBAL DEFAULT UND sG7 + +5: 0+ +0 TLS +GLOBAL DEFAULT UND sG2 + +6: 0+ +0 TLS +GLOBAL DEFAULT UND sG4 + +7: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start + +8: 0+ +0 TLS +GLOBAL DEFAULT UND sG6 + +9: 0+ +0 TLS +GLOBAL DEFAULT UND sG1 + +10: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata + +11: 0+804a100 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + +12: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end + +13: 0+ +0 TLS +GLOBAL DEFAULT UND sG8 + +14: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND ___tls_get_addr + +Symbol table '.symtab' contains 74 entries: + +Num: +Value Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 NOTYPE LOCAL DEFAULT UND * + +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 * + +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 * + +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 * + +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 * + +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 * + +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 * + +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 * + +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 * + +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 * + +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 * + +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 * + +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 * + +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 * + +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14 * + +15: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15 * + +16: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +16 * + +17: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +17 * + +18: 00000020 +0 TLS +LOCAL DEFAULT +10 sl1 + +19: 00000024 +0 TLS +LOCAL DEFAULT +10 sl2 + +20: 00000028 +0 TLS +LOCAL DEFAULT +10 sl3 + +21: 0000002c +0 TLS +LOCAL DEFAULT +10 sl4 + +22: 00000030 +0 TLS +LOCAL DEFAULT +10 sl5 + +23: 00000034 +0 TLS +LOCAL DEFAULT +10 sl6 + +24: 00000038 +0 TLS +LOCAL DEFAULT +10 sl7 + +25: 0000003c +0 TLS +LOCAL DEFAULT +10 sl8 + +26: 00000080 +0 TLS +LOCAL DEFAULT +11 bl1 + +27: 00000084 +0 TLS +LOCAL DEFAULT +11 bl2 + +28: 00000088 +0 TLS +LOCAL DEFAULT +11 bl3 + +29: 0000008c +0 TLS +LOCAL DEFAULT +11 bl4 + +30: 00000090 +0 TLS +LOCAL DEFAULT +11 bl5 + +31: 00000094 +0 TLS +LOCAL DEFAULT +11 bl6 + +32: 00000098 +0 TLS +LOCAL DEFAULT +11 bl7 + +33: 0000009c +0 TLS +LOCAL DEFAULT +11 bl8 + +34: 0+ +0 TLS +GLOBAL DEFAULT UND sG3 + +35: 0000001c +0 TLS +GLOBAL DEFAULT +10 sg8 + +36: 0000007c +0 TLS +GLOBAL DEFAULT +11 bg8 + +37: 00000074 +0 TLS +GLOBAL DEFAULT +11 bg6 + +38: 0+ +0 TLS +GLOBAL DEFAULT UND sG5 + +39: 00000068 +0 TLS +GLOBAL DEFAULT +11 bg3 + +40: 0+804a060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + +41: 00000008 +0 TLS +GLOBAL DEFAULT +10 sg3 + +42: 0+ +0 TLS +GLOBAL DEFAULT UND sG7 + +43: 00000048 +0 TLS +GLOBAL HIDDEN +10 sh3 + +44: 0+ +0 TLS +GLOBAL DEFAULT UND sG2 + +45: 0000000c +0 TLS +GLOBAL DEFAULT +10 sg4 + +46: 0+ +0 TLS +GLOBAL DEFAULT UND sG4 + +47: 00000010 +0 TLS +GLOBAL DEFAULT +10 sg5 + +48: 00000070 +0 TLS +GLOBAL DEFAULT +11 bg5 + +49: 00000058 +0 TLS +GLOBAL HIDDEN +10 sh7 + +50: 0000005c +0 TLS +GLOBAL HIDDEN +10 sh8 + +51: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1 + +52: 0+8049178 +0 FUNC +GLOBAL DEFAULT +8 _start + +53: 0000004c +0 TLS +GLOBAL HIDDEN +10 sh4 + +54: 00000078 +0 TLS +GLOBAL DEFAULT +11 bg7 + +55: 00000050 +0 TLS +GLOBAL HIDDEN +10 sh5 + +56: 0+804a134 +0 NOTYPE GLOBAL DEFAULT ABS __bss_start + +57: 0+ +0 TLS +GLOBAL DEFAULT UND sG6 + +58: 0+8049000 +0 FUNC +GLOBAL DEFAULT +8 fn2 + +59: 00000004 +0 TLS +GLOBAL DEFAULT +10 sg2 + +60: 0+ +0 TLS +GLOBAL DEFAULT UND sG1 + +61: 00000040 +0 TLS +GLOBAL HIDDEN +10 sh1 + +62: 00000014 +0 TLS +GLOBAL DEFAULT +10 sg6 + +63: 00000018 +0 TLS +GLOBAL DEFAULT +10 sg7 + +64: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata + +65: 0+804a100 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + +66: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end + +67: 00000044 +0 TLS +GLOBAL HIDDEN +10 sh2 + +68: 00000054 +0 TLS +GLOBAL HIDDEN +10 sh6 + +69: 0+ +0 TLS +GLOBAL DEFAULT UND sG8 + +70: 00000064 +0 TLS +GLOBAL DEFAULT +11 bg2 + +71: 00000060 +0 TLS +GLOBAL DEFAULT +11 bg1 + +72: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND ___tls_get_addr + +73: 0000006c +0 TLS +GLOBAL DEFAULT +11 bg4 diff --git a/ld/testsuite/ld-i386/tlsbin.s b/ld/testsuite/ld-i386/tlsbin.s new file mode 100644 index 00000000000..db80e0984ff --- /dev/null +++ b/ld/testsuite/ld-i386/tlsbin.s @@ -0,0 +1,165 @@ + .section ".tbss", "awT", @nobits + .globl bg1, bg2, bg3, bg4, bg5, bg6, bg7, bg8 +bg1: .space 4 +bg2: .space 4 +bg3: .space 4 +bg4: .space 4 +bg5: .space 4 +bg6: .space 4 +bg7: .space 4 +bg8: .space 4 +bl1: .space 4 +bl2: .space 4 +bl3: .space 4 +bl4: .space 4 +bl5: .space 4 +bl6: .space 4 +bl7: .space 4 +bl8: .space 4 + .text + .globl _start + .type _start,@function +_start: + pushl %ebp + movl %esp, %ebp + /* Set up .GOT pointer for non-pic @gottpoff sequences */ + call 1f +1: popl %ecx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx + nop;nop;nop;nop + + /* @gottpoff IE against global var */ + movl %gs:0, %edx + nop;nop + subl sG6@gottpoff(%ecx), %edx + nop;nop;nop;nop + + /* @indntpoff IE against global var */ + movl %gs:0, %eax + nop;nop + addl sG7@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE against global var */ + movl sG8@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* @gottpoff IE -> LE against global var defined in exec */ + movl %gs:0, %edx + nop;nop + subl bg6@gottpoff(%ecx), %edx + nop;nop;nop;nop + + /* @indntpoff IE -> LE against global var defined in exec */ + movl %gs:0, %eax + nop;nop + addl bg7@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE -> LE against global var defined + in exec */ + movl bg8@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* @gottpoff IE -> LE against local var */ + movl %gs:0, %edx + nop;nop + subl bl6@gottpoff(%ecx), %edx + nop;nop;nop;nop + + /* @indntpoff IE -> LE against local var */ + movl %gs:0, %eax + nop;nop + addl bl7@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE -> LE against local var */ + movl bl8@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* @gottpoff IE -> LE against hidden but not local var */ + movl %gs:0, %edx + nop;nop + subl sh6@gottpoff(%ecx), %edx + nop;nop;nop;nop + + /* @indntpoff IE -> LE against hidden but not local var */ + movl %gs:0, %eax + nop;nop + addl sh7@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE -> LE against hidden but not + local var */ + movl sh8@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* LE @tpoff, global var defined in exec */ + movl $sg1@tpoff, %edx + nop;nop + movl %gs:0, %eax + nop;nop + subl %edx, %eax + nop;nop;nop;nop + + /* LE @tpoff, local var */ + movl $-1+bl1@tpoff, %eax + nop;nop + movl %gs:0, %edx + nop;nop + subl %eax, %edx + nop;nop;nop;nop + + /* LE @tpoff, hidden var defined in exec */ + movl $sh1@tpoff-3, %eax + nop;nop + movl %gs:0, %edx + nop;nop + subl %eax, %edx + nop;nop;nop;nop + + /* LE @ntpoff, global var defined in exec */ + movl %gs:0, %eax + nop;nop + leal sg2@ntpoff(%eax), %edx + nop;nop;nop;nop + + /* LE @ntpoff, local var, non-canonical sequence */ + movl $2+bl2@ntpoff, %eax + nop;nop + movl %gs:0, %edx + nop;nop + addl %eax, %edx + nop;nop;nop;nop + + /* LE @ntpoff, hidden var defined in exec, non-canonical sequence */ + movl %gs:0, %edx + nop;nop + addl $sh2@ntpoff+1, %edx + nop;nop;nop;nop + + /* Direct %gs access */ + + /* LE @ntpoff, global var defined in exec */ + movl %gs:sg3@ntpoff, %eax + nop;nop;nop;nop + + /* LE @ntpoff, local var */ + movl %gs:bl3@ntpoff+3, %edx + nop;nop;nop;nop + + /* LE @ntpoff, hidden var defined in exec */ + movl %gs:1+sh3@ntpoff, %edx + nop;nop;nop;nop + + movl -4(%ebp), %ebx + leave + ret diff --git a/ld/testsuite/ld-i386/tlsbin.sd b/ld/testsuite/ld-i386/tlsbin.sd new file mode 100644 index 00000000000..b82affe98f6 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsbin.sd @@ -0,0 +1,14 @@ +#source: tlsbinpic.s +#source: tlsbin.s +#as: --32 +#ld: -melf_i386 tmpdir/libtlslib.so +#objdump: -sj.got +#target: i?86-*-* + +.*: file format elf32-i386 + +Contents of section \.got: + 804a100 [0-9a-f]+ 00000000 00000000 [0-9a-f]+ .* + 804a110 00000000 00000000 00000000 00000000 .* + 804a120 00000000 00000000 00000000 00000000 .* + 804a130 00000000 +.* diff --git a/ld/testsuite/ld-i386/tlsbin.td b/ld/testsuite/ld-i386/tlsbin.td new file mode 100644 index 00000000000..bb29455e5de --- /dev/null +++ b/ld/testsuite/ld-i386/tlsbin.td @@ -0,0 +1,16 @@ +#source: tlsbinpic.s +#source: tlsbin.s +#as: --32 +#ld: -melf_i386 tmpdir/libtlslib.so +#objdump: -sj.tdata +#target: i?86-*-* + +.*: file format elf32-i386 + +Contents of section \.tdata: + 804a000 11000000 12000000 13000000 14000000 .* + 804a010 15000000 16000000 17000000 18000000 .* + 804a020 41000000 42000000 43000000 44000000 .* + 804a030 45000000 46000000 47000000 48000000 .* + 804a040 01010000 02010000 03010000 04010000 .* + 804a050 05010000 06010000 07010000 08010000 .* diff --git a/ld/testsuite/ld-i386/tlsbinpic.s b/ld/testsuite/ld-i386/tlsbinpic.s new file mode 100644 index 00000000000..027773a3e97 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsbinpic.s @@ -0,0 +1,168 @@ + /* Force .got aligned to 4K, so it very likely gets at 0x804a100 + (0x60 bytes .tdata and 0xa0 bytes .dynamic) */ + .data + .balign 4096 + .section ".tdata", "awT", @progbits + .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8 + .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8 + .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8 +sg1: .long 17 +sg2: .long 18 +sg3: .long 19 +sg4: .long 20 +sg5: .long 21 +sg6: .long 22 +sg7: .long 23 +sg8: .long 24 +sl1: .long 65 +sl2: .long 66 +sl3: .long 67 +sl4: .long 68 +sl5: .long 69 +sl6: .long 70 +sl7: .long 71 +sl8: .long 72 +sh1: .long 257 +sh2: .long 258 +sh3: .long 259 +sh4: .long 260 +sh5: .long 261 +sh6: .long 262 +sh7: .long 263 +sh8: .long 264 + /* Force .text aligned to 4K, so it very likely gets at 0x8049000. */ + .text + .balign 4096 + .globl fn2 + .type fn2,@function +fn2: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %eax + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + nop;nop;nop;nop + + /* GD -> IE because variable is not defined in executable */ + leal sG1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE because variable is not defined in executable where + the variable is referenced through @gottpoff too */ + leal sG2@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE because variable is not defined in executable where + the variable is referenced through @gotntpoff too */ + leal sG3@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE because variable is not defined in executable where + the variable is referenced through @gottpoff and @gotntpoff too */ + leal sG4@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> LE with global variable defined in executable */ + leal sg1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> LE with local variable defined in executable */ + leal sl1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> LE with hidden variable defined in executable */ + leal sh1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* LD */ + leal sl1@tlsldm(%ebx), %eax + call ___tls_get_addr@PLT + nop;nop + leal sl1@dtpoff(%eax), %edx + nop;nop + leal sl2@dtpoff(%eax), %ecx + nop;nop;nop;nop + + /* LD against hidden variables */ + leal sh1@tlsldm(%ebx), %eax + call ___tls_get_addr@PLT + nop;nop + leal sh1@dtpoff(%eax), %edx + nop;nop + leal sh2@dtpoff(%eax), %ecx + nop;nop;nop;nop + + /* @gottpoff IE against global var */ + movl %gs:0, %ecx + nop;nop + subl sG2@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gottpoff IE against global var */ + movl %gs:0, %eax + nop;nop + subl sG4@gottpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gotntpoff IE against global var */ + movl %gs:0, %ecx + nop;nop + addl sG3@gotntpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gotntpoff IE against global var */ + movl %gs:0, %eax + nop;nop + addl sG4@gotntpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gottpoff IE -> LE against global var defined in exec */ + movl %gs:0, %ecx + nop;nop + subl sg1@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gotntpoff IE -> LE against local var */ + movl %gs:0, %ecx + nop;nop + addl sl1@gotntpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gottpoff IE -> LE against hidden var */ + movl %gs:0, %ecx + nop;nop + subl sh1@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* Direct access through %gs */ + + /* @gotntpoff IE against global var */ + movl sG5@gotntpoff(%ebx), %ecx + nop;nop + movl %gs:(%ecx), %edx + nop;nop;nop;nop + + /* @gotntpoff IE->LE against local var */ + movl sl5@gotntpoff(%ebx), %eax + nop;nop + movl %gs:(%eax), %edx + nop;nop;nop;nop + + /* @gotntpoff IE->LE against hidden var */ + movl sh5@gotntpoff(%ebx), %edx + nop;nop + movl %gs:(%edx), %edx + nop;nop;nop;nop + + movl -4(%ebp), %ebx + leave + ret diff --git a/ld/testsuite/ld-i386/tlslib.s b/ld/testsuite/ld-i386/tlslib.s new file mode 100644 index 00000000000..22e1f8d2d55 --- /dev/null +++ b/ld/testsuite/ld-i386/tlslib.s @@ -0,0 +1,17 @@ + .section ".tdata", "awT", @progbits + .globl sG1, sG2, sG3, sG4, sG5, sG6, sG7, sG8 +sG1: .long 513 +sG2: .long 514 +sG3: .long 515 +sG4: .long 516 +sG5: .long 517 +sG6: .long 518 +sG7: .long 519 +sG8: .long 520 + + .text + /* Dummy. */ + .globl ___tls_get_addr + .type ___tls_get_addr,@function +___tls_get_addr: + ret diff --git a/ld/testsuite/ld-i386/tlsnopic.dd b/ld/testsuite/ld-i386/tlsnopic.dd new file mode 100644 index 00000000000..bb9f6e5abfe --- /dev/null +++ b/ld/testsuite/ld-i386/tlsnopic.dd @@ -0,0 +1,161 @@ +#source: tlsnopic1.s +#source: tlsnopic2.s +#as: --32 +#ld: -shared -melf_i386 +#objdump: -drj.text +#target: i?86-*-* + +.*: +file format elf32-i386 + +Disassembly of section .text: + +0+1000 : + 1000: 55[ ]+push %ebp + 1001: 89 e5[ ]+mov %esp,%ebp +# @indntpoff IE against global var + 1003: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 1009: 90[ ]+nop * + 100a: 90[ ]+nop * + 100b: 03 05 94 20 00 00[ ]+add 0x2094,%eax +# ->R_386_TLS_TPOFF sg1 + 1011: 90[ ]+nop * + 1012: 90[ ]+nop * + 1013: 90[ ]+nop * + 1014: 90[ ]+nop * +# @indntpoff direct %gs access IE against global var + 1015: 8b 15 98 20 00 00[ ]+mov 0x2098,%edx +# ->R_386_TLS_TPOFF sg2 + 101b: 90[ ]+nop * + 101c: 90[ ]+nop * + 101d: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 1020: 90[ ]+nop * + 1021: 90[ ]+nop * + 1022: 90[ ]+nop * + 1023: 90[ ]+nop * +# @indntpoff IE against hidden var + 1024: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 102a: 90[ ]+nop * + 102b: 90[ ]+nop * + 102c: 03 05 9c 20 00 00[ ]+add 0x209c,%eax +# ->R_386_TLS_TPOFF [0x14000000] + 1032: 90[ ]+nop * + 1033: 90[ ]+nop * + 1034: 90[ ]+nop * + 1035: 90[ ]+nop * +# @indntpoff direct %gs access IE against hidden var + 1036: 8b 15 a0 20 00 00[ ]+mov 0x20a0,%edx +# ->R_386_TLS_TPOFF [0x18000000] + 103c: 90[ ]+nop * + 103d: 90[ ]+nop * + 103e: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 1041: 90[ ]+nop * + 1042: 90[ ]+nop * + 1043: 90[ ]+nop * + 1044: 90[ ]+nop * +# @indntpoff IE against local var + 1045: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 104b: 90[ ]+nop * + 104c: 90[ ]+nop * + 104d: 03 05 8c 20 00 00[ ]+add 0x208c,%eax +# ->R_386_TLS_TPOFF [0x00000000] + 1053: 90[ ]+nop * + 1054: 90[ ]+nop * + 1055: 90[ ]+nop * + 1056: 90[ ]+nop * +# @indntpoff direct %gs access IE against local var + 1057: 8b 15 90 20 00 00[ ]+mov 0x2090,%edx +# ->R_386_TLS_TPOFF [0x04000000] + 105d: 90[ ]+nop * + 105e: 90[ ]+nop * + 105f: 65 8b 02[ ]+mov %gs:\(%edx\),%eax + 1062: 90[ ]+nop * + 1063: 90[ ]+nop * + 1064: 90[ ]+nop * + 1065: 90[ ]+nop * +# LE @tpoff, global var + 1066: ba fd ff ff ff[ ]+mov \$0xfffffffd,%edx +# R_386_TLS_TPOFF32 sg3 + 106b: 90[ ]+nop * + 106c: 90[ ]+nop * + 106d: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 1073: 90[ ]+nop * + 1074: 90[ ]+nop * + 1075: 29 d0[ ]+sub %edx,%eax + 1077: 90[ ]+nop * + 1078: 90[ ]+nop * + 1079: 90[ ]+nop * + 107a: 90[ ]+nop * +# LE @tpoff, local var + 107b: b8 f7 ff ff ff[ ]+mov \$0xfffffff7,%eax +# R_386_TLS_TPOFF32 + 1080: 90[ ]+nop * + 1081: 90[ ]+nop * + 1082: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 1089: 90[ ]+nop * + 108a: 90[ ]+nop * + 108b: 29 c2[ ]+sub %eax,%edx + 108d: 90[ ]+nop * + 108e: 90[ ]+nop * + 108f: 90[ ]+nop * + 1090: 90[ ]+nop * +# LE @ntpoff, global var + 1091: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + 1097: 90[ ]+nop * + 1098: 90[ ]+nop * + 1099: 8d 90 02 00 00 00[ ]+lea 0x2\(%eax\),%edx +# R_386_TLS_TPOFF sg4 + 109f: 90[ ]+nop * + 10a0: 90[ ]+nop * + 10a1: 90[ ]+nop * + 10a2: 90[ ]+nop * +# LE @ntpoff, hidden var, non-canonical sequence + 10a3: b8 1c 00 00 00[ ]+mov \$0x1c,%eax +# R_386_TLS_TPOFF + 10a8: 90[ ]+nop * + 10a9: 90[ ]+nop * + 10aa: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 10b1: 90[ ]+nop * + 10b2: 90[ ]+nop * + 10b3: 01 c2[ ]+add %eax,%edx + 10b5: 90[ ]+nop * + 10b6: 90[ ]+nop * + 10b7: 90[ ]+nop * + 10b8: 90[ ]+nop * +# LE @ntpoff, local var, non-canonical sequence + 10b9: 65 8b 15 00 00 00 00 mov %gs:0x0,%edx + 10c0: 90[ ]+nop * + 10c1: 90[ ]+nop * + 10c2: 81 c2 0d 00 00 00[ ]+add \$0xd,%edx +# R_386_TLS_TPOFF + 10c8: 90[ ]+nop * + 10c9: 90[ ]+nop * + 10ca: 90[ ]+nop * + 10cb: 90[ ]+nop * +# Direct %gs access +# LE @ntpoff, global var + 10cc: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax +# R_386_TLS_TPOFF sg5 + 10d2: 90[ ]+nop * + 10d3: 90[ ]+nop * + 10d4: 90[ ]+nop * + 10d5: 90[ ]+nop * +# LE @ntpoff, local var + 10d6: 65 8b 15 13 00 00 00 mov %gs:0x13,%edx +# R_386_TLS_TPOFF + 10dd: 90[ ]+nop * + 10de: 90[ ]+nop * + 10df: 90[ ]+nop * + 10e0: 90[ ]+nop * +# LE @ntpoff, hidden var + 10e1: 65 8b 15 21 00 00 00 mov %gs:0x21,%edx +# R_386_TLS_TPOFF + 10e8: 90[ ]+nop * + 10e9: 90[ ]+nop * + 10ea: 90[ ]+nop * + 10eb: 90[ ]+nop * + 10ec: 8b 5d fc[ ]+mov 0xfffffffc\(%ebp\),%ebx + 10ef: c9[ ]+leave * + 10f0: c3[ ]+ret * + 10f1: 90[ ]+nop * + 10f2: 90[ ]+nop * + 10f3: 90[ ]+nop * diff --git a/ld/testsuite/ld-i386/tlsnopic.rd b/ld/testsuite/ld-i386/tlsnopic.rd new file mode 100644 index 00000000000..3c6f3725e07 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsnopic.rd @@ -0,0 +1,133 @@ +#source: tlsnopic1.s +#source: tlsnopic2.s +#as: --32 +#ld: -shared -melf_i386 +#readelf: -Ssrl +#target: i?86-*-* + +There are 14 section headers, starting at offset 0x[0-9a-f]+: + +Section Headers: + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al + \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0 + \[ 1\] \.hash +.* + \[ 2\] \.dynsym +.* + \[ 3\] \.dynstr +.* + \[ 4\] \.rel.dyn +.* + \[ 5\] \.text +PROGBITS +0+1000 .* + \[ 6\] \.data +.* + \[ 7\] .tbss +NOBITS +[0-9a-f]+ [0-9a-f]+ 000024 00 WAT 0 0 1 + \[ 8\] \.dynamic +DYNAMIC +0+2000 .* + \[ 9\] \.got +PROGBITS +0+2080 .* + \[10\] \.bss +.* + \[11\] \.shstrtab +.* + \[12\] \.symtab +.* + \[13\] \.strtab +.* +Key to Flags: +.* +.* +.* + +Elf file type is DYN \(Shared object file\) +Entry point 0x1000 +There are 4 program headers, starting at offset [0-9]+ + +Program Headers: + Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align + LOAD.* + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+ 0x0+24 R +0x1 + + Section to Segment mapping: + Segment Sections... + 00 +.hash .dynsym .dynstr .rel.dyn .text * + 01 +.tbss .dynamic .got * + 02 +.tbss .dynamic * + 03 +.tbss * + +Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 20 entries: + Offset +Info +Type +Sym.Value +Sym. Name +0+100d 0+8 R_386_RELATIVE + +0+1017 0+8 R_386_RELATIVE + +0+102e 0+8 R_386_RELATIVE + +0+1038 0+8 R_386_RELATIVE + +0+104f 0+8 R_386_RELATIVE + +0+1059 0+8 R_386_RELATIVE + +0+1067 0+c25 R_386_TLS_TPOFF32 0+ sg3 +0+107c 0+25 R_386_TLS_TPOFF32 +0+10a4 0+e R_386_TLS_TPOFF + +0+10c4 0+e R_386_TLS_TPOFF + +0+10d9 0+e R_386_TLS_TPOFF + +0+10e4 0+e R_386_TLS_TPOFF + +0+208c 0+e R_386_TLS_TPOFF + +0+2090 0+e R_386_TLS_TPOFF + +0+209c 0+e R_386_TLS_TPOFF + +0+20a0 0+e R_386_TLS_TPOFF + +0+109b 0+d0e R_386_TLS_TPOFF 0+ sg4 +0+10ce 0+f0e R_386_TLS_TPOFF 0+ sg5 +0+2094 0+100e R_386_TLS_TPOFF 0+ sg1 +0+2098 0+120e R_386_TLS_TPOFF 0+ sg2 + + +Symbol table '.dynsym' contains 22 entries: + +Num: +Value Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 NOTYPE LOCAL DEFAULT UND * + +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 * + +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 * + +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 * + +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 * + +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 * + +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 * + +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 * + +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 * + +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 * + +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 * + +11: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + +12: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg3 + +13: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg4 + +14: 0+1000 +0 FUNC +GLOBAL DEFAULT +5 fn3 + +15: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg5 + +16: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg1 + +17: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start + +18: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg2 + +19: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata + +20: 0+2080 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + +21: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end + +Symbol table '.symtab' contains 34 entries: + +Num: +Value Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 NOTYPE LOCAL DEFAULT UND * + +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 * + +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 * + +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 * + +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 * + +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 * + +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 * + +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 * + +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 * + +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 * + +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 * + +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 * + +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 * + +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 * + +14: 0+00 +0 TLS +LOCAL DEFAULT +7 bl1 + +15: 0+04 +0 TLS +LOCAL DEFAULT +7 bl2 + +16: 0+08 +0 TLS +LOCAL DEFAULT +7 bl3 + +17: 0+0c +0 TLS +LOCAL DEFAULT +7 bl4 + +18: 0+10 +0 TLS +LOCAL DEFAULT +7 bl5 + +19: 0+1c +0 TLS +LOCAL HIDDEN +7 sh3 + +20: 0+20 +0 TLS +LOCAL HIDDEN +7 sh4 + +21: 0+14 +0 TLS +LOCAL HIDDEN +7 sh1 + +22: 0+18 +0 TLS +LOCAL HIDDEN +7 sh2 + +23: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + +24: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg3 + +25: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg4 + +26: 0+1000 +0 FUNC +GLOBAL DEFAULT +5 fn3 + +27: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg5 + +28: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg1 + +29: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start + +30: 0+ +0 NOTYPE GLOBAL DEFAULT UND sg2 + +31: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata + +32: 0+2080 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + +33: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end diff --git a/ld/testsuite/ld-i386/tlsnopic.sd b/ld/testsuite/ld-i386/tlsnopic.sd new file mode 100644 index 00000000000..a79226f43df --- /dev/null +++ b/ld/testsuite/ld-i386/tlsnopic.sd @@ -0,0 +1,13 @@ +#source: tlsnopic1.s +#source: tlsnopic2.s +#as: --32 +#ld: -shared -melf_i386 +#objdump: -sj.got +#target: i?86-*-* + +.*: file format elf32-i386 + +Contents of section \.got: + 2080 [0-9a-f]+ 00000000 00000000 00000000 .* + 2090 04000000 00000000 00000000 14000000 .* + 20a0 18000000 +.* diff --git a/ld/testsuite/ld-i386/tlsnopic1.s b/ld/testsuite/ld-i386/tlsnopic1.s new file mode 100644 index 00000000000..32d730bedc8 --- /dev/null +++ b/ld/testsuite/ld-i386/tlsnopic1.s @@ -0,0 +1,107 @@ + .data + /* Align, so that .got is likely at address 0x2080. */ + .balign 4096 + .section ".tbss", "awT", @nobits +bl1: .space 4 +bl2: .space 4 +bl3: .space 4 +bl4: .space 4 +bl5: .space 4 + .text + /* Align, so that fn3 is likely at address 0x1000. */ + .balign 4096 + .globl fn3 + .type fn3,@function +fn3: + pushl %ebp + movl %esp, %ebp + + /* @indntpoff IE against global var */ + movl %gs:0, %eax + nop;nop + addl sg1@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE against global var */ + movl sg2@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* @indntpoff IE against hidden var */ + movl %gs:0, %eax + nop;nop + addl sh1@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE against hidden var */ + movl sh2@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* @indntpoff IE against local var */ + movl %gs:0, %eax + nop;nop + addl bl1@indntpoff, %eax + nop;nop;nop;nop + + /* @indntpoff direct %gs access IE against local var */ + movl bl2@indntpoff, %edx + nop;nop + movl %gs:(%edx), %eax + nop;nop;nop;nop + + /* LE @tpoff, global var */ + movl $-3+sg3@tpoff, %edx + nop;nop + movl %gs:0, %eax + nop;nop + subl %edx, %eax + nop;nop;nop;nop + + /* LE @tpoff, local var */ + movl $-1+bl3@tpoff, %eax + nop;nop + movl %gs:0, %edx + nop;nop + subl %eax, %edx + nop;nop;nop;nop + + /* LE @ntpoff, global var */ + movl %gs:0, %eax + nop;nop + leal 2+sg4@ntpoff(%eax), %edx + nop;nop;nop;nop + + /* LE @ntpoff, hidden var, non-canonical sequence */ + movl $sh3@ntpoff, %eax + nop;nop + movl %gs:0, %edx + nop;nop + addl %eax, %edx + nop;nop;nop;nop + + /* LE @ntpoff, local var, non-canonical sequence */ + movl %gs:0, %edx + nop;nop + addl $bl4@ntpoff+1, %edx + nop;nop;nop;nop + + /* Direct %gs access */ + + /* LE @ntpoff, global var */ + movl %gs:sg5@ntpoff, %eax + nop;nop;nop;nop + + /* LE @ntpoff, local var */ + movl %gs:bl5@ntpoff+3, %edx + nop;nop;nop;nop + + /* LE @ntpoff, hidden var */ + movl %gs:1+sh4@ntpoff, %edx + nop;nop;nop;nop + + movl -4(%ebp), %ebx + leave + ret diff --git a/ld/testsuite/ld-i386/tlsnopic2.s b/ld/testsuite/ld-i386/tlsnopic2.s new file mode 100644 index 00000000000..d9329566e8a --- /dev/null +++ b/ld/testsuite/ld-i386/tlsnopic2.s @@ -0,0 +1,7 @@ + .section ".tbss", "awT", @nobits + .globl sh1, sh2, sh3, sh4 + .hidden sh1, sh2, sh3, sh4 +sh1: .space 4 +sh2: .space 4 +sh3: .space 4 +sh4: .space 4 diff --git a/ld/testsuite/ld-i386/tlspic.dd b/ld/testsuite/ld-i386/tlspic.dd new file mode 100644 index 00000000000..60bcfaa12c6 --- /dev/null +++ b/ld/testsuite/ld-i386/tlspic.dd @@ -0,0 +1,411 @@ +#source: tlspic1.s +#source: tlspic2.s +#as: --32 +#ld: -shared -melf_i386 +#objdump: -drj.text +#target: i?86-*-* + +.*: +file format elf32-i386 + +Disassembly of section .text: + +[0-9a-f]+ : + [0-9a-f]+: 55[ ]+push %ebp + [0-9a-f]+: 89 e5[ ]+mov %esp,%ebp + [0-9a-f]+: 53[ ]+push %ebx + [0-9a-f]+: 50[ ]+push %eax + [0-9a-f]+: e8 00 00 00 00[ ]+call [0-9a-f]+ + [0-9a-f]+: 5b[ ]+pop %ebx + [0-9a-f]+: 81 c3 [0-9a-f ]+[ ]+add \$0x[0-9a-f]+,%ebx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD + [0-9a-f]+: 8d 04 1d 5c 00 00 00 lea 0x5c\(,%ebx,1\),%eax +# ->R_386_TLS_DTPMOD32 sg1 + [0-9a-f]+: e8 cf ff ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE because variable is referenced through @gottpoff too + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 78 00 00 00[ ]+sub 0x78\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sg2 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE because variable is referenced through @gotntpoff too + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 03 83 3c 00 00 00[ ]+add 0x3c\(%ebx\),%eax +# ->R_386_TLS_TPOFF sg3 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE because variable is referenced through @gottpoff and + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 48 00 00 00[ ]+sub 0x48\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sg4 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD against local variable + [0-9a-f]+: 8d 04 1d 10 00 00 00 lea 0x10\(,%ebx,1\),%eax +# ->R_386_TLS_DTPMOD32 [0x00000000 0x20000000] + [0-9a-f]+: e8 8f ff ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against local variable referenced through @gottpoff too + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 18 00 00 00[ ]+sub 0x18\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0xdcffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against local variable referenced through @gotntpoff + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 03 83 1c 00 00 00[ ]+add 0x1c\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x28000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against local variable referenced through @gottpoff and + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 20 00 00 00[ ]+sub 0x20\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0xd4ffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD against hidden and local variable + [0-9a-f]+: 8d 04 1d 7c 00 00 00 lea 0x7c\(,%ebx,1\),%eax +# ->R_386_TLS_DTPMOD32 [0x00000000 0x40000000] + [0-9a-f]+: e8 4f ff ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against hidden and local variable referenced through @gottpoff too + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 84 00 00 00[ ]+sub 0x84\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0xbcffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against hidden and local variable referenced through @gotntpoff too + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 03 83 40 00 00 00[ ]+add 0x40\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x48000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against hidden and local variable referenced through @gottpoff and @gotntpoff too + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 64 00 00 00[ ]+sub 0x64\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0xb4ffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD against hidden but not local variable + [0-9a-f]+: 8d 04 1d 34 00 00 00 lea 0x34\(,%ebx,1\),%eax +# ->R_386_TLS_DTPMOD32 [0x00000000 0x60000000] + [0-9a-f]+: e8 0f ff ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against hidden but not local variable referenced through + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 44 00 00 00[ ]+sub 0x44\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0x9cffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against hidden but not local variable referenced through + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 03 83 6c 00 00 00[ ]+add 0x6c\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x68000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# GD -> IE against hidden but not local variable referenced through + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 2b 83 54 00 00 00[ ]+sub 0x54\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0x94ffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# LD + [0-9a-f]+: 8d 83 2c 00 00 00[ ]+lea 0x2c\(%ebx\),%eax +# ->R_386_TLS_DTPMOD32 [0x00000000 0x00000000] + [0-9a-f]+: e8 d0 fe ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8d 90 20 00 00 00[ ]+lea 0x20\(%eax\),%edx +# sl1 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8d 88 26 00 00 00[ ]+lea 0x26\(%eax\),%ecx +# sl2+2 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# LD against hidden and local variables + [0-9a-f]+: 8d 83 2c 00 00 00[ ]+lea 0x2c\(%ebx\),%eax +# ->R_386_TLS_DTPMOD32 [0x00000000 0x00000000] + [0-9a-f]+: e8 b1 fe ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8d 90 40 00 00 00[ ]+lea 0x40\(%eax\),%edx +# sh1 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8d 88 47 00 00 00[ ]+lea 0x47\(%eax\),%ecx +# sh2+3 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# LD against hidden but not local variables + [0-9a-f]+: 8d 83 2c 00 00 00[ ]+lea 0x2c\(%ebx\),%eax +# ->R_386_TLS_DTPMOD32 [0x00000000 0x00000000] + [0-9a-f]+: e8 92 fe ff ff[ ]+call [0-9a-f]+ <.*0x[0-9a-f]+> +# ->R_386_JUMP_SLOT ___tls_get_addr + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8d 90 60 00 00 00[ ]+lea 0x60\(%eax\),%edx +# sH1 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8d 88 65 00 00 00[ ]+lea 0x65\(%eax\),%ecx +# sH2+1 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against global var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 8b 78 00 00 00[ ]+sub 0x78\(%ebx\),%ecx +# ->R_386_TLS_TPOFF32 sg2 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against global var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 83 48 00 00 00[ ]+sub 0x48\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 sg4 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against global var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 8b 3c 00 00 00[ ]+add 0x3c\(%ebx\),%ecx +# ->R_386_TLS_TPOFF sg3 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against global var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 83 4c 00 00 00[ ]+add 0x4c\(%ebx\),%eax +# ->R_386_TLS_TPOFF sg4 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against local var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 8b 18 00 00 00[ ]+sub 0x18\(%ebx\),%ecx +# ->R_386_TLS_TPOFF32 [0xdcffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against local var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 83 20 00 00 00[ ]+sub 0x20\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0xd4ffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against local var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 8b 1c 00 00 00[ ]+add 0x1c\(%ebx\),%ecx +# ->R_386_TLS_TPOFF [0x28000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against local var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 83 24 00 00 00[ ]+add 0x24\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x2c000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against hidden and local var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 8b 84 00 00 00[ ]+sub 0x84\(%ebx\),%ecx +# ->R_386_TLS_TPOFF32 [0xbcffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against hidden and local var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 83 64 00 00 00[ ]+sub 0x64\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0xb4ffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against hidden and local var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 8b 40 00 00 00[ ]+add 0x40\(%ebx\),%ecx +# ->R_386_TLS_TPOFF [0x48000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against hidden and local var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 83 68 00 00 00[ ]+add 0x68\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x4c000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against hidden but not local var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 8b 44 00 00 00[ ]+sub 0x44\(%ebx\),%ecx +# ->R_386_TLS_TPOFF32 [0x9cffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gottpoff IE against hidden but not local var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 2b 83 54 00 00 00[ ]+sub 0x54\(%ebx\),%eax +# ->R_386_TLS_TPOFF32 [0x94ffffff] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against hidden but not local var + [0-9a-f]+: 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 8b 6c 00 00 00[ ]+add 0x6c\(%ebx\),%ecx +# ->R_386_TLS_TPOFF [0x68000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against hidden but not local var + [0-9a-f]+: 65 a1 00 00 00 00[ ]+mov %gs:0x0,%eax + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 03 83 58 00 00 00[ ]+add 0x58\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x6c000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# Direct access through %gs +# @gotntpoff IE against global var + [0-9a-f]+: 8b 8b 50 00 00 00[ ]+mov 0x50\(%ebx\),%ecx +# ->R_386_TLS_TPOFF sg5 + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 65 8b 11[ ]+mov %gs:\(%ecx\),%edx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against local var + [0-9a-f]+: 8b 83 28 00 00 00[ ]+mov 0x28\(%ebx\),%eax +# ->R_386_TLS_TPOFF [0x30000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 65 8b 10[ ]+mov %gs:\(%eax\),%edx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against hidden and local var + [0-9a-f]+: 8b 93 70 00 00 00[ ]+mov 0x70\(%ebx\),%edx +# ->R_386_TLS_TPOFF [0x50000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 65 8b 12[ ]+mov %gs:\(%edx\),%edx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * +# @gotntpoff IE against hidden but not local var + [0-9a-f]+: 8b 8b 74 00 00 00[ ]+mov 0x74\(%ebx\),%ecx +# ->R_386_TLS_TPOFF [0x70000000] + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 65 8b 11[ ]+mov %gs:\(%ecx\),%edx + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 8b 5d fc[ ]+mov 0xfffffffc\(%ebp\),%ebx + [0-9a-f]+: c9[ ]+leave * + [0-9a-f]+: c3[ ]+ret * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * + [0-9a-f]+: 90[ ]+nop * diff --git a/ld/testsuite/ld-i386/tlspic.rd b/ld/testsuite/ld-i386/tlspic.rd new file mode 100644 index 00000000000..b890e565576 --- /dev/null +++ b/ld/testsuite/ld-i386/tlspic.rd @@ -0,0 +1,174 @@ +#source: tlspic1.s +#source: tlspic2.s +#as: --32 +#ld: -shared -melf_i386 +#readelf: -Ssrl +#target: i?86-*-* + +There are [0-9]+ section headers, starting at offset 0x.*: + +Section Headers: + \[Nr\] Name +Type +Addr +Off +Size +ES Flg Lk Inf Al + \[ 0\] +NULL +0+ 0+ 0+ 0+ +0 +0 +0 + \[ 1\] \.hash +.* + \[ 2\] \.dynsym +.* + \[ 3\] \.dynstr +.* + \[ 4\] \.rel.dyn +.* + \[ 5\] \.rel.plt +.* + \[ 6\] \.plt +.* + \[ 7\] \.text +.* + \[ 8\] \.data +.* + \[ 9\] .tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 000060 00 WAT 0 0 1 + \[10\] .tbss +NOBITS +[0-9aa-f]+ [0-9a-f]+ 000020 00 WAT 0 0 1 + \[11\] \.dynamic +.* + \[12\] \.got +.* + \[13\] \.bss +.* + \[14\] \.shstrtab +.* + \[15\] \.symtab +.* + \[16\] \.strtab +.* +Key to Flags: +.* +.* +.* + +Elf file type is DYN \(Shared object file\) +Entry point 0x[0-9a-f]+ +There are [0-9]+ program headers, starting at offset [0-9]+ + +Program Headers: + Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align + LOAD.* + LOAD.* + DYNAMIC.* + TLS +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x0+60 0x0+80 R +0x1 + + Section to Segment mapping: + Segment Sections... + 00 +.hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text * + 01 +.tdata .tbss .dynamic .got * + 02 +.tbss .dynamic * + 03 +.tdata .tbss * + +Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 26 entries: + Offset +Info +Type +Sym.Value +Sym. Name +[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3 +[0-9a-f]+ +0+25 R_386_TLS_TPOFF32 +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+25 R_386_TLS_TPOFF32 +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3 +[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3 +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+25 R_386_TLS_TPOFF32 +[0-9a-f]+ +0+25 R_386_TLS_TPOFF32 +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+25 R_386_TLS_TPOFF32 +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+0e R_386_TLS_TPOFF * +[0-9a-f]+ +0+23 R_386_TLS_DTPMOD3 +[0-9a-f]+ +0+25 R_386_TLS_TPOFF32 +[0-9a-f]+ +0+100e R_386_TLS_TPOFF 0+8 sg3 +[0-9a-f]+ +0+1125 R_386_TLS_TPOFF32 0+c sg4 +[0-9a-f]+ +0+110e R_386_TLS_TPOFF 0+c sg4 +[0-9a-f]+ +0+120e R_386_TLS_TPOFF 0+10 sg5 +[0-9a-f]+ +0+1323 R_386_TLS_DTPMOD3 0+ sg1 +[0-9a-f]+ +0+1324 R_386_TLS_DTPOFF3 0+ sg1 +[0-9a-f]+ +0+1625 R_386_TLS_TPOFF32 0+4 sg2 + +Relocation section '.rel.plt' at offset 0x480 contains 1 entries: + Offset Info Type Sym.Value Sym. Name +[0-9a-f]+ 0+1c07 R_386_JUMP_SLOT 0+ ___tls_get_addr + +Symbol table '.dynsym' contains 29 entries: + +Num: + Value Size Type + Bind +Vis +Ndx Name + +0: 0+ +0 NOTYPE LOCAL DEFAULT UND * + +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 * + +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 * + +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 * + +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 * + +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 * + +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 * + +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 * + +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 * + +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 * + +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 * + +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 * + +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 * + +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 * + +14: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8 + +15: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + +16: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3 + +17: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4 + +18: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5 + +19: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1 + +20: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1 + +21: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start + +22: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2 + +23: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6 + +24: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7 + +25: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata + +26: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + +27: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end + +28: 0+ +0 NOTYPE GLOBAL DEFAULT UND ___tls_get_addr + +Symbol table '.symtab' contains 56 entries: + +Num: +Value Size Type +Bind +Vis +Ndx Name + +0: 0+ +0 NOTYPE LOCAL DEFAULT UND * + +1: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +1 * + +2: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +2 * + +3: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +3 * + +4: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +4 * + +5: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +5 * + +6: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +6 * + +7: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +7 * + +8: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +8 * + +9: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +9 * + +10: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +10 * + +11: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +11 * + +12: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +12 * + +13: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +13 * + +14: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +14 * + +15: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +15 * + +16: [0-9a-f]+ +0 SECTION LOCAL DEFAULT +16 * + +17: 0+20 +0 TLS +LOCAL DEFAULT +9 sl1 + +18: 0+24 +0 TLS +LOCAL DEFAULT +9 sl2 + +19: 0+28 +0 TLS +LOCAL DEFAULT +9 sl3 + +20: 0+2c +0 TLS +LOCAL DEFAULT +9 sl4 + +21: 0+30 +0 TLS +LOCAL DEFAULT +9 sl5 + +22: 0+34 +0 TLS +LOCAL DEFAULT +9 sl6 + +23: 0+38 +0 TLS +LOCAL DEFAULT +9 sl7 + +24: 0+3c +0 TLS +LOCAL DEFAULT +9 sl8 + +25: 0+60 +0 TLS +LOCAL HIDDEN +10 sH1 + +26: 0+48 +0 TLS +LOCAL HIDDEN +9 sh3 + +27: 0+64 +0 TLS +LOCAL HIDDEN +10 sH2 + +28: 0+78 +0 TLS +LOCAL HIDDEN +10 sH7 + +29: 0+58 +0 TLS +LOCAL HIDDEN +9 sh7 + +30: 0+5c +0 TLS +LOCAL HIDDEN +9 sh8 + +31: 0+6c +0 TLS +LOCAL HIDDEN +10 sH4 + +32: 0+4c +0 TLS +LOCAL HIDDEN +9 sh4 + +33: 0+68 +0 TLS +LOCAL HIDDEN +10 sH3 + +34: 0+50 +0 TLS +LOCAL HIDDEN +9 sh5 + +35: 0+70 +0 TLS +LOCAL HIDDEN +10 sH5 + +36: 0+74 +0 TLS +LOCAL HIDDEN +10 sH6 + +37: 0+7c +0 TLS +LOCAL HIDDEN +10 sH8 + +38: 0+40 +0 TLS +LOCAL HIDDEN +9 sh1 + +39: 0+44 +0 TLS +LOCAL HIDDEN +9 sh2 + +40: 0+54 +0 TLS +LOCAL HIDDEN +9 sh6 + +41: 0+1c +0 TLS +GLOBAL DEFAULT +9 sg8 + +42: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC + +43: 0+8 +0 TLS +GLOBAL DEFAULT +9 sg3 + +44: 0+c +0 TLS +GLOBAL DEFAULT +9 sg4 + +45: 0+10 +0 TLS +GLOBAL DEFAULT +9 sg5 + +46: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1 + +47: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT +7 fn1 + +48: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start + +49: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2 + +50: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6 + +51: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7 + +52: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata + +53: [0-9a-f]+ +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_ + +54: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end + +55: 0+ +0 NOTYPE GLOBAL DEFAULT UND ___tls_get_addr diff --git a/ld/testsuite/ld-i386/tlspic.sd b/ld/testsuite/ld-i386/tlspic.sd new file mode 100644 index 00000000000..e51848ddd86 --- /dev/null +++ b/ld/testsuite/ld-i386/tlspic.sd @@ -0,0 +1,19 @@ +#source: tlspic1.s +#source: tlspic2.s +#as: --32 +#ld: -shared -melf_i386 +#objdump: -sj.got +#target: i?86-*-* + +.*: file format elf32-i386 + +Contents of section \.got: + [0-9a-f]+ [0-9a-f]+ 00000000 00000000 [0-9a-f]+ .* + [0-9a-f]+ 00000000 20000000 dcffffff 28000000 .* + [0-9a-f]+ d4ffffff 2c000000 30000000 00000000 .* + [0-9a-f]+ 00000000 00000000 60000000 00000000 .* + [0-9a-f]+ 48000000 9cffffff 00000000 00000000 .* + [0-9a-f]+ 00000000 94ffffff 6c000000 00000000 .* + [0-9a-f]+ 00000000 b4ffffff 4c000000 68000000 .* + [0-9a-f]+ 50000000 70000000 00000000 00000000 .* + [0-9a-f]+ 40000000 bcffffff +.* diff --git a/ld/testsuite/ld-i386/tlspic.td b/ld/testsuite/ld-i386/tlspic.td new file mode 100644 index 00000000000..1291584da46 --- /dev/null +++ b/ld/testsuite/ld-i386/tlspic.td @@ -0,0 +1,16 @@ +#source: tlspic1.s +#source: tlspic2.s +#as: --32 +#ld: -shared -melf_i386 +#objdump: -sj.tdata +#target: i?86-*-* + +.*: file format elf32-i386 + +Contents of section \.tdata: + [0-9a-f]+ 11000000 12000000 13000000 14000000 .* + [0-9a-f]+ 15000000 16000000 17000000 18000000 .* + [0-9a-f]+ 41000000 42000000 43000000 44000000 .* + [0-9a-f]+ 45000000 46000000 47000000 48000000 .* + [0-9a-f]+ 01010000 02010000 03010000 04010000 .* + [0-9a-f]+ 05010000 06010000 07010000 08010000 .* diff --git a/ld/testsuite/ld-i386/tlspic1.s b/ld/testsuite/ld-i386/tlspic1.s new file mode 100644 index 00000000000..9dcb3b73722 --- /dev/null +++ b/ld/testsuite/ld-i386/tlspic1.s @@ -0,0 +1,282 @@ + .section ".tdata", "awT", @progbits + .globl sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8 + .globl sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8 + .hidden sh1, sh2, sh3, sh4, sh5, sh6, sh7, sh8 +sg1: .long 17 +sg2: .long 18 +sg3: .long 19 +sg4: .long 20 +sg5: .long 21 +sg6: .long 22 +sg7: .long 23 +sg8: .long 24 +sl1: .long 65 +sl2: .long 66 +sl3: .long 67 +sl4: .long 68 +sl5: .long 69 +sl6: .long 70 +sl7: .long 71 +sl8: .long 72 +sh1: .long 257 +sh2: .long 258 +sh3: .long 259 +sh4: .long 260 +sh5: .long 261 +sh6: .long 262 +sh7: .long 263 +sh8: .long 264 + .text + .globl fn1 + .type fn1,@function +fn1: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %eax + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + nop;nop;nop;nop + + /* GD */ + leal sg1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE because variable is referenced through @gottpoff too */ + leal sg2@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE because variable is referenced through @gotntpoff too */ + leal sg3@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE because variable is referenced through @gottpoff and + @gotntpoff too */ + leal sg4@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD against local variable */ + leal sl1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against local variable referenced through @gottpoff too */ + leal sl2@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against local variable referenced through @gotntpoff + too */ + leal sl3@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against local variable referenced through @gottpoff and + @gotntpoff too */ + leal sl4@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD against hidden and local variable */ + leal sh1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against hidden and local variable referenced through + @gottpoff too */ + leal sh2@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against hidden and local variable referenced through + @gotntpoff too */ + leal sh3@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against hidden and local variable referenced through + @gottpoff and @gotntpoff too */ + leal sh4@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD against hidden but not local variable */ + leal sH1@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against hidden but not local variable referenced through + @gottpoff too */ + leal sH2@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against hidden but not local variable referenced through + @gotntpoff too */ + leal sH3@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* GD -> IE against hidden but not local variable referenced through + @gottpoff and @gotntpoff too */ + leal sH4@tlsgd(,%ebx,1), %eax + call ___tls_get_addr@plt + nop;nop;nop;nop + + /* LD */ + leal sl1@tlsldm(%ebx), %eax + call ___tls_get_addr@PLT + nop;nop + leal sl1@dtpoff(%eax), %edx + nop;nop + leal 2+sl2@dtpoff(%eax), %ecx + nop;nop;nop;nop + + /* LD against hidden and local variables */ + leal sh1@tlsldm(%ebx), %eax + call ___tls_get_addr@PLT + nop;nop + leal sh1@dtpoff(%eax), %edx + nop;nop + leal sh2@dtpoff+3(%eax), %ecx + nop;nop;nop;nop + + /* LD against hidden but not local variables */ + leal sH1@tlsldm(%ebx), %eax + call ___tls_get_addr@PLT + nop;nop + leal sH1@dtpoff(%eax), %edx + nop;nop + leal sH2@dtpoff+1(%eax), %ecx + nop;nop + + /* @gottpoff IE against global var */ + movl %gs:0, %ecx + nop;nop + subl sg2@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gottpoff IE against global var */ + movl %gs:0, %eax + nop;nop + subl sg4@gottpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gotntpoff IE against global var */ + movl %gs:0, %ecx + nop;nop + addl sg3@gotntpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gotntpoff IE against global var */ + movl %gs:0, %eax + nop;nop + addl sg4@gotntpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gottpoff IE against local var */ + movl %gs:0, %ecx + nop;nop + subl sl2@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gottpoff IE against local var */ + movl %gs:0, %eax + nop;nop + subl sl4@gottpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gotntpoff IE against local var */ + movl %gs:0, %ecx + nop;nop + addl sl3@gotntpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gotntpoff IE against local var */ + movl %gs:0, %eax + nop;nop + addl sl4@gotntpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gottpoff IE against hidden and local var */ + movl %gs:0, %ecx + nop;nop + subl sh2@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gottpoff IE against hidden and local var */ + movl %gs:0, %eax + nop;nop + subl sh4@gottpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gotntpoff IE against hidden and local var */ + movl %gs:0, %ecx + nop;nop + addl sh3@gotntpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gotntpoff IE against hidden and local var */ + movl %gs:0, %eax + nop;nop + addl sh4@gotntpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gottpoff IE against hidden but not local var */ + movl %gs:0, %ecx + nop;nop + subl sH2@gottpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gottpoff IE against hidden but not local var */ + movl %gs:0, %eax + nop;nop + subl sH4@gottpoff(%ebx), %eax + nop;nop;nop;nop + + /* @gotntpoff IE against hidden but not local var */ + movl %gs:0, %ecx + nop;nop + addl sH3@gotntpoff(%ebx), %ecx + nop;nop;nop;nop + + /* @gotntpoff IE against hidden but not local var */ + movl %gs:0, %eax + nop;nop + addl sH4@gotntpoff(%ebx), %eax + nop;nop;nop;nop + + /* Direct access through %gs */ + + /* @gotntpoff IE against global var */ + movl sg5@gotntpoff(%ebx), %ecx + nop;nop + movl %gs:(%ecx), %edx + nop;nop;nop;nop + + /* @gotntpoff IE against local var */ + movl sl5@gotntpoff(%ebx), %eax + nop;nop + movl %gs:(%eax), %edx + nop;nop;nop;nop + + /* @gotntpoff IE against hidden and local var */ + movl sh5@gotntpoff(%ebx), %edx + nop;nop + movl %gs:(%edx), %edx + nop;nop;nop;nop + + /* @gotntpoff IE against hidden but not local var */ + movl sH5@gotntpoff(%ebx), %ecx + nop;nop + movl %gs:(%ecx), %edx + nop;nop;nop;nop + + movl -4(%ebp), %ebx + leave + ret diff --git a/ld/testsuite/ld-i386/tlspic2.s b/ld/testsuite/ld-i386/tlspic2.s new file mode 100644 index 00000000000..5513f9b5851 --- /dev/null +++ b/ld/testsuite/ld-i386/tlspic2.s @@ -0,0 +1,11 @@ + .section ".tbss", "awT", @nobits + .globl sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8 + .hidden sH1, sH2, sH3, sH4, sH5, sH6, sH7, sH8 +sH1: .space 4 +sH2: .space 4 +sH3: .space 4 +sH4: .space 4 +sH5: .space 4 +sH6: .space 4 +sH7: .space 4 +sH8: .space 4 -- 2.30.2