mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
bfd/
* reloc.c: Add x86-64 TLS relocs. * bfd-in2.h, libbfd.h: Rebuilt. * elf64-x86-64.c (x86_64_elf_howto): Fix size fields for 32-bit relocs. Add TLS relocs. (x86_64_reloc_map): Add TLS relocs. (elf64_x86_64_info_to_howto): Adjust for added TLS relocs. (struct elf64_x86_64_link_hash_entry): Add tls_type field. (GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE): Define. (elf64_x86_64_hash_entry): Define. (struct elf64_x86_64_obj_tdata): New. (elf64_x86_64_tdata, elf64_x86_64_local_got_tls_type): Define. (struct elf64_x86_64_link_hash_table): Add tls_ld_got. (link_hash_newfunc): Initialize tls_type. (elf64_x86_64_link_hash_table_create): Initialize tls_ld_got. (elf64_x86_64_copy_indirect_symbol): Swap tls_type if necessary. (elf64_x86_64_mkobject): New. (elf64_x86_64_elf_object_p): Allocate struct elf64_x86_64_obj_tdata. (elf64_x86_64_tls_transition): New. (elf64_x86_64_check_relocs): Add r_type variable and use it. Handle TLS relocs. (elf64_x86_64_gc_sweep_hook): Handle TLS relocs. (allocate_dynrelocs): Allocate GOT space for TLS relocs. (elf64_x86_64_size_dynamic_sections): Likewise. (dtpoff_base, tpoff): New. (elf64_x86_64_relocate_section): Handle TLS relocs. (elf64_x86_64_finish_dynamic_symbol): Only handle non-TLS GOT entries. (bfd_elf64_mkobject): Define. * elf32-i386.c (elf_i386_check_relocs) [R_386_TLS_LE]: Set DF_STATIC_TLS if shared. gas/ * config/tc-i386.c (tc_i386_fix_adjustable): Add x86-64 TLS relocs. Define them if not BFD_ASSEMBLER. (lex_got): Handle @tlsgd, @dtpoff and @tpoff in 64-bit mode, add @tlsld. (md_apply_fix3): No addend for BFD_RELOC_X86_64_TLSGD, BFD_RELOC_X86_64_TLSLD and BFD_RELOC_X86_64_GOTTPOFF. (tc_gen_reloc): Handle x86-64 TLS relocs. include/ * elf/x86-64.h: Add TLS relocs. ld/testsuite/ * lib/ld-lib.exp (run_ld_link_tests): Add. * ld-sh/sh64/sh64.exp (run_ld_link_tests, regexp_diff, file_contents): Remove. (sh64tests): Add 6th field to the tests array. * ld-i386/i386.exp (run_ld_link_tests): Remove. * ld-x86-64/x86-64.exp: New. * ld-x86-64/tlsbin.dd: New test. * ld-x86-64/tlsbinpic.s: New test. * ld-x86-64/tlsbin.rd: New test. * ld-x86-64/tlsbin.s: New test. * ld-x86-64/tlsbin.sd: New test. * ld-x86-64/tlsbin.td: New test. * ld-x86-64/tlslib.s: New test. * ld-x86-64/tlspic1.s: New test. * ld-x86-64/tlspic2.s: New test. * ld-x86-64/tlspic.dd: New test. * ld-x86-64/tlspic.rd: New test. * ld-x86-64/tlspic.sd: New test. * ld-x86-64/tlspic.td: New test.
This commit is contained in:
parent
43b2fdc74c
commit
bffbf9406f
@ -1,3 +1,37 @@
|
||||
2002-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* reloc.c: Add x86-64 TLS relocs.
|
||||
* bfd-in2.h, libbfd.h: Rebuilt.
|
||||
* elf64-x86-64.c (x86_64_elf_howto): Fix size fields for 32-bit
|
||||
relocs. Add TLS relocs.
|
||||
(x86_64_reloc_map): Add TLS relocs.
|
||||
(elf64_x86_64_info_to_howto): Adjust for added TLS relocs.
|
||||
(struct elf64_x86_64_link_hash_entry): Add tls_type field.
|
||||
(GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE): Define.
|
||||
(elf64_x86_64_hash_entry): Define.
|
||||
(struct elf64_x86_64_obj_tdata): New.
|
||||
(elf64_x86_64_tdata, elf64_x86_64_local_got_tls_type): Define.
|
||||
(struct elf64_x86_64_link_hash_table): Add tls_ld_got.
|
||||
(link_hash_newfunc): Initialize tls_type.
|
||||
(elf64_x86_64_link_hash_table_create): Initialize tls_ld_got.
|
||||
(elf64_x86_64_copy_indirect_symbol): Swap tls_type if necessary.
|
||||
(elf64_x86_64_mkobject): New.
|
||||
(elf64_x86_64_elf_object_p): Allocate struct elf64_x86_64_obj_tdata.
|
||||
(elf64_x86_64_tls_transition): New.
|
||||
(elf64_x86_64_check_relocs): Add r_type variable and use it.
|
||||
Handle TLS relocs.
|
||||
(elf64_x86_64_gc_sweep_hook): Handle TLS relocs.
|
||||
(allocate_dynrelocs): Allocate GOT space for TLS relocs.
|
||||
(elf64_x86_64_size_dynamic_sections): Likewise.
|
||||
(dtpoff_base, tpoff): New.
|
||||
(elf64_x86_64_relocate_section): Handle TLS relocs.
|
||||
(elf64_x86_64_finish_dynamic_symbol): Only handle non-TLS GOT
|
||||
entries.
|
||||
(bfd_elf64_mkobject): Define.
|
||||
|
||||
* elf32-i386.c (elf_i386_check_relocs) [R_386_TLS_LE]: Set
|
||||
DF_STATIC_TLS if shared.
|
||||
|
||||
2002-09-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
|
||||
* elfxx-mips.c (_bfd_mips_elf_fake_sections): Don't emit unneeded
|
||||
|
@ -2286,6 +2286,14 @@ to compensate for the borrow when the low bits are added. */
|
||||
BFD_RELOC_X86_64_RELATIVE,
|
||||
BFD_RELOC_X86_64_GOTPCREL,
|
||||
BFD_RELOC_X86_64_32S,
|
||||
BFD_RELOC_X86_64_DTPMOD64,
|
||||
BFD_RELOC_X86_64_DTPOFF64,
|
||||
BFD_RELOC_X86_64_TPOFF64,
|
||||
BFD_RELOC_X86_64_TLSGD,
|
||||
BFD_RELOC_X86_64_TLSLD,
|
||||
BFD_RELOC_X86_64_DTPOFF32,
|
||||
BFD_RELOC_X86_64_GOTTPOFF,
|
||||
BFD_RELOC_X86_64_TPOFF32,
|
||||
|
||||
/* ns32k relocations */
|
||||
BFD_RELOC_NS32K_IMM_8,
|
||||
|
@ -1057,6 +1057,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
case R_386_TLS_LE:
|
||||
if (!info->shared)
|
||||
break;
|
||||
info->flags |= DF_STATIC_TLS;
|
||||
/* Fall through */
|
||||
|
||||
case R_386_32:
|
||||
|
@ -40,16 +40,16 @@ static reloc_howto_type x86_64_elf_howto_table[] =
|
||||
HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_64", false, MINUS_ONE, MINUS_ONE,
|
||||
false),
|
||||
HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed,
|
||||
HOWTO(R_X86_64_PC32, 0, 2, 32, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0xffffffff, 0xffffffff,
|
||||
true),
|
||||
HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed,
|
||||
HOWTO(R_X86_64_GOT32, 0, 2, 32, false, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0xffffffff, 0xffffffff,
|
||||
false),
|
||||
HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed,
|
||||
HOWTO(R_X86_64_PLT32, 0, 2, 32, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0xffffffff, 0xffffffff,
|
||||
true),
|
||||
HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield,
|
||||
HOWTO(R_X86_64_COPY, 0, 2, 32, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0xffffffff, 0xffffffff,
|
||||
false),
|
||||
HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_bitfield,
|
||||
@ -61,13 +61,13 @@ static reloc_howto_type x86_64_elf_howto_table[] =
|
||||
HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, MINUS_ONE,
|
||||
MINUS_ONE, false),
|
||||
HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true,0 , complain_overflow_signed,
|
||||
HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0xffffffff,
|
||||
0xffffffff, true),
|
||||
HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned,
|
||||
HOWTO(R_X86_64_32, 0, 2, 32, false, 0, complain_overflow_unsigned,
|
||||
bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff,
|
||||
false),
|
||||
HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed,
|
||||
HOWTO(R_X86_64_32S, 0, 2, 32, false, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_32S", false, 0xffffffff, 0xffffffff,
|
||||
false),
|
||||
HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
|
||||
@ -78,6 +78,30 @@ static reloc_howto_type x86_64_elf_howto_table[] =
|
||||
bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false),
|
||||
HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0xff, 0xff, true),
|
||||
HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", false, MINUS_ONE,
|
||||
MINUS_ONE, false),
|
||||
HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", false, MINUS_ONE,
|
||||
MINUS_ONE, false),
|
||||
HOWTO(R_X86_64_TPOFF64, 0, 4, 64, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_TPOFF64", false, MINUS_ONE,
|
||||
MINUS_ONE, false),
|
||||
HOWTO(R_X86_64_TLSGD, 0, 2, 32, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_TLSGD", false, 0xffffffff,
|
||||
0xffffffff, true),
|
||||
HOWTO(R_X86_64_TLSLD, 0, 2, 32, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_TLSLD", false, 0xffffffff,
|
||||
0xffffffff, true),
|
||||
HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, false, 0, complain_overflow_bitfield,
|
||||
bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", false, 0xffffffff,
|
||||
0xffffffff, false),
|
||||
HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, true, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", false, 0xffffffff,
|
||||
0xffffffff, true),
|
||||
HOWTO(R_X86_64_TPOFF32, 0, 2, 32, false, 0, complain_overflow_signed,
|
||||
bfd_elf_generic_reloc, "R_X86_64_TPOFF32", false, 0xffffffff,
|
||||
0xffffffff, false),
|
||||
|
||||
/* GNU extension to record C++ vtable hierarchy. */
|
||||
HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, false, 0, complain_overflow_dont,
|
||||
@ -114,6 +138,14 @@ static const struct elf_reloc_map x86_64_reloc_map[] =
|
||||
{ BFD_RELOC_16_PCREL, R_X86_64_PC16, },
|
||||
{ BFD_RELOC_8, R_X86_64_8, },
|
||||
{ BFD_RELOC_8_PCREL, R_X86_64_PC8, },
|
||||
{ BFD_RELOC_X86_64_DTPMOD64, R_X86_64_DTPMOD64, },
|
||||
{ BFD_RELOC_X86_64_DTPOFF64, R_X86_64_DTPOFF64, },
|
||||
{ BFD_RELOC_X86_64_TPOFF64, R_X86_64_TPOFF64, },
|
||||
{ BFD_RELOC_X86_64_TLSGD, R_X86_64_TLSGD, },
|
||||
{ BFD_RELOC_X86_64_TLSLD, R_X86_64_TLSLD, },
|
||||
{ BFD_RELOC_X86_64_DTPOFF32, R_X86_64_DTPOFF32, },
|
||||
{ BFD_RELOC_X86_64_GOTTPOFF, R_X86_64_GOTTPOFF, },
|
||||
{ BFD_RELOC_X86_64_TPOFF32, R_X86_64_TPOFF32, },
|
||||
{ BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, },
|
||||
{ BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, },
|
||||
};
|
||||
@ -128,6 +160,10 @@ static boolean elf64_x86_64_grok_psinfo
|
||||
PARAMS ((bfd *, Elf_Internal_Note *));
|
||||
static struct bfd_link_hash_table *elf64_x86_64_link_hash_table_create
|
||||
PARAMS ((bfd *));
|
||||
static int elf64_x86_64_tls_transition
|
||||
PARAMS ((struct bfd_link_info *, int, int));
|
||||
static boolean elf64_x86_64_mkobject
|
||||
PARAMS((bfd *));
|
||||
static boolean elf64_x86_64_elf_object_p PARAMS ((bfd *abfd));
|
||||
static boolean create_got_section
|
||||
PARAMS((bfd *, struct bfd_link_info *));
|
||||
@ -158,6 +194,10 @@ static boolean readonly_dynrelocs
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf64_x86_64_size_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static bfd_vma dtpoff_base
|
||||
PARAMS ((struct bfd_link_info *));
|
||||
static bfd_vma tpoff
|
||||
PARAMS ((struct bfd_link_info *, bfd_vma));
|
||||
static boolean elf64_x86_64_relocate_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
|
||||
@ -198,13 +238,13 @@ elf64_x86_64_info_to_howto (abfd, cache_ptr, dst)
|
||||
r_type = ELF64_R_TYPE (dst->r_info);
|
||||
if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)
|
||||
{
|
||||
BFD_ASSERT (r_type <= (unsigned int) R_X86_64_PC8);
|
||||
BFD_ASSERT (r_type <= (unsigned int) R_X86_64_TPOFF32);
|
||||
i = r_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
|
||||
i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_PC8 - 1);
|
||||
i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1);
|
||||
}
|
||||
cache_ptr->howto = &x86_64_elf_howto_table[i];
|
||||
BFD_ASSERT (r_type == cache_ptr->howto->type);
|
||||
@ -343,8 +383,32 @@ struct elf64_x86_64_link_hash_entry
|
||||
|
||||
/* Track dynamic relocs copied for this symbol. */
|
||||
struct elf64_x86_64_dyn_relocs *dyn_relocs;
|
||||
|
||||
#define GOT_UNKNOWN 0
|
||||
#define GOT_NORMAL 1
|
||||
#define GOT_TLS_GD 2
|
||||
#define GOT_TLS_IE 3
|
||||
unsigned char tls_type;
|
||||
};
|
||||
|
||||
#define elf64_x86_64_hash_entry(ent) \
|
||||
((struct elf64_x86_64_link_hash_entry *)(ent))
|
||||
|
||||
struct elf64_x86_64_obj_tdata
|
||||
{
|
||||
struct elf_obj_tdata root;
|
||||
|
||||
/* tls_type for each local got entry. */
|
||||
char *local_got_tls_type;
|
||||
};
|
||||
|
||||
#define elf64_x86_64_tdata(abfd) \
|
||||
((struct elf64_x86_64_obj_tdata *) (abfd)->tdata.any)
|
||||
|
||||
#define elf64_x86_64_local_got_tls_type(abfd) \
|
||||
(elf64_x86_64_tdata (abfd)->local_got_tls_type)
|
||||
|
||||
|
||||
/* x86-64 ELF linker hash table. */
|
||||
|
||||
struct elf64_x86_64_link_hash_table
|
||||
@ -360,6 +424,11 @@ struct elf64_x86_64_link_hash_table
|
||||
asection *sdynbss;
|
||||
asection *srelbss;
|
||||
|
||||
union {
|
||||
bfd_signed_vma refcount;
|
||||
bfd_vma offset;
|
||||
} tls_ld_got;
|
||||
|
||||
/* Small local sym to section mapping cache. */
|
||||
struct sym_sec_cache sym_sec;
|
||||
};
|
||||
@ -395,6 +464,7 @@ link_hash_newfunc (entry, table, string)
|
||||
|
||||
eh = (struct elf64_x86_64_link_hash_entry *) entry;
|
||||
eh->dyn_relocs = NULL;
|
||||
eh->tls_type = GOT_UNKNOWN;
|
||||
}
|
||||
|
||||
return entry;
|
||||
@ -427,6 +497,7 @@ elf64_x86_64_link_hash_table_create (abfd)
|
||||
ret->sdynbss = NULL;
|
||||
ret->srelbss = NULL;
|
||||
ret->sym_sec.abfd = NULL;
|
||||
ret->tls_ld_got.refcount = 0;
|
||||
|
||||
return &ret->elf.root;
|
||||
}
|
||||
@ -538,18 +609,67 @@ elf64_x86_64_copy_indirect_symbol (bed, dir, ind)
|
||||
eind->dyn_relocs = NULL;
|
||||
}
|
||||
|
||||
if (ind->root.type == bfd_link_hash_indirect
|
||||
&& dir->got.refcount <= 0)
|
||||
{
|
||||
edir->tls_type = eind->tls_type;
|
||||
eind->tls_type = GOT_UNKNOWN;
|
||||
}
|
||||
|
||||
_bfd_elf_link_hash_copy_indirect (bed, dir, ind);
|
||||
}
|
||||
|
||||
static boolean
|
||||
elf64_x86_64_elf_object_p (abfd)
|
||||
elf64_x86_64_mkobject (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
bfd_size_type amt = sizeof (struct elf64_x86_64_obj_tdata);
|
||||
abfd->tdata.any = bfd_zalloc (abfd, amt);
|
||||
if (abfd->tdata.any == NULL)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
elf64_x86_64_elf_object_p (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
/* Allocate our special target data. */
|
||||
struct elf64_x86_64_obj_tdata *new_tdata;
|
||||
bfd_size_type amt = sizeof (struct elf64_x86_64_obj_tdata);
|
||||
new_tdata = bfd_zalloc (abfd, amt);
|
||||
if (new_tdata == NULL)
|
||||
return false;
|
||||
new_tdata->root = *abfd->tdata.elf_obj_data;
|
||||
abfd->tdata.any = new_tdata;
|
||||
/* Set the right machine number for an x86-64 elf64 file. */
|
||||
bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
elf64_x86_64_tls_transition (info, r_type, is_local)
|
||||
struct bfd_link_info *info;
|
||||
int r_type;
|
||||
int is_local;
|
||||
{
|
||||
if (info->shared)
|
||||
return r_type;
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_X86_64_TLSGD:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
if (is_local)
|
||||
return R_X86_64_TPOFF32;
|
||||
return R_X86_64_GOTTPOFF;
|
||||
case R_X86_64_TLSLD:
|
||||
return R_X86_64_TPOFF32;
|
||||
}
|
||||
|
||||
return r_type;
|
||||
}
|
||||
|
||||
/* Look through the relocs for a section during the first phase, and
|
||||
calculate needed space in the global offset table, procedure
|
||||
linkage table, and dynamic reloc sections. */
|
||||
@ -580,10 +700,12 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
|
||||
rel_end = relocs + sec->reloc_count;
|
||||
for (rel = relocs; rel < rel_end; rel++)
|
||||
{
|
||||
unsigned int r_type;
|
||||
unsigned long r_symndx;
|
||||
struct elf_link_hash_entry *h;
|
||||
|
||||
r_symndx = ELF64_R_SYM (rel->r_info);
|
||||
r_type = ELF64_R_TYPE (rel->r_info);
|
||||
|
||||
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
|
||||
{
|
||||
@ -598,38 +720,103 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
|
||||
else
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
|
||||
switch (ELF64_R_TYPE (rel->r_info))
|
||||
r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
|
||||
switch (r_type)
|
||||
{
|
||||
case R_X86_64_TLSLD:
|
||||
htab->tls_ld_got.refcount += 1;
|
||||
goto create_got;
|
||||
|
||||
case R_X86_64_TPOFF32:
|
||||
if (info->shared)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: relocation %s can not be used when making a shared object; recompile with -fPIC"),
|
||||
bfd_archive_filename (abfd),
|
||||
x86_64_elf_howto_table[r_type].name);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_X86_64_GOTTPOFF:
|
||||
if (info->shared)
|
||||
info->flags |= DF_STATIC_TLS;
|
||||
/* Fall through */
|
||||
|
||||
case R_X86_64_GOT32:
|
||||
case R_X86_64_GOTPCREL:
|
||||
case R_X86_64_TLSGD:
|
||||
/* This symbol requires a global offset table entry. */
|
||||
if (h != NULL)
|
||||
{
|
||||
h->got.refcount += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_signed_vma *local_got_refcounts;
|
||||
{
|
||||
int tls_type, old_tls_type;
|
||||
|
||||
/* This is a global offset table entry for a local symbol. */
|
||||
local_got_refcounts = elf_local_got_refcounts (abfd);
|
||||
if (local_got_refcounts == NULL)
|
||||
{
|
||||
bfd_size_type size;
|
||||
switch (r_type)
|
||||
{
|
||||
default: tls_type = GOT_NORMAL; break;
|
||||
case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
|
||||
case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
|
||||
}
|
||||
|
||||
size = symtab_hdr->sh_info;
|
||||
size *= sizeof (bfd_signed_vma);
|
||||
local_got_refcounts = ((bfd_signed_vma *)
|
||||
bfd_zalloc (abfd, size));
|
||||
if (local_got_refcounts == NULL)
|
||||
if (h != NULL)
|
||||
{
|
||||
h->got.refcount += 1;
|
||||
old_tls_type = elf64_x86_64_hash_entry (h)->tls_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_signed_vma *local_got_refcounts;
|
||||
|
||||
/* This is a global offset table entry for a local symbol. */
|
||||
local_got_refcounts = elf_local_got_refcounts (abfd);
|
||||
if (local_got_refcounts == NULL)
|
||||
{
|
||||
bfd_size_type size;
|
||||
|
||||
size = symtab_hdr->sh_info;
|
||||
size *= sizeof (bfd_signed_vma) + sizeof (char);
|
||||
local_got_refcounts = ((bfd_signed_vma *)
|
||||
bfd_zalloc (abfd, size));
|
||||
if (local_got_refcounts == NULL)
|
||||
return false;
|
||||
elf_local_got_refcounts (abfd) = local_got_refcounts;
|
||||
elf64_x86_64_local_got_tls_type (abfd)
|
||||
= (char *) (local_got_refcounts + symtab_hdr->sh_info);
|
||||
}
|
||||
local_got_refcounts[r_symndx] += 1;
|
||||
old_tls_type
|
||||
= elf64_x86_64_local_got_tls_type (abfd) [r_symndx];
|
||||
}
|
||||
|
||||
/* 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))
|
||||
{
|
||||
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 ? h->root.root.string : "<local>");
|
||||
return false;
|
||||
elf_local_got_refcounts (abfd) = local_got_refcounts;
|
||||
}
|
||||
local_got_refcounts[r_symndx] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (old_tls_type != tls_type)
|
||||
{
|
||||
if (h != NULL)
|
||||
elf64_x86_64_hash_entry (h)->tls_type = tls_type;
|
||||
else
|
||||
elf64_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
|
||||
}
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
//case R_X86_64_GOTPCREL:
|
||||
create_got:
|
||||
if (htab->sgot == NULL)
|
||||
{
|
||||
if (htab->elf.dynobj == NULL)
|
||||
@ -671,7 +858,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: relocation %s can not be used when making a shared object; recompile with -fPIC"),
|
||||
bfd_archive_filename (abfd),
|
||||
x86_64_elf_howto_table[ELF64_R_TYPE (rel->r_info)].name);
|
||||
x86_64_elf_howto_table[r_type].name);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return false;
|
||||
}
|
||||
@ -719,9 +906,9 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
|
||||
symbol. */
|
||||
if ((info->shared
|
||||
&& (sec->flags & SEC_ALLOC) != 0
|
||||
&& (((ELF64_R_TYPE (rel->r_info) != R_X86_64_PC8)
|
||||
&& (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC16)
|
||||
&& (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC32))
|
||||
&& (((r_type != R_X86_64_PC8)
|
||||
&& (r_type != R_X86_64_PC16)
|
||||
&& (r_type != R_X86_64_PC32))
|
||||
|| (h != NULL
|
||||
&& (! info->symbolic
|
||||
|| h->root.type == bfd_link_hash_defweak
|
||||
@ -822,9 +1009,9 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
|
||||
}
|
||||
|
||||
p->count += 1;
|
||||
if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8
|
||||
|| ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16
|
||||
|| ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32)
|
||||
if (r_type == R_X86_64_PC8
|
||||
|| r_type == R_X86_64_PC16
|
||||
|| r_type == R_X86_64_PC32)
|
||||
p->pc_count += 1;
|
||||
}
|
||||
break;
|
||||
@ -905,6 +1092,7 @@ elf64_x86_64_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;
|
||||
@ -915,8 +1103,18 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)
|
||||
|
||||
relend = relocs + sec->reloc_count;
|
||||
for (rel = relocs; rel < relend; rel++)
|
||||
switch (ELF64_R_TYPE (rel->r_info))
|
||||
switch ((r_type = elf64_x86_64_tls_transition (info,
|
||||
ELF64_R_TYPE (rel->r_info),
|
||||
ELF64_R_SYM (rel->r_info)
|
||||
>= symtab_hdr->sh_info)))
|
||||
{
|
||||
case R_X86_64_TLSLD:
|
||||
if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
|
||||
elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
|
||||
break;
|
||||
|
||||
case R_X86_64_TLSGD:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_GOT32:
|
||||
case R_X86_64_GOTPCREL:
|
||||
r_symndx = ELF64_R_SYM (rel->r_info);
|
||||
@ -1226,10 +1424,18 @@ allocate_dynrelocs (h, inf)
|
||||
h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
|
||||
}
|
||||
|
||||
if (h->got.refcount > 0)
|
||||
/* If R_X86_64_GOTTPOFF symbol is now local to the binary,
|
||||
make it a R_X86_64_TPOFF32 requiring no GOT entry. */
|
||||
if (h->got.refcount > 0
|
||||
&& !info->shared
|
||||
&& h->dynindx == -1
|
||||
&& elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
|
||||
h->got.offset = (bfd_vma) -1;
|
||||
else if (h->got.refcount > 0)
|
||||
{
|
||||
asection *s;
|
||||
boolean dyn;
|
||||
int tls_type = elf64_x86_64_hash_entry (h)->tls_type;
|
||||
|
||||
/* Make sure this symbol is output as a dynamic symbol.
|
||||
Undefined weak syms won't yet be marked as dynamic. */
|
||||
@ -1243,8 +1449,19 @@ allocate_dynrelocs (h, inf)
|
||||
s = htab->sgot;
|
||||
h->got.offset = s->_raw_size;
|
||||
s->_raw_size += GOT_ENTRY_SIZE;
|
||||
/* R_X86_64_TLSGD needs 2 consecutive GOT slots. */
|
||||
if (tls_type == GOT_TLS_GD)
|
||||
s->_raw_size += GOT_ENTRY_SIZE;
|
||||
dyn = htab->elf.dynamic_sections_created;
|
||||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
|
||||
/* R_X86_64_TLSGD needs one dynamic relocation if local symbol
|
||||
and two if global.
|
||||
R_X86_64_GOTTPOFF needs one dynamic relocation. */
|
||||
if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
|
||||
|| tls_type == GOT_TLS_IE)
|
||||
htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
|
||||
else if (tls_type == GOT_TLS_GD)
|
||||
htab->srelgot->_raw_size += 2 * sizeof (Elf64_External_Rela);
|
||||
else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
|
||||
htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
|
||||
}
|
||||
else
|
||||
@ -1390,6 +1607,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
|
||||
{
|
||||
bfd_signed_vma *local_got;
|
||||
bfd_signed_vma *end_local_got;
|
||||
char *local_tls_type;
|
||||
bfd_size_type locsymcount;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
asection *srel;
|
||||
@ -1432,15 +1650,20 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
|
||||
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
|
||||
locsymcount = symtab_hdr->sh_info;
|
||||
end_local_got = local_got + locsymcount;
|
||||
local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
|
||||
s = htab->sgot;
|
||||
srel = htab->srelgot;
|
||||
for (; local_got < end_local_got; ++local_got)
|
||||
for (; local_got < end_local_got; ++local_got, ++local_tls_type)
|
||||
{
|
||||
if (*local_got > 0)
|
||||
{
|
||||
*local_got = s->_raw_size;
|
||||
s->_raw_size += GOT_ENTRY_SIZE;
|
||||
if (info->shared)
|
||||
if (*local_tls_type == GOT_TLS_GD)
|
||||
s->_raw_size += GOT_ENTRY_SIZE;
|
||||
if (info->shared
|
||||
|| *local_tls_type == GOT_TLS_GD
|
||||
|| *local_tls_type == GOT_TLS_IE)
|
||||
srel->_raw_size += sizeof (Elf64_External_Rela);
|
||||
}
|
||||
else
|
||||
@ -1448,6 +1671,17 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
|
||||
}
|
||||
}
|
||||
|
||||
if (htab->tls_ld_got.refcount > 0)
|
||||
{
|
||||
/* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
|
||||
relocs. */
|
||||
htab->tls_ld_got.offset = htab->sgot->_raw_size;
|
||||
htab->sgot->_raw_size += 2 * GOT_ENTRY_SIZE;
|
||||
htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);
|
||||
}
|
||||
else
|
||||
htab->tls_ld_got.offset = -1;
|
||||
|
||||
/* Allocate global sym .plt and .got entries, and space for global
|
||||
sym dynamic relocs. */
|
||||
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
|
||||
@ -1558,6 +1792,38 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return the base VMA address which should be subtracted from real addresses
|
||||
when resolving @dtpoff relocation.
|
||||
This is PT_TLS segment p_vaddr. */
|
||||
|
||||
static bfd_vma
|
||||
dtpoff_base (info)
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
/* If tls_segment is NULL, we should have signalled an error already. */
|
||||
if (elf_hash_table (info)->tls_segment == NULL)
|
||||
return 0;
|
||||
return elf_hash_table (info)->tls_segment->start;
|
||||
}
|
||||
|
||||
/* Return the relocation value for @tpoff relocation
|
||||
if STT_TLS virtual address is ADDRESS. */
|
||||
|
||||
static bfd_vma
|
||||
tpoff (info, address)
|
||||
struct bfd_link_info *info;
|
||||
bfd_vma address;
|
||||
{
|
||||
struct elf_link_tls_segment *tls_segment
|
||||
= elf_hash_table (info)->tls_segment;
|
||||
|
||||
/* If tls_segment is NULL, we should have signalled an error already. */
|
||||
if (tls_segment == NULL)
|
||||
return 0;
|
||||
return address - align_power (tls_segment->size, tls_segment->align)
|
||||
- tls_segment->start;
|
||||
}
|
||||
|
||||
/* Relocate an x86_64 ELF section. */
|
||||
|
||||
static boolean
|
||||
@ -1591,7 +1857,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
relend = relocs + input_section->reloc_count;
|
||||
for (; rel < relend; rel++)
|
||||
{
|
||||
int r_type;
|
||||
unsigned int r_type;
|
||||
reloc_howto_type *howto;
|
||||
unsigned long r_symndx;
|
||||
struct elf_link_hash_entry *h;
|
||||
@ -1601,13 +1867,14 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
bfd_vma relocation;
|
||||
boolean unresolved_reloc;
|
||||
bfd_reloc_status_type r;
|
||||
int tls_type;
|
||||
|
||||
r_type = ELF64_R_TYPE (rel->r_info);
|
||||
if (r_type == (int) R_X86_64_GNU_VTINHERIT
|
||||
|| r_type == (int) R_X86_64_GNU_VTENTRY)
|
||||
continue;
|
||||
|
||||
if (r_type < 0 || r_type >= R_X86_64_max)
|
||||
if (r_type >= R_X86_64_max)
|
||||
{
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return false;
|
||||
@ -1933,6 +2200,313 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
break;
|
||||
|
||||
case R_X86_64_TLSGD:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
|
||||
tls_type = GOT_UNKNOWN;
|
||||
if (h == NULL && local_got_offsets)
|
||||
tls_type = elf64_x86_64_local_got_tls_type (input_bfd) [r_symndx];
|
||||
else if (h != NULL)
|
||||
{
|
||||
tls_type = elf64_x86_64_hash_entry (h)->tls_type;
|
||||
if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
|
||||
r_type = R_X86_64_TPOFF32;
|
||||
}
|
||||
if (r_type == R_X86_64_TLSGD)
|
||||
{
|
||||
if (tls_type == GOT_TLS_IE)
|
||||
r_type = R_X86_64_GOTTPOFF;
|
||||
}
|
||||
|
||||
if (r_type == R_X86_64_TPOFF32)
|
||||
{
|
||||
BFD_ASSERT (! unresolved_reloc);
|
||||
if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
|
||||
{
|
||||
unsigned int i;
|
||||
static unsigned char tlsgd[7]
|
||||
= { 0x66, 0x66, 0x66, 0x66, 0x48, 0x8d, 0x3d };
|
||||
|
||||
/* GD->LE transition.
|
||||
.long 0x66666666; leaq foo@tlsgd(%rip), %rdi
|
||||
callq __tls_get_addr@plt
|
||||
Change it into:
|
||||
movq %fs:0, %rax
|
||||
leaq foo@tpoff(%rax), %rax */
|
||||
BFD_ASSERT (rel->r_offset >= 7);
|
||||
for (i = 0; i < 7; i++)
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||
contents + rel->r_offset - 7 + i)
|
||||
== tlsgd[i]);
|
||||
BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||
contents + rel->r_offset + 4)
|
||||
== 0xe8);
|
||||
BFD_ASSERT (rel + 1 < relend);
|
||||
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||
memcpy (contents + rel->r_offset - 7,
|
||||
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
|
||||
16);
|
||||
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
||||
contents + rel->r_offset + 5);
|
||||
/* Skip R_X86_64_PLT32. */
|
||||
rel++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int val, type, reg;
|
||||
|
||||
/* IE->LE transition:
|
||||
Originally it can be one of:
|
||||
movq foo@gottpoff(%rip), %reg
|
||||
addq foo@gottpoff(%rip), %reg
|
||||
We change it into:
|
||||
movq $foo, %reg
|
||||
leaq foo(%reg), %reg
|
||||
addq $foo, %reg. */
|
||||
BFD_ASSERT (rel->r_offset >= 3);
|
||||
val = bfd_get_8 (input_bfd, contents + rel->r_offset - 3);
|
||||
BFD_ASSERT (val == 0x48 || val == 0x4c);
|
||||
type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
|
||||
BFD_ASSERT (type == 0x8b || type == 0x03);
|
||||
reg = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
|
||||
BFD_ASSERT ((reg & 0xc7) == 5);
|
||||
reg >>= 3;
|
||||
BFD_ASSERT (rel->r_offset + 4 <= input_section->_raw_size);
|
||||
if (type == 0x8b)
|
||||
{
|
||||
/* movq */
|
||||
if (val == 0x4c)
|
||||
bfd_put_8 (output_bfd, 0x49,
|
||||
contents + rel->r_offset - 3);
|
||||
bfd_put_8 (output_bfd, 0xc7,
|
||||
contents + rel->r_offset - 2);
|
||||
bfd_put_8 (output_bfd, 0xc0 | reg,
|
||||
contents + rel->r_offset - 1);
|
||||
}
|
||||
else if (reg == 4)
|
||||
{
|
||||
/* addq -> addq - addressing with %rsp/%r12 is
|
||||
special */
|
||||
if (val == 0x4c)
|
||||
bfd_put_8 (output_bfd, 0x49,
|
||||
contents + rel->r_offset - 3);
|
||||
bfd_put_8 (output_bfd, 0x81,
|
||||
contents + rel->r_offset - 2);
|
||||
bfd_put_8 (output_bfd, 0xc0 | reg,
|
||||
contents + rel->r_offset - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* addq -> leaq */
|
||||
if (val == 0x4c)
|
||||
bfd_put_8 (output_bfd, 0x4d,
|
||||
contents + rel->r_offset - 3);
|
||||
bfd_put_8 (output_bfd, 0x8d,
|
||||
contents + rel->r_offset - 2);
|
||||
bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
|
||||
contents + rel->r_offset - 1);
|
||||
}
|
||||
bfd_put_32 (output_bfd, tpoff (info, relocation),
|
||||
contents + rel->r_offset);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (htab->sgot == NULL)
|
||||
abort ();
|
||||
|
||||
if (h != NULL)
|
||||
off = h->got.offset;
|
||||
else
|
||||
{
|
||||
if (local_got_offsets == NULL)
|
||||
abort ();
|
||||
|
||||
off = local_got_offsets[r_symndx];
|
||||
}
|
||||
|
||||
if ((off & 1) != 0)
|
||||
off &= ~1;
|
||||
else
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
Elf64_External_Rela *loc;
|
||||
int dr_type, indx;
|
||||
|
||||
if (htab->srelgot == NULL)
|
||||
abort ();
|
||||
|
||||
outrel.r_offset = (htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset + off);
|
||||
|
||||
indx = h && h->dynindx != -1 ? h->dynindx : 0;
|
||||
if (r_type == R_X86_64_TLSGD)
|
||||
dr_type = R_X86_64_DTPMOD64;
|
||||
else
|
||||
dr_type = R_X86_64_TPOFF64;
|
||||
|
||||
bfd_put_64 (output_bfd, 0, htab->sgot->contents + off);
|
||||
outrel.r_addend = 0;
|
||||
if (dr_type == R_X86_64_TPOFF64 && indx == 0)
|
||||
outrel.r_addend = relocation - dtpoff_base (info);
|
||||
outrel.r_info = ELF64_R_INFO (indx, dr_type);
|
||||
|
||||
loc = (Elf64_External_Rela *) htab->srelgot->contents;
|
||||
loc += htab->srelgot->reloc_count++;
|
||||
bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
|
||||
|
||||
if (r_type == R_X86_64_TLSGD)
|
||||
{
|
||||
if (indx == 0)
|
||||
{
|
||||
BFD_ASSERT (! unresolved_reloc);
|
||||
bfd_put_64 (output_bfd,
|
||||
relocation - dtpoff_base (info),
|
||||
htab->sgot->contents + off + GOT_ENTRY_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_put_64 (output_bfd, 0,
|
||||
htab->sgot->contents + off + GOT_ENTRY_SIZE);
|
||||
outrel.r_info = ELF64_R_INFO (indx,
|
||||
R_X86_64_DTPOFF64);
|
||||
outrel.r_offset += GOT_ENTRY_SIZE;
|
||||
htab->srelgot->reloc_count++;
|
||||
loc++;
|
||||
bfd_elf64_swap_reloca_out (output_bfd, &outrel,
|
||||
loc);
|
||||
}
|
||||
}
|
||||
|
||||
if (h != NULL)
|
||||
h->got.offset |= 1;
|
||||
else
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
}
|
||||
|
||||
if (off >= (bfd_vma) -2)
|
||||
abort ();
|
||||
if (r_type == ELF64_R_TYPE (rel->r_info))
|
||||
{
|
||||
relocation = htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset + off;
|
||||
unresolved_reloc = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i;
|
||||
static unsigned char tlsgd[7]
|
||||
= { 0x66, 0x66, 0x66, 0x66, 0x48, 0x8d, 0x3d };
|
||||
|
||||
/* GD->IE transition.
|
||||
.long 0x66666666; leaq foo@tlsgd(%rip), %rdi
|
||||
callq __tls_get_addr@plt
|
||||
Change it into:
|
||||
movq %fs:0, %rax
|
||||
addq foo@gottpoff(%rip), %rax */
|
||||
BFD_ASSERT (rel->r_offset >= 7);
|
||||
for (i = 0; i < 7; i++)
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||
contents + rel->r_offset - 7 + i)
|
||||
== tlsgd[i]);
|
||||
BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd,
|
||||
contents + rel->r_offset + 4)
|
||||
== 0xe8);
|
||||
BFD_ASSERT (rel + 1 < relend);
|
||||
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||
memcpy (contents + rel->r_offset - 7,
|
||||
"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
|
||||
16);
|
||||
|
||||
relocation = (htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset + off
|
||||
- rel->r_offset
|
||||
- input_section->output_section->vma
|
||||
- input_section->output_offset
|
||||
- 9);
|
||||
bfd_put_32 (output_bfd, relocation,
|
||||
contents + rel->r_offset + 5);
|
||||
/* Skip R_X86_64_PLT32. */
|
||||
rel++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_X86_64_TLSLD:
|
||||
if (! info->shared)
|
||||
{
|
||||
/* LD->LE transition:
|
||||
Ensure it is:
|
||||
leaq foo@tlsld(%rip), %rdi; call __tls_get_addr@plt.
|
||||
We change it into:
|
||||
.word 0x6666; .byte 0x66; movl %fs:0, %rax. */
|
||||
BFD_ASSERT (rel->r_offset >= 3);
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 3)
|
||||
== 0x48);
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 2)
|
||||
== 0x8d);
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 1)
|
||||
== 0x3d);
|
||||
BFD_ASSERT (rel->r_offset + 9 <= input_section->_raw_size);
|
||||
BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
|
||||
== 0xe8);
|
||||
BFD_ASSERT (rel + 1 < relend);
|
||||
BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
|
||||
memcpy (contents + rel->r_offset - 3,
|
||||
"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
|
||||
/* Skip R_X86_64_PLT32. */
|
||||
rel++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (htab->sgot == NULL)
|
||||
abort ();
|
||||
|
||||
off = htab->tls_ld_got.offset;
|
||||
if (off & 1)
|
||||
off &= ~1;
|
||||
else
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
Elf64_External_Rela *loc;
|
||||
|
||||
if (htab->srelgot == NULL)
|
||||
abort ();
|
||||
|
||||
outrel.r_offset = (htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset + off);
|
||||
|
||||
bfd_put_64 (output_bfd, 0,
|
||||
htab->sgot->contents + off);
|
||||
bfd_put_64 (output_bfd, 0,
|
||||
htab->sgot->contents + off + GOT_ENTRY_SIZE);
|
||||
outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
|
||||
outrel.r_addend = 0;
|
||||
loc = (Elf64_External_Rela *) htab->srelgot->contents;
|
||||
loc += htab->srelgot->reloc_count++;
|
||||
bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
|
||||
htab->tls_ld_got.offset |= 1;
|
||||
}
|
||||
relocation = htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset + off;
|
||||
unresolved_reloc = false;
|
||||
break;
|
||||
|
||||
case R_X86_64_DTPOFF32:
|
||||
if (info->shared)
|
||||
relocation -= dtpoff_base (info);
|
||||
else
|
||||
relocation = tpoff (info, relocation);
|
||||
break;
|
||||
|
||||
case R_X86_64_TPOFF32:
|
||||
BFD_ASSERT (! info->shared);
|
||||
relocation = tpoff (info, relocation);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2087,13 +2661,15 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
}
|
||||
}
|
||||
|
||||
if (h->got.offset != (bfd_vma) -1)
|
||||
if (h->got.offset != (bfd_vma) -1
|
||||
&& elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_GD
|
||||
&& elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
|
||||
{
|
||||
Elf_Internal_Rela rela;
|
||||
Elf64_External_Rela *loc;
|
||||
|
||||
/* This symbol has an entry in the global offset table. Set it
|
||||
up. */
|
||||
up. */
|
||||
|
||||
if (htab->sgot == NULL || htab->srelgot == NULL)
|
||||
abort ();
|
||||
@ -2351,5 +2927,6 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
|
||||
#define elf_backend_relocate_section elf64_x86_64_relocate_section
|
||||
#define elf_backend_size_dynamic_sections elf64_x86_64_size_dynamic_sections
|
||||
#define elf_backend_object_p elf64_x86_64_elf_object_p
|
||||
#define bfd_elf64_mkobject elf64_x86_64_mkobject
|
||||
|
||||
#include "elf64-target.h"
|
||||
|
@ -819,6 +819,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_X86_64_RELATIVE",
|
||||
"BFD_RELOC_X86_64_GOTPCREL",
|
||||
"BFD_RELOC_X86_64_32S",
|
||||
"BFD_RELOC_X86_64_DTPMOD64",
|
||||
"BFD_RELOC_X86_64_DTPOFF64",
|
||||
"BFD_RELOC_X86_64_TPOFF64",
|
||||
"BFD_RELOC_X86_64_TLSGD",
|
||||
"BFD_RELOC_X86_64_TLSLD",
|
||||
"BFD_RELOC_X86_64_DTPOFF32",
|
||||
"BFD_RELOC_X86_64_GOTTPOFF",
|
||||
"BFD_RELOC_X86_64_TPOFF32",
|
||||
"BFD_RELOC_NS32K_IMM_8",
|
||||
"BFD_RELOC_NS32K_IMM_16",
|
||||
"BFD_RELOC_NS32K_IMM_32",
|
||||
|
16
bfd/reloc.c
16
bfd/reloc.c
@ -2165,6 +2165,22 @@ ENUMX
|
||||
BFD_RELOC_X86_64_GOTPCREL
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_32S
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_DTPMOD64
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_DTPOFF64
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_TPOFF64
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_TLSGD
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_TLSLD
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_DTPOFF32
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_GOTTPOFF
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_TPOFF32
|
||||
ENUMDOC
|
||||
x86-64/elf relocations
|
||||
|
||||
|
@ -1,3 +1,13 @@
|
||||
2002-09-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/tc-i386.c (tc_i386_fix_adjustable): Add x86-64 TLS relocs.
|
||||
Define them if not BFD_ASSEMBLER.
|
||||
(lex_got): Handle @tlsgd, @dtpoff and @tpoff in 64-bit mode, add
|
||||
@tlsld.
|
||||
(md_apply_fix3): No addend for BFD_RELOC_X86_64_TLSGD,
|
||||
BFD_RELOC_X86_64_TLSLD and BFD_RELOC_X86_64_GOTTPOFF.
|
||||
(tc_gen_reloc): Handle x86-64 TLS relocs.
|
||||
|
||||
2002-09-27 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/tc-avr.c (md_apply_fix3): Reinstate code handling pcrel
|
||||
|
@ -1235,6 +1235,11 @@ tc_i386_fix_adjustable (fixP)
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_TLSGD
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_TLSLD
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF32
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
|
||||
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|
||||
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
|
||||
return 0;
|
||||
@ -1263,6 +1268,11 @@ tc_i386_fix_adjustable (fixP)
|
||||
#define BFD_RELOC_X86_64_PLT32 0
|
||||
#define BFD_RELOC_X86_64_GOT32 0
|
||||
#define BFD_RELOC_X86_64_GOTPCREL 0
|
||||
#define BFD_RELOC_X86_64_TLSGD 0
|
||||
#define BFD_RELOC_X86_64_TLSLD 0
|
||||
#define BFD_RELOC_X86_64_DTPOFF32 0
|
||||
#define BFD_RELOC_X86_64_GOTTPOFF 0
|
||||
#define BFD_RELOC_X86_64_TPOFF32 0
|
||||
#endif
|
||||
|
||||
static int intel_float_operand PARAMS ((const char *mnemonic));
|
||||
@ -3484,12 +3494,13 @@ lex_got (reloc, adjust)
|
||||
{ "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
|
||||
{ "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
|
||||
{ "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
|
||||
{ "TLSGD", { BFD_RELOC_386_TLS_GD, 0, 0 } },
|
||||
{ "TLSGD", { BFD_RELOC_386_TLS_GD, 0, BFD_RELOC_X86_64_TLSGD } },
|
||||
{ "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } },
|
||||
{ "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, 0 } },
|
||||
{ "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, 0 } },
|
||||
{ "TLSLD", { 0, 0, BFD_RELOC_X86_64_TLSLD } },
|
||||
{ "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, BFD_RELOC_X86_64_GOTTPOFF } },
|
||||
{ "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, BFD_RELOC_X86_64_TPOFF32 } },
|
||||
{ "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } },
|
||||
{ "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, 0 } },
|
||||
{ "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, BFD_RELOC_X86_64_DTPOFF32 } },
|
||||
{ "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 } }
|
||||
@ -4665,6 +4676,9 @@ md_apply_fix3 (fixP, valP, seg)
|
||||
case BFD_RELOC_386_TLS_IE:
|
||||
case BFD_RELOC_386_TLS_GOTIE:
|
||||
case BFD_RELOC_X86_64_GOT32:
|
||||
case BFD_RELOC_X86_64_TLSGD:
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
value = 0; /* Fully resolved at runtime. No addend. */
|
||||
break;
|
||||
|
||||
@ -5149,6 +5163,11 @@ tc_gen_reloc (section, fixp)
|
||||
case BFD_RELOC_386_TLS_LE_32:
|
||||
case BFD_RELOC_386_TLS_LE:
|
||||
case BFD_RELOC_X86_64_32S:
|
||||
case BFD_RELOC_X86_64_TLSGD:
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
case BFD_RELOC_X86_64_DTPOFF32:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_TPOFF32:
|
||||
case BFD_RELOC_RVA:
|
||||
case BFD_RELOC_VTABLE_ENTRY:
|
||||
case BFD_RELOC_VTABLE_INHERIT:
|
||||
@ -5226,6 +5245,9 @@ tc_gen_reloc (section, fixp)
|
||||
case BFD_RELOC_X86_64_PLT32:
|
||||
case BFD_RELOC_X86_64_GOT32:
|
||||
case BFD_RELOC_X86_64_GOTPCREL:
|
||||
case BFD_RELOC_X86_64_TLSGD:
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
rel->addend = fixp->fx_offset - fixp->fx_size;
|
||||
break;
|
||||
default:
|
||||
|
@ -1,3 +1,7 @@
|
||||
2002-09-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/x86-64.h: Add TLS relocs.
|
||||
|
||||
2002-09-26 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* regs/: Delete directory.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* x86_64 ELF support for BFD.
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Jan Hubicka <jh@suse.cz>
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
@ -25,22 +25,30 @@
|
||||
|
||||
START_RELOC_NUMBERS (elf_x86_64_reloc_type)
|
||||
RELOC_NUMBER (R_X86_64_NONE, 0) /* No reloc */
|
||||
RELOC_NUMBER (R_X86_64_64, 1) /* Direct 64 bit */
|
||||
RELOC_NUMBER (R_X86_64_64, 1) /* Direct 64 bit */
|
||||
RELOC_NUMBER (R_X86_64_PC32, 2) /* PC relative 32 bit signed */
|
||||
RELOC_NUMBER (R_X86_64_GOT32, 3) /* 32 bit GOT entry */
|
||||
RELOC_NUMBER (R_X86_64_PLT32, 4) /* 32 bit PLT address */
|
||||
RELOC_NUMBER (R_X86_64_COPY, 5) /* Copy symbol at runtime */
|
||||
RELOC_NUMBER (R_X86_64_GLOB_DAT, 6) /* Create GOT entry */
|
||||
RELOC_NUMBER (R_X86_64_JUMP_SLOT, 7) /* Create PLT entry */
|
||||
RELOC_NUMBER (R_X86_64_JUMP_SLOT,7) /* Create PLT entry */
|
||||
RELOC_NUMBER (R_X86_64_RELATIVE, 8) /* Adjust by program base */
|
||||
RELOC_NUMBER (R_X86_64_GOTPCREL, 9) /* 32 bit signed pc relative
|
||||
offset to GOT */
|
||||
RELOC_NUMBER (R_X86_64_32, 10) /* Direct 32 bit zero extended */
|
||||
RELOC_NUMBER (R_X86_64_32S, 11) /* Direct 32 bit sign extended */
|
||||
RELOC_NUMBER (R_X86_64_16, 12) /* Direct 16 bit zero extended */
|
||||
RELOC_NUMBER (R_X86_64_32, 10) /* Direct 32 bit zero extended */
|
||||
RELOC_NUMBER (R_X86_64_32S, 11) /* Direct 32 bit sign extended */
|
||||
RELOC_NUMBER (R_X86_64_16, 12) /* Direct 16 bit zero extended */
|
||||
RELOC_NUMBER (R_X86_64_PC16, 13) /* 16 bit sign extended pc relative*/
|
||||
RELOC_NUMBER (R_X86_64_8, 14) /* Direct 8 bit sign extended */
|
||||
RELOC_NUMBER (R_X86_64_PC8, 15) /* 8 bit sign extended pc relative*/
|
||||
RELOC_NUMBER (R_X86_64_8, 14) /* Direct 8 bit sign extended */
|
||||
RELOC_NUMBER (R_X86_64_PC8, 15) /* 8 bit sign extended pc relative*/
|
||||
RELOC_NUMBER (R_X86_64_DTPMOD64, 16) /* ID of module containing symbol */
|
||||
RELOC_NUMBER (R_X86_64_DTPOFF64, 17) /* Offset in TLS block */
|
||||
RELOC_NUMBER (R_X86_64_TPOFF64, 18) /* Offset in initial TLS block */
|
||||
RELOC_NUMBER (R_X86_64_TLSGD, 19) /* PC relative offset to GD GOT block */
|
||||
RELOC_NUMBER (R_X86_64_TLSLD, 20) /* PC relative offset to LD GOT block */
|
||||
RELOC_NUMBER (R_X86_64_DTPOFF32, 21) /* Offset in TLS block */
|
||||
RELOC_NUMBER (R_X86_64_GOTTPOFF, 22) /* PC relative offset to IE GOT entry */
|
||||
RELOC_NUMBER (R_X86_64_TPOFF32, 23) /* Offset in initial TLS block */
|
||||
RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */
|
||||
RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */
|
||||
END_RELOC_NUMBERS (R_X86_64_max)
|
||||
|
@ -1,3 +1,25 @@
|
||||
2002-09-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* lib/ld-lib.exp (run_ld_link_tests): Add.
|
||||
* ld-sh/sh64/sh64.exp (run_ld_link_tests, regexp_diff,
|
||||
file_contents): Remove.
|
||||
(sh64tests): Add 6th field to the tests array.
|
||||
* ld-i386/i386.exp (run_ld_link_tests): Remove.
|
||||
* ld-x86-64/x86-64.exp: New.
|
||||
* ld-x86-64/tlsbin.dd: New test.
|
||||
* ld-x86-64/tlsbinpic.s: New test.
|
||||
* ld-x86-64/tlsbin.rd: New test.
|
||||
* ld-x86-64/tlsbin.s: New test.
|
||||
* ld-x86-64/tlsbin.sd: New test.
|
||||
* ld-x86-64/tlsbin.td: New test.
|
||||
* ld-x86-64/tlslib.s: New test.
|
||||
* ld-x86-64/tlspic1.s: New test.
|
||||
* ld-x86-64/tlspic2.s: New test.
|
||||
* ld-x86-64/tlspic.dd: New test.
|
||||
* ld-x86-64/tlspic.rd: New test.
|
||||
* ld-x86-64/tlspic.sd: New test.
|
||||
* ld-x86-64/tlspic.td: New test.
|
||||
|
||||
2002-09-21 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-undefined/undefined.exp: Adjust function test.
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Expect script for ld-i386 tests
|
||||
# Copyright (C) 2000, 2001, 2002 Free Software Foundation
|
||||
# Copyright (C) 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
|
||||
@ -26,11 +26,6 @@ if { !([istarget "i?86-*-elf*"]
|
||||
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
|
||||
@ -59,126 +54,4 @@ set i386tests {
|
||||
{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
|
||||
|
@ -23,18 +23,14 @@ if ![istarget sh64-*-*] {
|
||||
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.
|
||||
# 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).
|
||||
|
||||
# Note that the contents dump is the same for "inter-file datalabel
|
||||
# references, 64-bit ABI" as for 32-bit ABI and ELF so we re-use it.
|
||||
@ -42,323 +38,89 @@ if ![info exists readelf] then {
|
||||
set sh64tests {
|
||||
{"SH64 linking, 64-bit ABI" "-mshelf64"
|
||||
"--abi=64" {sh64-1.s sh64-2.s}
|
||||
{{objdump -sr abi64.sd} {objdump -x abi64.xd}}}
|
||||
{{objdump -sr abi64.sd} {objdump -x abi64.xd}} "abi64.bin" }
|
||||
{"SH64 linking, 64-bit ABI, -no-expand" "-mshelf64"
|
||||
"--abi=64 -no-expand" {sh64-1.s sh64-2.s}
|
||||
{{objdump -sr abixx-noexp.sd}}}
|
||||
{{objdump -sr abixx-noexp.sd}} "abi64-noexp.bin" }
|
||||
{"SH64 linking, 32-bit ABI" "-mshelf32"
|
||||
"--abi=32" {sh64-1.s sh64-2.s}
|
||||
{{objdump -sr abi32.sd} {objdump -x abi32.xd}}}
|
||||
{{objdump -sr abi32.sd} {objdump -x abi32.xd}} "abi32.bin" }
|
||||
{"SH64 linking, 32-bit ABI, -no-expand" "-mshelf32"
|
||||
"--abi=32 -no-expand" {sh64-1.s sh64-2.s}
|
||||
{{objdump -sr abixx-noexp.sd}}}
|
||||
{{objdump -sr abixx-noexp.sd}} "abi32-noexp.bin" }
|
||||
{"SH64 linking, single multi-ISA object" "-mshelf32"
|
||||
"--abi=32" {shmix-1.s}
|
||||
{{objdump -sr mix1.sd} {objdump -x mix1.xd}}}
|
||||
{{objdump -sr mix1.sd} {objdump -x mix1.xd}} "mix1.bin" }
|
||||
{"SH64 linking, single multi-ISA object, -no-expand" "-mshelf32"
|
||||
"--abi=32 -no-expand" {shmix-1.s}
|
||||
{{objdump -sr mix1-noexp.sd}}}
|
||||
{{objdump -sr mix1-noexp.sd}} "mix1-noexp.bin" }
|
||||
{"SH64 linking, two different-ISA objects" "-mshelf32"
|
||||
"--abi=32" {shmix-2.s shmix-3.s}
|
||||
{{objdump -sr mix2.sd} {objdump -x mix2.xd}}}
|
||||
{{objdump -sr mix2.sd} {objdump -x mix2.xd}} "mix2.bin" }
|
||||
{"SH64 linking, two different-ISA objects, -no-expand" "-mshelf32"
|
||||
"--abi=32 -no-expand" {shmix-2.s shmix-3.s}
|
||||
{{objdump -sr mix2-noexp.sd}}}
|
||||
{{objdump -sr mix2-noexp.sd}} "mix2-noexp.bin" }
|
||||
{"SH64 linking, single SHcompact" "-mshelf32"
|
||||
"--isa=SHcompact" {shcmp-1.s}
|
||||
{{objdump -sr cmpct1.sd} {objdump -x cmpct1.xd}}}
|
||||
{{objdump -sr cmpct1.sd} {objdump -x cmpct1.xd}} "cmpct1.bin" }
|
||||
{"SH64 inter-file datalabel references, 64-bit ABI" "-mshelf64"
|
||||
"--abi=64" {shdl-1.s shdl-2.s}
|
||||
{{objdump -sr shdl64.sd} {objdump -x shdl64.xd}}}
|
||||
{{objdump -sr shdl64.sd} {objdump -x shdl64.xd}} "shdl64.bin" }
|
||||
{"SH64 inter-file datalabel references, 32-bit ABI" "-mshelf32"
|
||||
"--abi=32" {shdl-1.s shdl-2.s}
|
||||
{{objdump -sr shdl64.sd} {objdump -x shdl32.xd}}}
|
||||
{{objdump -sr shdl64.sd} {objdump -x shdl32.xd}} "shdl32.bin" }
|
||||
{"SH64 inter-file datalabel references and gc-sections, 32-bit ABI" "-mshelf32 --gc-sections"
|
||||
"--abi=32" {dlsection-1.s }
|
||||
{{objdump -sr dlsection.sd}}}
|
||||
{{objdump -sr dlsection.sd}} "dlsection32.bin" }
|
||||
{"SH64 inter-file datalabel references and gc-sections, 64-bit ABI" "-mshelf64 --gc-sections"
|
||||
"--abi=64" {dlsection-1.s }
|
||||
{{objdump -sr dlsection.sd}}}
|
||||
{{objdump -sr dlsection.sd}} "dlsection64.bin" }
|
||||
{"SH64 simple partial linking, 32-bit ABI" "-mshelf32 -r"
|
||||
"--abi=32" {rel-1.s rel-2.s}
|
||||
{{objdump -sx rel32.xd}}}
|
||||
{{objdump -sx rel32.xd}} "rel32.bin" }
|
||||
{"SH64 simple partial linking, 64-bit ABI" "-mshelf64 -r"
|
||||
"--abi=64" {rel-1.s rel-2.s}
|
||||
{{objdump -sx rel64.xd}}}
|
||||
{{objdump -sx rel64.xd}} "rel64.bin" }
|
||||
{"SH64 partial linking with datalabel references, 32-bit ABI" "-mshelf32 -r"
|
||||
"--abi=32" {reldl-1.s reldl-2.s}
|
||||
{{readelf {-s -r -x 1 -x 3} reldl32.rd}}}
|
||||
{{readelf {-s -r -x 1 -x 3} reldl32.rd}} "reldl32.bin" }
|
||||
{"SH64 partial linking with datalabel references, 64-bit ABI" "-mshelf64 -r"
|
||||
"--abi=64" {reldl-1.s reldl-2.s}
|
||||
{{readelf {-s -r -x 1 -x 3} reldl64.rd}}}
|
||||
{{readelf {-s -r -x 1 -x 3} reldl64.rd}} "reldl64.bin" }
|
||||
{"Handling SH64 assembler-generated .cranges" "-mshelf32"
|
||||
"--abi=32" {crange-2a.s crange-1.s}
|
||||
{{readelf {-S -s -r -x 1 -x 2 -x 9} crange1.rd}}}
|
||||
{{readelf {-S -s -r -x 1 -x 2 -x 9} crange1.rd}} "crange1.bin" }
|
||||
{"Handling SH64 assembler-generated .cranges, partial linking" "-mshelf32 -r"
|
||||
"--abi=32" {crange-2a.s}
|
||||
{{readelf {-S -s -r -x 2 -x 5} crangerel1.rd}}}
|
||||
{{readelf {-S -s -r -x 2 -x 5} crangerel1.rd}} "crangerel1.bin" }
|
||||
{"Mixing SH64 assembler-generated with linker-generated .cranges" "-mshelf32"
|
||||
"--abi=32" {crange-2a.s crange-2b.s crange-1.s}
|
||||
{{readelf {-S -s -r -x 2 -x 9} crange2.rd}}}
|
||||
{{readelf {-S -s -r -x 2 -x 9} crange2.rd}} "crange2.bin" }
|
||||
{"Mixing SH64 assembler-generated with linker-generated .cranges, partial linking"
|
||||
"-mshelf32 -r"
|
||||
"--abi=32" {crange-2a.s crange-2c.s crange-2d.s crange-2e.s}
|
||||
{{readelf {-S -s -r -x 2 -x 5} crangerel2.rd}}}
|
||||
{{readelf {-S -s -r -x 2 -x 5} crangerel2.rd}} "crangerel2.bin" }
|
||||
{"Merge and use of SH64 .cranges, some not originally in order" "-mshelf32"
|
||||
"--abi=32"
|
||||
{crange-2e.s crange-2f.s crange-2g.s crange-2a.s crange-2d.s crange-2i.s
|
||||
crange-2h.s crange-1.s}
|
||||
{{readelf {-S -s -x 2 -x 9} crange3.rd} {objdump -d crange3.dd}}}
|
||||
{{readelf {-S -s -x 2 -x 9} crange3.rd} {objdump -d crange3.dd}} "crange3.bin" }
|
||||
{"Sorted SH64 .cranges, entry at SHcompact code" "-mshelf32 --entry diversion"
|
||||
"--abi=32"
|
||||
{crange-2e.s crange-2f.s crange-2g.s crange-2a.s crange-2d.s crange-2i.s
|
||||
crange-2h.s crange-1.s}
|
||||
{{readelf {-h -S -s -x 2 -x 9} crange3-cmpct.rd}}}
|
||||
{{readelf {-h -S -s -x 2 -x 9} crange3-cmpct.rd}} "crange3-cmpct.bin" }
|
||||
{"Sorted SH64 .cranges, entry at SHmedia code" "-mshelf32 --entry diversion2"
|
||||
"--abi=32"
|
||||
{crange-2e.s crange-2f.s crange-2g.s crange-2a.s crange-2d.s crange-2i.s
|
||||
crange-2h.s crange-1.s}
|
||||
{{readelf {-h -S -s -x 2 -x 9} crange3-media.rd}}}
|
||||
{{readelf {-h -S -s -x 2 -x 9} crange3-media.rd}} "crange3-media.bin" }
|
||||
{"SH64 Big Endianness" "-mshelf64 -Tendian.ld"
|
||||
"--abi=64" {endian.s}
|
||||
{{objdump -s endian.sbd} {objdump -d endian.dbd}}}
|
||||
{{objdump -s endian.sbd} {objdump -d endian.dbd}} "endianb.bin" }
|
||||
{"SH64 Little Endianness" "-mshlelf64 -Tendian.ld"
|
||||
"--abi=64 --little" {endian.s}
|
||||
{{objdump -s endian.sld} {objdump -d endian.dld}}}
|
||||
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
set binfile "tmpdir/linked"
|
||||
|
||||
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 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"
|
||||
|
||||
# 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# FIXME: Move this to ld-lib.exp or higher up.
|
||||
|
||||
# regexp_diff, based on simple_diff taken from ld test suite
|
||||
# compares two files line-by-line
|
||||
# file1 contains strings, file2 contains regexps and #-comments
|
||||
# blank lines are ignored in either file
|
||||
# returns non-zero if differences exist
|
||||
#
|
||||
proc regexp_diff { file_1 file_2 } {
|
||||
|
||||
set eof -1
|
||||
set end_1 0
|
||||
set end_2 0
|
||||
set differences 0
|
||||
set diff_pass 0
|
||||
|
||||
if [file exists $file_1] then {
|
||||
set file_a [open $file_1 r]
|
||||
} else {
|
||||
warning "$file_1 doesn't exist"
|
||||
return 1
|
||||
}
|
||||
|
||||
if [file exists $file_2] then {
|
||||
set file_b [open $file_2 r]
|
||||
} else {
|
||||
fail "$file_2 doesn't exist"
|
||||
close $file_a
|
||||
return 1
|
||||
}
|
||||
|
||||
verbose " Regexp-diff'ing: $file_1 $file_2" 2
|
||||
|
||||
while { 1 } {
|
||||
set line_a ""
|
||||
set line_b ""
|
||||
while { [string length $line_a] == 0 } {
|
||||
if { [gets $file_a line_a] == $eof } {
|
||||
set end_1 1
|
||||
break
|
||||
}
|
||||
}
|
||||
while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
|
||||
if [ string match "#pass" $line_b ] {
|
||||
set end_2 1
|
||||
set diff_pass 1
|
||||
break
|
||||
} elseif [ string match "#..." $line_b ] {
|
||||
if { [gets $file_b line_b] == $eof } {
|
||||
set end_2 1
|
||||
break
|
||||
}
|
||||
verbose "looking for \"^$line_b$\"" 3
|
||||
while { ![regexp "^$line_b$" "$line_a"] } {
|
||||
verbose "skipping \"$line_a\"" 3
|
||||
if { [gets $file_a line_a] == $eof } {
|
||||
set end_1 1
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if { [gets $file_b line_b] == $eof } {
|
||||
set end_2 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if { $diff_pass } {
|
||||
break
|
||||
} elseif { $end_1 && $end_2 } {
|
||||
break
|
||||
} elseif { $end_1 } {
|
||||
send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
|
||||
verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
|
||||
set differences 1
|
||||
break
|
||||
} elseif { $end_2 } {
|
||||
send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
|
||||
verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
|
||||
set differences 1
|
||||
break
|
||||
} else {
|
||||
verbose "regexp \"^$line_b$\"\nline \"$line_a\"" 3
|
||||
if ![regexp "^$line_b$" "$line_a"] {
|
||||
send_log "regexp_diff match failure\n"
|
||||
send_log "regexp \"^$line_b$\"\nline \"$line_a\"\n"
|
||||
set differences 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
|
||||
send_log "$file_1 and $file_2 are different lengths\n"
|
||||
verbose "$file_1 and $file_2 are different lengths" 3
|
||||
set differences 1
|
||||
}
|
||||
|
||||
close $file_a
|
||||
close $file_b
|
||||
|
||||
return $differences
|
||||
}
|
||||
|
||||
proc file_contents { filename } {
|
||||
set file [open $filename r]
|
||||
set contents [read $file]
|
||||
close $file
|
||||
return $contents
|
||||
{{objdump -s endian.sld} {objdump -d endian.dld}} "endinanl.bin" }
|
||||
}
|
||||
|
||||
run_ld_link_tests $sh64tests
|
||||
|
310
ld/testsuite/ld-x86-64/tlsbin.dd
Normal file
310
ld/testsuite/ld-x86-64/tlsbin.dd
Normal file
@ -0,0 +1,310 @@
|
||||
#source: tlsbinpic.s
|
||||
#source: tlsbin.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#objdump: -drj.text
|
||||
#target: x86_64-*-*
|
||||
|
||||
# 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 elf64-x86-64
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+401000 <fn2>:
|
||||
401000: 55[ ]+push %rbp
|
||||
401001: 48 89 e5[ ]+mov %rsp,%rbp
|
||||
# GD -> IE because variable is not defined in executable
|
||||
401004: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
40100b: 00 00 *
|
||||
40100d: 48 03 05 c4 11 10 00[ ]+add 1053124\(%rip\),%rax +# 5021d8 <_GLOBAL_OFFSET_TABLE_\+0x38>
|
||||
# -> R_X86_64_TPOFF64 sG1
|
||||
401014: 90[ ]+nop *
|
||||
401015: 90[ ]+nop *
|
||||
401016: 90[ ]+nop *
|
||||
401017: 90[ ]+nop *
|
||||
# GD -> IE because variable is not defined in executable where
|
||||
# the variable is referenced through IE too
|
||||
401018: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
40101f: 00 00 *
|
||||
401021: 48 03 05 a0 11 10 00[ ]+add 1053088\(%rip\),%rax +# 5021c8 <_GLOBAL_OFFSET_TABLE_\+0x28>
|
||||
# -> R_X86_64_TPOFF64 sG2
|
||||
401028: 90[ ]+nop *
|
||||
401029: 90[ ]+nop *
|
||||
40102a: 90[ ]+nop *
|
||||
40102b: 90[ ]+nop *
|
||||
# GD -> LE with global variable defined in executable
|
||||
40102c: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
401033: 00 00 *
|
||||
401035: 48 8d 80 60 ff ff ff[ ]+lea 0xf+60\(%rax\),%rax
|
||||
# sg1
|
||||
40103c: 90[ ]+nop *
|
||||
40103d: 90[ ]+nop *
|
||||
40103e: 90[ ]+nop *
|
||||
40103f: 90[ ]+nop *
|
||||
# GD -> LE with local variable defined in executable
|
||||
401040: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
401047: 00 00 *
|
||||
401049: 48 8d 80 80 ff ff ff[ ]+lea 0xf+80\(%rax\),%rax
|
||||
# sl1
|
||||
401050: 90[ ]+nop *
|
||||
401051: 90[ ]+nop *
|
||||
401052: 90[ ]+nop *
|
||||
401053: 90[ ]+nop *
|
||||
# GD -> LE with hidden variable defined in executable
|
||||
401054: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
40105b: 00 00 *
|
||||
40105d: 48 8d 80 a0 ff ff ff[ ]+lea 0xf+a0\(%rax\),%rax
|
||||
# sh1
|
||||
401064: 90[ ]+nop *
|
||||
401065: 90[ ]+nop *
|
||||
401066: 90[ ]+nop *
|
||||
401067: 90[ ]+nop *
|
||||
# LD
|
||||
401068: 66 66 66 64 48 8b 04[ ]+mov %fs:0x0,%rax
|
||||
40106f: 25 00 00 00 00 *
|
||||
401074: 90[ ]+nop *
|
||||
401075: 90[ ]+nop *
|
||||
401076: 48 8d 90 81 ff ff ff[ ]+lea 0xf+81\(%rax\),%rdx
|
||||
# sl1+1
|
||||
40107d: 90[ ]+nop *
|
||||
40107e: 90[ ]+nop *
|
||||
40107f: 4c 8d 88 86 ff ff ff[ ]+lea 0xf+86\(%rax\),%r9
|
||||
# sl2+2
|
||||
401086: 90[ ]+nop *
|
||||
401087: 90[ ]+nop *
|
||||
401088: 90[ ]+nop *
|
||||
401089: 90[ ]+nop *
|
||||
# LD against hidden variables
|
||||
40108a: 66 66 66 64 48 8b 04[ ]+mov %fs:0x0,%rax
|
||||
401091: 25 00 00 00 00 *
|
||||
401096: 90[ ]+nop *
|
||||
401097: 90[ ]+nop *
|
||||
401098: 48 8d 90 a0 ff ff ff[ ]+lea 0xf+a0\(%rax\),%rdx
|
||||
# sh1
|
||||
40109f: 90[ ]+nop *
|
||||
4010a0: 90[ ]+nop *
|
||||
4010a1: 48 8d 88 a7 ff ff ff[ ]+lea 0xf+a7\(%rax\),%rcx
|
||||
# sh2+3
|
||||
4010a8: 90[ ]+nop *
|
||||
4010a9: 90[ ]+nop *
|
||||
4010aa: 90[ ]+nop *
|
||||
4010ab: 90[ ]+nop *
|
||||
# IE against global var
|
||||
4010ac: 64 4c 8b 0c 25 00 00[ ]+mov %fs:0x0,%r9
|
||||
4010b3: 00 00 *
|
||||
4010b5: 90[ ]+nop *
|
||||
4010b6: 90[ ]+nop *
|
||||
4010b7: 4c 03 0d 0a 11 10 00[ ]+add 1052938\(%rip\),%r9 +# 5021c8 <_GLOBAL_OFFSET_TABLE_\+0x28>
|
||||
# -> R_X86_64_TPOFF64 sG2
|
||||
4010be: 90[ ]+nop *
|
||||
4010bf: 90[ ]+nop *
|
||||
4010c0: 90[ ]+nop *
|
||||
4010c1: 90[ ]+nop *
|
||||
# IE -> LE against global var defined in exec
|
||||
4010c2: 64 4c 8b 14 25 00 00[ ]+mov %fs:0x0,%r10
|
||||
4010c9: 00 00 *
|
||||
4010cb: 90[ ]+nop *
|
||||
4010cc: 90[ ]+nop *
|
||||
4010cd: 4d 8d 92 60 ff ff ff[ ]+lea 0xf+60\(%r10\),%r10
|
||||
# sg1
|
||||
4010d4: 90[ ]+nop *
|
||||
4010d5: 90[ ]+nop *
|
||||
4010d6: 90[ ]+nop *
|
||||
4010d7: 90[ ]+nop *
|
||||
# IE -> LE against local var
|
||||
4010d8: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
4010df: 00 00 *
|
||||
4010e1: 90[ ]+nop *
|
||||
4010e2: 90[ ]+nop *
|
||||
4010e3: 48 8d 80 80 ff ff ff[ ]+lea 0xf+80\(%rax\),%rax
|
||||
# sl1
|
||||
4010ea: 90[ ]+nop *
|
||||
4010eb: 90[ ]+nop *
|
||||
4010ec: 90[ ]+nop *
|
||||
4010ed: 90[ ]+nop *
|
||||
# IE -> LE against hidden var
|
||||
4010ee: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
|
||||
4010f5: 00 00 *
|
||||
4010f7: 90[ ]+nop *
|
||||
4010f8: 90[ ]+nop *
|
||||
4010f9: 48 8d 89 a0 ff ff ff[ ]+lea 0xf+a0\(%rcx\),%rcx
|
||||
# sh1
|
||||
401100: 90[ ]+nop *
|
||||
401101: 90[ ]+nop *
|
||||
401102: 90[ ]+nop *
|
||||
401103: 90[ ]+nop *
|
||||
# Direct access through %fs
|
||||
# IE against global var
|
||||
401104: 48 8b 0d b5 10 10 00[ ]+mov 1052853\(%rip\),%rcx +# 5021c0 <_GLOBAL_OFFSET_TABLE_\+0x20>
|
||||
# -> R_X86_64_TPOFF64 sG5
|
||||
40110b: 90[ ]+nop *
|
||||
40110c: 90[ ]+nop *
|
||||
40110d: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
|
||||
401111: 90[ ]+nop *
|
||||
401112: 90[ ]+nop *
|
||||
401113: 90[ ]+nop *
|
||||
401114: 90[ ]+nop *
|
||||
# IE->LE against local var
|
||||
401115: 49 c7 c3 90 ff ff ff[ ]+mov \$0xf+90,%r11
|
||||
# sl5
|
||||
40111c: 90[ ]+nop *
|
||||
40111d: 90[ ]+nop *
|
||||
40111e: 64 4d 8b 23[ ]+mov %fs:\(%r11\),%r12
|
||||
401122: 90[ ]+nop *
|
||||
401123: 90[ ]+nop *
|
||||
401124: 90[ ]+nop *
|
||||
401125: 90[ ]+nop *
|
||||
# IE->LE against hidden var
|
||||
401126: 48 c7 c2 b0 ff ff ff[ ]+mov \$0xf+b0,%rdx
|
||||
40112d: 90[ ]+nop *
|
||||
40112e: 90[ ]+nop *
|
||||
40112f: 64 48 8b 12[ ]+mov %fs:\(%rdx\),%rdx
|
||||
# sh5
|
||||
401133: 90[ ]+nop *
|
||||
401134: 90[ ]+nop *
|
||||
401135: 90[ ]+nop *
|
||||
401136: 90[ ]+nop *
|
||||
401137: c9[ ]+leaveq *
|
||||
401138: c3[ ]+retq *
|
||||
401139: 90[ ]+nop *
|
||||
40113a: 90[ ]+nop *
|
||||
40113b: 90[ ]+nop *
|
||||
|
||||
0+40113c <_start>:
|
||||
40113c: 55[ ]+push %rbp
|
||||
40113d: 48 89 e5[ ]+mov %rsp,%rbp
|
||||
# IE against global var
|
||||
401140: 64 4c 8b 1c 25 00 00[ ]+mov %fs:0x0,%r11
|
||||
401147: 00 00 *
|
||||
401149: 90[ ]+nop *
|
||||
40114a: 90[ ]+nop *
|
||||
40114b: 4c 03 1d 7e 10 10 00[ ]+add 1052798\(%rip\),%r11 +# 5021d0 <_GLOBAL_OFFSET_TABLE_\+0x30>
|
||||
# -> R_X86_64_TPOFF64 sG6
|
||||
401152: 90[ ]+nop *
|
||||
401153: 90[ ]+nop *
|
||||
401154: 90[ ]+nop *
|
||||
401155: 90[ ]+nop *
|
||||
# IE -> LE against global var defined in exec
|
||||
401156: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
|
||||
40115d: 00 00 *
|
||||
40115f: 90[ ]+nop *
|
||||
401160: 90[ ]+nop *
|
||||
401161: 48 8d 92 d4 ff ff ff[ ]+lea 0xf+d4\(%rdx\),%rdx
|
||||
# bg6
|
||||
401168: 90[ ]+nop *
|
||||
401169: 90[ ]+nop *
|
||||
40116a: 90[ ]+nop *
|
||||
40116b: 90[ ]+nop *
|
||||
# IE -> LE against local var
|
||||
40116c: 64 4c 8b 24 25 00 00[ ]+mov %fs:0x0,%r12
|
||||
401173: 00 00 *
|
||||
401175: 90[ ]+nop *
|
||||
401176: 90[ ]+nop *
|
||||
401177: 49 81 c4 f4 ff ff ff[ ]+add \$0xf+f4,%r12
|
||||
# bl6
|
||||
40117e: 90[ ]+nop *
|
||||
40117f: 90[ ]+nop *
|
||||
401180: 90[ ]+nop *
|
||||
401181: 90[ ]+nop *
|
||||
# direct %fs access IE -> LE against local var
|
||||
401182: 48 c7 c2 fc ff ff ff[ ]+mov \$0xf+fc,%rdx
|
||||
# bl8
|
||||
401189: 90[ ]+nop *
|
||||
40118a: 90[ ]+nop *
|
||||
40118b: 64 48 8b 02[ ]+mov %fs:\(%rdx\),%rax
|
||||
40118f: 90[ ]+nop *
|
||||
401190: 90[ ]+nop *
|
||||
401191: 90[ ]+nop *
|
||||
401192: 90[ ]+nop *
|
||||
# IE -> LE against hidden but not local var
|
||||
401193: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
|
||||
40119a: 00 00 *
|
||||
40119c: 90[ ]+nop *
|
||||
40119d: 90[ ]+nop *
|
||||
40119e: 48 8d 92 b4 ff ff ff[ ]+lea 0xf+b4\(%rdx\),%rdx
|
||||
# sh6
|
||||
4011a5: 90[ ]+nop *
|
||||
4011a6: 90[ ]+nop *
|
||||
4011a7: 90[ ]+nop *
|
||||
4011a8: 90[ ]+nop *
|
||||
# direct %fs access IE -> LE against hidden but not local var
|
||||
4011a9: 48 c7 c2 bc ff ff ff[ ]+mov \$0xf+bc,%rdx
|
||||
# sh8
|
||||
4011b0: 90[ ]+nop *
|
||||
4011b1: 90[ ]+nop *
|
||||
4011b2: 64 48 8b 02[ ]+mov %fs:\(%rdx\),%rax
|
||||
4011b6: 90[ ]+nop *
|
||||
4011b7: 90[ ]+nop *
|
||||
4011b8: 90[ ]+nop *
|
||||
4011b9: 90[ ]+nop *
|
||||
# LE, global var defined in exec
|
||||
4011ba: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
4011c1: 00 00 *
|
||||
4011c3: 90[ ]+nop *
|
||||
4011c4: 90[ ]+nop *
|
||||
4011c5: 48 8d 90 64 ff ff ff[ ]+lea 0xf+64\(%rax\),%rdx
|
||||
# sg2
|
||||
4011cc: 90[ ]+nop *
|
||||
4011cd: 90[ ]+nop *
|
||||
4011ce: 90[ ]+nop *
|
||||
4011cf: 90[ ]+nop *
|
||||
# LE, local var, non-canonical sequence
|
||||
4011d0: 49 c7 c1 e6 ff ff ff[ ]+mov \$0xf+e6,%r9
|
||||
# bl2+2
|
||||
4011d7: 90[ ]+nop *
|
||||
4011d8: 90[ ]+nop *
|
||||
4011d9: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
|
||||
4011e0: 00 00 *
|
||||
4011e2: 90[ ]+nop *
|
||||
4011e3: 90[ ]+nop *
|
||||
4011e4: 4c 01 ca[ ]+add %r9,%rdx
|
||||
4011e7: 90[ ]+nop *
|
||||
4011e8: 90[ ]+nop *
|
||||
4011e9: 90[ ]+nop *
|
||||
4011ea: 90[ ]+nop *
|
||||
# LE, hidden var defined in exec, non-canonical sequence
|
||||
4011eb: 64 48 8b 14 25 00 00[ ]+mov %fs:0x0,%rdx
|
||||
4011f2: 00 00 *
|
||||
4011f4: 90[ ]+nop *
|
||||
4011f5: 90[ ]+nop *
|
||||
4011f6: 48 81 c2 a5 ff ff ff[ ]+add \$0xf+a5,%rdx
|
||||
# sh2+1
|
||||
4011fd: 90[ ]+nop *
|
||||
4011fe: 90[ ]+nop *
|
||||
4011ff: 90[ ]+nop *
|
||||
401200: 90[ ]+nop *
|
||||
# Direct %fs access
|
||||
# LE, global var defined in exec
|
||||
401201: 64 48 8b 04 25 68 ff[ ]+mov %fs:0xf+68,%rax
|
||||
401208: ff ff *
|
||||
# sg3
|
||||
40120a: 90[ ]+nop *
|
||||
40120b: 90[ ]+nop *
|
||||
40120c: 90[ ]+nop *
|
||||
40120d: 90[ ]+nop *
|
||||
# LE, local var
|
||||
40120e: 64 4c 8b 14 25 eb ff[ ]+mov %fs:0xf+eb,%r10
|
||||
401215: ff ff *
|
||||
# bl3+3
|
||||
401217: 90[ ]+nop *
|
||||
401218: 90[ ]+nop *
|
||||
401219: 90[ ]+nop *
|
||||
40121a: 90[ ]+nop *
|
||||
# LE, hidden var defined in exec
|
||||
40121b: 64 48 8b 14 25 a9 ff[ ]+mov %fs:0xf+a9,%rdx
|
||||
401222: ff ff *
|
||||
# sh3+1
|
||||
401224: 90[ ]+nop *
|
||||
401225: 90[ ]+nop *
|
||||
401226: 90[ ]+nop *
|
||||
401227: 90[ ]+nop *
|
||||
401228: c9[ ]+leaveq *
|
||||
401229: c3[ ]+retq *
|
154
ld/testsuite/ld-x86-64/tlsbin.rd
Normal file
154
ld/testsuite/ld-x86-64/tlsbin.rd
Normal file
@ -0,0 +1,154 @@
|
||||
#source: tlsbinpic.s
|
||||
#source: tlsbin.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#readelf: -WSsrl
|
||||
#target: x86_64-*-*
|
||||
|
||||
There are 18 section headers, starting at offset 0x[0-9a-f]+:
|
||||
|
||||
Section Headers:
|
||||
\[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
|
||||
\[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
|
||||
\[ 1\] .interp +.*
|
||||
\[ 2\] .hash +.*
|
||||
\[ 3\] .dynsym +.*
|
||||
\[ 4\] .dynstr +.*
|
||||
\[ 5\] .rela.dyn +.*
|
||||
\[ 6\] .rela.plt +.*
|
||||
\[ 7\] .plt +.*
|
||||
\[ 8\] .text +PROGBITS +0+401000 0+1000 0+22a 00 +AX +0 +0 +4096
|
||||
\[ 9\] .data +.*
|
||||
\[10\] .tdata +PROGBITS +0+502000 0+2000 0+60 00 WAT +0 +0 +1
|
||||
\[11\] .tbss +NOBITS +0+502060 0+2060 0+40 00 WAT +0 +0 +1
|
||||
\[12\] .dynamic +DYNAMIC +0+502060 0+2060 0+140 10 +WA +4 +0 +8
|
||||
\[13\] .got +PROGBITS +0+5021a0 0+21a0 0+40 08 +WA +0 +0 +8
|
||||
\[14\] .bss +.*
|
||||
\[15\] .shstrtab +.*
|
||||
\[16\] .symtab +.*
|
||||
\[17\] .strtab +.*
|
||||
Key to Flags:
|
||||
.*
|
||||
.*
|
||||
.*
|
||||
|
||||
Elf file type is EXEC \(Executable file\)
|
||||
Entry point 0x40113c
|
||||
There are 6 program headers, starting at offset [0-9]+
|
||||
|
||||
Program Headers:
|
||||
Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg Align
|
||||
PHDR +0x0+40 0x0+400040 0x0+400040 0x0+150 0x0+150 R E 0x8
|
||||
INTERP +0x0+190 0x0+400190 0x0+400190 0x0+f 0x0+f R +0x1
|
||||
.*Requesting program interpreter.*
|
||||
LOAD +0x0+ 0x0+400000 0x0+400000 0x0+122a 0x0+122a R E 0x100000
|
||||
LOAD +0x0+2000 0x0+502000 0x0+502000 0x0+1e0 0x0+1e0 RW 0x100000
|
||||
DYNAMIC +0x0+2060 0x0+502060 0x0+502060 0x0+140 0x0+140 RW 0x8
|
||||
TLS +0x0+2000 0x0+502000 0x0+502000 0x0+60 0x0+a0 R +0x1
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00 *
|
||||
01 +.interp *
|
||||
02 +.interp .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
|
||||
03 +.tdata .tbss .dynamic .got *
|
||||
04 +.tbss .dynamic *
|
||||
05 +.tdata .tbss *
|
||||
|
||||
Relocation section '.rela.dyn' at offset 0x358 contains 4 entries:
|
||||
+Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
|
||||
0+5021c0 0+100000012 R_X86_64_TPOFF64 +0+ sG5 \+ 0
|
||||
0+5021c8 0+300000012 R_X86_64_TPOFF64 +0+ sG2 \+ 0
|
||||
0+5021d0 0+600000012 R_X86_64_TPOFF64 +0+ sG6 \+ 0
|
||||
0+5021d8 0+700000012 R_X86_64_TPOFF64 +0+ sG1 \+ 0
|
||||
|
||||
Relocation section '.rela.plt' at offset 0x3b8 contains 1 entries:
|
||||
+Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
|
||||
0+[0-9a-f]+ 0+400000007 R_X86_64_JUMP_SLOT +0+[0-9a-f]+ __tls_get_addr \+ 0
|
||||
|
||||
Symbol table '.dynsym' contains 11 entries:
|
||||
+Num: +Value +Size Type +Bind +Vis +Ndx Name
|
||||
+0: 0+ +0 NOTYPE LOCAL DEFAULT UND *
|
||||
+1: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
|
||||
+2: 0+502060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
|
||||
+3: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
|
||||
+4: 0+[0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_addr
|
||||
+5: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
+6: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
|
||||
+7: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
|
||||
+8: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
+9: 0+5021a0 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
|
||||
+10: 0+[0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
|
||||
|
||||
Symbol table '.symtab' contains 70 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: 0+20 +0 TLS +LOCAL DEFAULT +10 sl1
|
||||
+19: 0+24 +0 TLS +LOCAL DEFAULT +10 sl2
|
||||
+20: 0+28 +0 TLS +LOCAL DEFAULT +10 sl3
|
||||
+21: 0+2c +0 TLS +LOCAL DEFAULT +10 sl4
|
||||
+22: 0+30 +0 TLS +LOCAL DEFAULT +10 sl5
|
||||
+23: 0+34 +0 TLS +LOCAL DEFAULT +10 sl6
|
||||
+24: 0+38 +0 TLS +LOCAL DEFAULT +10 sl7
|
||||
+25: 0+3c +0 TLS +LOCAL DEFAULT +10 sl8
|
||||
+26: 0+80 +0 TLS +LOCAL DEFAULT +11 bl1
|
||||
+27: 0+84 +0 TLS +LOCAL DEFAULT +11 bl2
|
||||
+28: 0+88 +0 TLS +LOCAL DEFAULT +11 bl3
|
||||
+29: 0+8c +0 TLS +LOCAL DEFAULT +11 bl4
|
||||
+30: 0+90 +0 TLS +LOCAL DEFAULT +11 bl5
|
||||
+31: 0+94 +0 TLS +LOCAL DEFAULT +11 bl6
|
||||
+32: 0+98 +0 TLS +LOCAL DEFAULT +11 bl7
|
||||
+33: 0+9c +0 TLS +LOCAL DEFAULT +11 bl8
|
||||
+34: 0+1c +0 TLS +GLOBAL DEFAULT +10 sg8
|
||||
+35: 0+7c +0 TLS +GLOBAL DEFAULT +11 bg8
|
||||
+36: 0+74 +0 TLS +GLOBAL DEFAULT +11 bg6
|
||||
+37: 0+ +0 TLS +GLOBAL DEFAULT UND sG5
|
||||
+38: 0+68 +0 TLS +GLOBAL DEFAULT +11 bg3
|
||||
+39: 0+502060 +0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
|
||||
+40: 0+8 +0 TLS +GLOBAL DEFAULT +10 sg3
|
||||
+41: 0+48 +0 TLS +GLOBAL HIDDEN +10 sh3
|
||||
+42: 0+ +0 TLS +GLOBAL DEFAULT UND sG2
|
||||
+43: 0+c +0 TLS +GLOBAL DEFAULT +10 sg4
|
||||
+44: 0+10 +0 TLS +GLOBAL DEFAULT +10 sg5
|
||||
+45: 0+70 +0 TLS +GLOBAL DEFAULT +11 bg5
|
||||
+46: [0-9a-f]+ +0 FUNC +GLOBAL DEFAULT UND __tls_get_addr
|
||||
+47: 0+58 +0 TLS +GLOBAL HIDDEN +10 sh7
|
||||
+48: 0+5c +0 TLS +GLOBAL HIDDEN +10 sh8
|
||||
+49: 0+ +0 TLS +GLOBAL DEFAULT +10 sg1
|
||||
+50: 0+40113c +0 FUNC +GLOBAL DEFAULT +8 _start
|
||||
+51: 0+4c +0 TLS +GLOBAL HIDDEN +10 sh4
|
||||
+52: 0+78 +0 TLS +GLOBAL DEFAULT +11 bg7
|
||||
+53: 0+50 +0 TLS +GLOBAL HIDDEN +10 sh5
|
||||
+54: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
+55: 0+ +0 TLS +GLOBAL DEFAULT UND sG6
|
||||
+56: 0+401000 +0 FUNC +GLOBAL DEFAULT +8 fn2
|
||||
+57: 0+4 +0 TLS +GLOBAL DEFAULT +10 sg2
|
||||
+58: 0+ +0 TLS +GLOBAL DEFAULT UND sG1
|
||||
+59: 0+40 +0 TLS +GLOBAL HIDDEN +10 sh1
|
||||
+60: 0+14 +0 TLS +GLOBAL DEFAULT +10 sg6
|
||||
+61: 0+18 +0 TLS +GLOBAL DEFAULT +10 sg7
|
||||
+62: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
+63: 0+5021a0 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
|
||||
+64: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
|
||||
+65: 0+44 +0 TLS +GLOBAL HIDDEN +10 sh2
|
||||
+66: 0+54 +0 TLS +GLOBAL HIDDEN +10 sh6
|
||||
+67: 0+64 +0 TLS +GLOBAL DEFAULT +11 bg2
|
||||
+68: 0+60 +0 TLS +GLOBAL DEFAULT +11 bg1
|
||||
+69: 0+6c +0 TLS +GLOBAL DEFAULT +11 bg4
|
97
ld/testsuite/ld-x86-64/tlsbin.s
Normal file
97
ld/testsuite/ld-x86-64/tlsbin.s
Normal file
@ -0,0 +1,97 @@
|
||||
.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:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
/* IE against global var */
|
||||
movq %fs:0, %r11
|
||||
nop;nop
|
||||
addq sG6@gottpoff(%rip), %r11
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE -> LE against global var defined in exec */
|
||||
movq %fs:0, %rdx
|
||||
nop;nop
|
||||
addq bg6@gottpoff(%rip), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE -> LE against local var */
|
||||
movq %fs:0, %r12
|
||||
nop;nop
|
||||
addq bl6@gottpoff(%rip), %r12
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* direct %fs access IE -> LE against local var */
|
||||
movq bl8@gottpoff(%rip), %rdx
|
||||
nop;nop
|
||||
movq %fs:(%rdx), %rax
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE -> LE against hidden but not local var */
|
||||
movq %fs:0, %rdx
|
||||
nop;nop
|
||||
addq sh6@gottpoff(%rip), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* direct %fs access IE -> LE against hidden but not local var */
|
||||
movq sh8@gottpoff(%rip), %rdx
|
||||
nop;nop
|
||||
movq %fs:(%rdx), %rax
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LE, global var defined in exec */
|
||||
movq %fs:0, %rax
|
||||
nop;nop
|
||||
leaq sg2@tpoff(%rax), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LE, local var, non-canonical sequence */
|
||||
movq $2+bl2@tpoff, %r9
|
||||
nop;nop
|
||||
movq %fs:0, %rdx
|
||||
nop;nop
|
||||
addq %r9, %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LE, hidden var defined in exec, non-canonical sequence */
|
||||
movq %fs:0, %rdx
|
||||
nop;nop
|
||||
addq $sh2@tpoff+1, %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* Direct %fs access */
|
||||
|
||||
/* LE, global var defined in exec */
|
||||
movq %fs:sg3@tpoff, %rax
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LE, local var */
|
||||
movq %fs:bl3@tpoff+3, %r10
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LE, hidden var defined in exec */
|
||||
movq %fs:1+sh3@tpoff, %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
leave
|
||||
ret
|
14
ld/testsuite/ld-x86-64/tlsbin.sd
Normal file
14
ld/testsuite/ld-x86-64/tlsbin.sd
Normal file
@ -0,0 +1,14 @@
|
||||
#source: tlsbinpic.s
|
||||
#source: tlsbin.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#objdump: -sj.got
|
||||
#target: x86_64-*-*
|
||||
|
||||
.*: +file format elf64-x86-64
|
||||
|
||||
Contents of section .got:
|
||||
5021a0 [0-9a-f]+ [0-9a-f]+ 00000000 00000000 .*
|
||||
5021b0 00000000 00000000 [0-9a-f]+ [0-9a-f]+ .*
|
||||
5021c0 00000000 00000000 00000000 00000000 .*
|
||||
5021d0 00000000 00000000 00000000 00000000 .*
|
16
ld/testsuite/ld-x86-64/tlsbin.td
Normal file
16
ld/testsuite/ld-x86-64/tlsbin.td
Normal file
@ -0,0 +1,16 @@
|
||||
#source: tlsbinpic.s
|
||||
#source: tlsbin.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#objdump: -sj.tdata
|
||||
#target: x86_64-*-*
|
||||
|
||||
.*: +file format elf64-x86-64
|
||||
|
||||
Contents of section .tdata:
|
||||
502000 11000000 12000000 13000000 14000000 .*
|
||||
502010 15000000 16000000 17000000 18000000 .*
|
||||
502020 41000000 42000000 43000000 44000000 .*
|
||||
502030 45000000 46000000 47000000 48000000 .*
|
||||
502040 01010000 02010000 03010000 04010000 .*
|
||||
502050 05010000 06010000 07010000 08010000 .*
|
136
ld/testsuite/ld-x86-64/tlsbinpic.s
Normal file
136
ld/testsuite/ld-x86-64/tlsbinpic.s
Normal file
@ -0,0 +1,136 @@
|
||||
/* Force .data aligned to 4K, so that .got very likely gets at
|
||||
0x5021a0 (0x60 bytes .tdata and 0x140 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 0x401000. */
|
||||
.text
|
||||
.balign 4096
|
||||
.globl fn2
|
||||
.type fn2,@function
|
||||
fn2:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
/* GD -> IE because variable is not defined in executable */
|
||||
.long 0x66666666
|
||||
leaq sG1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> IE because variable is not defined in executable where
|
||||
the variable is referenced through IE too */
|
||||
.long 0x66666666
|
||||
leaq sG2@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> LE with global variable defined in executable */
|
||||
.long 0x66666666
|
||||
leaq sg1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> LE with local variable defined in executable */
|
||||
.long 0x66666666
|
||||
leaq sl1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> LE with hidden variable defined in executable */
|
||||
.long 0x66666666
|
||||
leaq sh1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LD */
|
||||
leaq sl1@tlsld(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop
|
||||
leaq 1+sl1@dtpoff(%rax), %rdx
|
||||
nop;nop
|
||||
leaq sl2@dtpoff+2(%rax), %r9
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LD against hidden variables */
|
||||
leaq sh1@tlsld(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop
|
||||
leaq sh1@dtpoff(%rax), %rdx
|
||||
nop;nop
|
||||
leaq 3+sh2@dtpoff(%rax), %rcx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against global var */
|
||||
movq %fs:0, %r9
|
||||
nop;nop
|
||||
addq sG2@gottpoff(%rip), %r9
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE -> LE against global var defined in exec */
|
||||
movq %fs:0, %r10
|
||||
nop;nop
|
||||
addq sg1@gottpoff(%rip), %r10
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE -> LE against local var */
|
||||
movq %fs:0, %rax
|
||||
nop;nop
|
||||
addq sl1@gottpoff(%rip), %rax
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE -> LE against hidden var */
|
||||
movq %fs:0, %rcx
|
||||
nop;nop
|
||||
addq sh1@gottpoff(%rip), %rcx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* Direct access through %fs */
|
||||
|
||||
/* IE against global var */
|
||||
movq sG5@gottpoff(%rip), %rcx
|
||||
nop;nop
|
||||
movq %fs:(%rcx), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE->LE against local var */
|
||||
movq sl5@gottpoff(%rip), %r11
|
||||
nop;nop
|
||||
movq %fs:(%r11), %r12
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE->LE against hidden var */
|
||||
movq sh5@gottpoff(%rip), %rdx
|
||||
nop;nop
|
||||
movq %fs:(%rdx), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
leave
|
||||
ret
|
18
ld/testsuite/ld-x86-64/tlslib.s
Normal file
18
ld/testsuite/ld-x86-64/tlslib.s
Normal file
@ -0,0 +1,18 @@
|
||||
.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:
|
||||
movq %rdi, %rax
|
||||
ret
|
226
ld/testsuite/ld-x86-64/tlspic.dd
Normal file
226
ld/testsuite/ld-x86-64/tlspic.dd
Normal file
@ -0,0 +1,226 @@
|
||||
#source: tlspic1.s
|
||||
#source: tlspic2.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#objdump: -drj.text
|
||||
#target: x86_64-*-*
|
||||
|
||||
.*: +file format elf64-x86-64
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+1000 <fn1>:
|
||||
+1000: 55[ ]+push %rbp
|
||||
+1001: 48 89 e5[ ]+mov %rsp,%rbp
|
||||
+1004: 90[ ]+nop *
|
||||
+1005: 90[ ]+nop *
|
||||
+1006: 90[ ]+nop *
|
||||
+1007: 90[ ]+nop *
|
||||
# GD
|
||||
+1008: 66 66 66 66 48 8d 3d[ ]+lea 1053165\(%rip\),%rdi +# 102200 <_GLOBAL_OFFSET_TABLE_\+0x70>
|
||||
+100f: ed 11 10 00 *
|
||||
# -> R_X86_64_DTPMOD64 sg1
|
||||
+1013: e8 68 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+1018: 90[ ]+nop *
|
||||
+1019: 90[ ]+nop *
|
||||
+101a: 90[ ]+nop *
|
||||
+101b: 90[ ]+nop *
|
||||
# GD -> IE because variable is referenced through IE too
|
||||
+101c: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
+1023: 00 00 *
|
||||
+1025: 48 03 05 f4 11 10 00[ ]+add 1053172\(%rip\),%rax +# 102220 <_GLOBAL_OFFSET_TABLE_\+0x90>
|
||||
# -> R_X86_64_TPOFF64 sg2
|
||||
+102c: 90[ ]+nop *
|
||||
+102d: 90[ ]+nop *
|
||||
+102e: 90[ ]+nop *
|
||||
+102f: 90[ ]+nop *
|
||||
# GD against local variable
|
||||
+1030: 66 66 66 66 48 8d 3d[ ]+lea 1053045\(%rip\),%rdi +# 1021b0 <_GLOBAL_OFFSET_TABLE_\+0x20>
|
||||
+1037: 75 11 10 00 *
|
||||
# -> R_X86_64_DTPMOD64 [0 0x2000000000000000]
|
||||
+103b: e8 40 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+1040: 90[ ]+nop *
|
||||
+1041: 90[ ]+nop *
|
||||
+1042: 90[ ]+nop *
|
||||
+1043: 90[ ]+nop *
|
||||
# GD -> IE against local variable referenced through IE too
|
||||
+1044: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
+104b: 00 00 *
|
||||
+104d: 48 03 05 6c 11 10 00[ ]+add 1053036\(%rip\),%rax +# 1021c0 <_GLOBAL_OFFSET_TABLE_\+0x30>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x24
|
||||
+1054: 90[ ]+nop *
|
||||
+1055: 90[ ]+nop *
|
||||
+1056: 90[ ]+nop *
|
||||
+1057: 90[ ]+nop *
|
||||
# GD against hidden and local variable
|
||||
+1058: 66 66 66 66 48 8d 3d[ ]+lea 1053125\(%rip\),%rdi +# 102228 <_GLOBAL_OFFSET_TABLE_\+0x98>
|
||||
+105f: c5 11 10 00 *
|
||||
# -> R_X86_64_DTPMOD64 [0 0x4000000000000000]
|
||||
+1063: e8 18 f6 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+1068: 90[ ]+nop *
|
||||
+1069: 90[ ]+nop *
|
||||
+106a: 90[ ]+nop *
|
||||
+106b: 90[ ]+nop *
|
||||
# GD -> IE against hidden and local variable referenced through IE too
|
||||
+106c: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
+1073: 00 00 *
|
||||
+1075: 48 03 05 bc 11 10 00[ ]+add 1053116\(%rip\),%rax +# 102238 <_GLOBAL_OFFSET_TABLE_\+0xa8>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x44
|
||||
+107c: 90[ ]+nop *
|
||||
+107d: 90[ ]+nop *
|
||||
+107e: 90[ ]+nop *
|
||||
+107f: 90[ ]+nop *
|
||||
# GD against hidden but not local variable
|
||||
+1080: 66 66 66 66 48 8d 3d[ ]+lea 1053013\(%rip\),%rdi +# 1021e0 <_GLOBAL_OFFSET_TABLE_\+0x50>
|
||||
+1087: 55 11 10 00 *
|
||||
# -> R_X86_64_DTPMOD64 [0 0x6000000000000000]
|
||||
+108b: e8 f0 f5 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+1090: 90[ ]+nop *
|
||||
+1091: 90[ ]+nop *
|
||||
+1092: 90[ ]+nop *
|
||||
+1093: 90[ ]+nop *
|
||||
# GD -> IE against hidden but not local variable referenced through IE too
|
||||
+1094: 64 48 8b 04 25 00 00[ ]+mov %fs:0x0,%rax
|
||||
+109b: 00 00 *
|
||||
+109d: 48 03 05 4c 11 10 00[ ]+add 1053004\(%rip\),%rax +# 1021f0 <_GLOBAL_OFFSET_TABLE_\+0x60>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x64
|
||||
+10a4: 90[ ]+nop *
|
||||
+10a5: 90[ ]+nop *
|
||||
+10a6: 90[ ]+nop *
|
||||
+10a7: 90[ ]+nop *
|
||||
# LD
|
||||
+10a8: 48 8d 3d 21 11 10 00[ ]+lea 1052961\(%rip\),%rdi +# 1021d0 <_GLOBAL_OFFSET_TABLE_\+0x40>
|
||||
# -> R_X86_64_DTPMOD64 [0 0x000000000000000]
|
||||
+10af: e8 cc f5 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+10b4: 90[ ]+nop *
|
||||
+10b5: 90[ ]+nop *
|
||||
+10b6: 48 8d 90 20 00 00 00[ ]+lea 0x20\(%rax\),%rdx
|
||||
+10bd: 90[ ]+nop *
|
||||
+10be: 90[ ]+nop *
|
||||
+10bf: 4c 8d 88 26 00 00 00[ ]+lea 0x26\(%rax\),%r9
|
||||
+10c6: 90[ ]+nop *
|
||||
+10c7: 90[ ]+nop *
|
||||
+10c8: 90[ ]+nop *
|
||||
+10c9: 90[ ]+nop *
|
||||
# LD against hidden and local variables
|
||||
+10ca: 48 8d 3d ff 10 10 00[ ]+lea 1052927\(%rip\),%rdi +# 1021d0 <_GLOBAL_OFFSET_TABLE_\+0x40>
|
||||
# -> R_X86_64_DTPMOD64 [0 0x000000000000000]
|
||||
+10d1: e8 aa f5 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+10d6: 90[ ]+nop *
|
||||
+10d7: 90[ ]+nop *
|
||||
+10d8: 48 8d 90 40 00 00 00[ ]+lea 0x40\(%rax\),%rdx
|
||||
+10df: 90[ ]+nop *
|
||||
+10e0: 90[ ]+nop *
|
||||
+10e1: 48 8d 88 47 00 00 00[ ]+lea 0x47\(%rax\),%rcx
|
||||
+10e8: 90[ ]+nop *
|
||||
+10e9: 90[ ]+nop *
|
||||
+10ea: 90[ ]+nop *
|
||||
+10eb: 90[ ]+nop *
|
||||
# LD against hidden but not local variables
|
||||
+10ec: 48 8d 3d dd 10 10 00[ ]+lea 1052893\(%rip\),%rdi +# 1021d0 <_GLOBAL_OFFSET_TABLE_\+0x40>
|
||||
# -> R_X86_64_DTPMOD64 [0 0x000000000000000]
|
||||
+10f3: e8 88 f5 ff ff[ ]+callq [0-9a-f]+ <.*>
|
||||
# -> R_X86_64_JUMP_SLOT __tls_get_addr
|
||||
+10f8: 90[ ]+nop *
|
||||
+10f9: 90[ ]+nop *
|
||||
+10fa: 4c 8d a0 60 00 00 00[ ]+lea 0x60\(%rax\),%r12
|
||||
+1101: 90[ ]+nop *
|
||||
+1102: 90[ ]+nop *
|
||||
+1103: 48 8d 88 65 00 00 00[ ]+lea 0x65\(%rax\),%rcx
|
||||
+110a: 90[ ]+nop *
|
||||
+110b: 90[ ]+nop *
|
||||
# IE against global var
|
||||
+110c: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
|
||||
+1113: 00 00 *
|
||||
+1115: 90[ ]+nop *
|
||||
+1116: 90[ ]+nop *
|
||||
+1117: 48 03 0d 02 11 10 00[ ]+add 1052930\(%rip\),%rcx +# 102220 <_GLOBAL_OFFSET_TABLE_\+0x90>
|
||||
# -> R_X86_64_TPOFF64 sg2
|
||||
+111e: 90[ ]+nop *
|
||||
+111f: 90[ ]+nop *
|
||||
+1120: 90[ ]+nop *
|
||||
+1121: 90[ ]+nop *
|
||||
# IE against local var
|
||||
+1122: 64 4c 8b 34 25 00 00[ ]+mov %fs:0x0,%r14
|
||||
+1129: 00 00 *
|
||||
+112b: 90[ ]+nop *
|
||||
+112c: 90[ ]+nop *
|
||||
+112d: 4c 03 35 8c 10 10 00[ ]+add 1052812\(%rip\),%r14 +# 1021c0 <_GLOBAL_OFFSET_TABLE_\+0x30>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x24
|
||||
+1134: 90[ ]+nop *
|
||||
+1135: 90[ ]+nop *
|
||||
+1136: 90[ ]+nop *
|
||||
+1137: 90[ ]+nop *
|
||||
# IE against hidden and local var
|
||||
+1138: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
|
||||
+113f: 00 00 *
|
||||
+1141: 90[ ]+nop *
|
||||
+1142: 90[ ]+nop *
|
||||
+1143: 48 03 0d ee 10 10 00[ ]+add 1052910\(%rip\),%rcx +# 102238 <_GLOBAL_OFFSET_TABLE_\+0xa8>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x44
|
||||
+114a: 90[ ]+nop *
|
||||
+114b: 90[ ]+nop *
|
||||
+114c: 90[ ]+nop *
|
||||
+114d: 90[ ]+nop *
|
||||
# IE against hidden but not local var
|
||||
+114e: 64 48 8b 0c 25 00 00[ ]+mov %fs:0x0,%rcx
|
||||
+1155: 00 00 *
|
||||
+1157: 90[ ]+nop *
|
||||
+1158: 90[ ]+nop *
|
||||
+1159: 48 03 0d 90 10 10 00[ ]+add 1052816\(%rip\),%rcx +# 1021f0 <_GLOBAL_OFFSET_TABLE_\+0x60>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x64
|
||||
+1160: 90[ ]+nop *
|
||||
+1161: 90[ ]+nop *
|
||||
+1162: 90[ ]+nop *
|
||||
+1163: 90[ ]+nop *
|
||||
# Direct access through %fs
|
||||
# IE against global var
|
||||
+1164: 48 8b 0d 8d 10 10 00[ ]+mov 1052813\(%rip\),%rcx +# 1021f8 <_GLOBAL_OFFSET_TABLE_\+0x68>
|
||||
# -> R_X86_64_TPOFF64 sg5
|
||||
+116b: 90[ ]+nop *
|
||||
+116c: 90[ ]+nop *
|
||||
+116d: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
|
||||
+1171: 90[ ]+nop *
|
||||
+1172: 90[ ]+nop *
|
||||
+1173: 90[ ]+nop *
|
||||
+1174: 90[ ]+nop *
|
||||
# IE against local var
|
||||
+1175: 4c 8b 15 4c 10 10 00[ ]+mov 1052748\(%rip\),%r10 +# 1021c8 <_GLOBAL_OFFSET_TABLE_\+0x38>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x30
|
||||
+117c: 90[ ]+nop *
|
||||
+117d: 90[ ]+nop *
|
||||
+117e: 64 4d 8b 22[ ]+mov %fs:\(%r10\),%r12
|
||||
+1182: 90[ ]+nop *
|
||||
+1183: 90[ ]+nop *
|
||||
+1184: 90[ ]+nop *
|
||||
+1185: 90[ ]+nop *
|
||||
# IE against hidden and local var
|
||||
+1186: 48 8b 15 83 10 10 00[ ]+mov 1052803\(%rip\),%rdx +# 102210 <_GLOBAL_OFFSET_TABLE_\+0x80>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x50
|
||||
+118d: 90[ ]+nop *
|
||||
+118e: 90[ ]+nop *
|
||||
+118f: 64 48 8b 12[ ]+mov %fs:\(%rdx\),%rdx
|
||||
+1193: 90[ ]+nop *
|
||||
+1194: 90[ ]+nop *
|
||||
+1195: 90[ ]+nop *
|
||||
+1196: 90[ ]+nop *
|
||||
# IE against hidden but not local var
|
||||
+1197: 48 8b 0d 7a 10 10 00[ ]+mov 1052794\(%rip\),%rcx +# 102218 <_GLOBAL_OFFSET_TABLE_\+0x88>
|
||||
# -> R_X86_64_TPOFF64 *ABS*+0x70
|
||||
+119e: 90[ ]+nop *
|
||||
+119f: 90[ ]+nop *
|
||||
+11a0: 64 48 8b 11[ ]+mov %fs:\(%rcx\),%rdx
|
||||
+11a4: 90[ ]+nop *
|
||||
+11a5: 90[ ]+nop *
|
||||
+11a6: 90[ ]+nop *
|
||||
+11a7: 90[ ]+nop *
|
||||
+11a8: c9[ ]+leaveq *
|
||||
+11a9: c3[ ]+retq *
|
||||
+11aa: 90[ ]+nop *
|
||||
+11ab: 90[ ]+nop *
|
162
ld/testsuite/ld-x86-64/tlspic.rd
Normal file
162
ld/testsuite/ld-x86-64/tlspic.rd
Normal file
@ -0,0 +1,162 @@
|
||||
#source: tlspic1.s
|
||||
#source: tlspic2.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#readelf: -WSsrl
|
||||
#target: x86_64-*-*
|
||||
|
||||
There are 17 section headers, starting at offset 0x[0-9a-f]+:
|
||||
|
||||
Section Headers:
|
||||
\[Nr\] Name +Type +Address +Off +Size +ES Flg Lk Inf Al
|
||||
\[ 0\] +NULL +0+ 0+ 0+ 00 +0 +0 +0
|
||||
\[ 1\] .hash +.*
|
||||
\[ 2\] .dynsym +.*
|
||||
\[ 3\] .dynstr +.*
|
||||
\[ 4\] .rela.dyn +.*
|
||||
\[ 5\] .rela.plt +.*
|
||||
\[ 6\] .plt +.*
|
||||
\[ 7\] .text +PROGBITS +0+1000 0+1000 0+1ac 00 +AX +0 +0 4096
|
||||
\[ 8\] .data +.*
|
||||
\[ 9\] .tdata +PROGBITS +0+102000 0+2000 0+60 00 WAT +0 +0 +1
|
||||
\[10\] .tbss +NOBITS +0+102060 0+2060 0+20 00 WAT +0 +0 +1
|
||||
\[11\] .dynamic +DYNAMIC +0+102060 0+2060 0+130 10 +WA +3 +0 +8
|
||||
\[12\] .got +PROGBITS +0+102190 0+2190 0+b0 08 +WA +0 +0 +8
|
||||
\[13\] .bss +.*
|
||||
\[14\] .shstrtab +.*
|
||||
\[15\] .symtab +.*
|
||||
\[16\] .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 +0x0+ 0x0+ 0x0+ 0x[0-9a-f]+ 0x[0-9a-f]+ R E 0x100000
|
||||
LOAD +0x0+2000 0x0+102000 0x0+102000 0x0+240 0x0+240 RW +0x100000
|
||||
DYNAMIC +0x0+2060 0x0+102060 0x0+102060 0x0+130 0x0+130 RW +0x8
|
||||
TLS +0x0+2000 0x0+102000 0x0+102000 0x0+60 0x0+80 R +0x1
|
||||
|
||||
Section to Segment mapping:
|
||||
Segment Sections...
|
||||
00 +.hash .dynsym .dynstr .rela.dyn .rela.plt .plt .text *
|
||||
01 +.tdata .tbss .dynamic .got *
|
||||
02 +.tbss .dynamic *
|
||||
03 +.tdata .tbss *
|
||||
|
||||
Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 14 entries:
|
||||
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
|
||||
0+1021b0 0+10 R_X86_64_DTPMOD64 +0+
|
||||
0+1021c0 0+12 R_X86_64_TPOFF64 +0+24
|
||||
0+1021c8 0+12 R_X86_64_TPOFF64 +0+30
|
||||
0+1021d0 0+10 R_X86_64_DTPMOD64 +0+
|
||||
0+1021e0 0+10 R_X86_64_DTPMOD64 +0+
|
||||
0+1021f0 0+12 R_X86_64_TPOFF64 +0+64
|
||||
0+102210 0+12 R_X86_64_TPOFF64 +0+50
|
||||
0+102218 0+12 R_X86_64_TPOFF64 +0+70
|
||||
0+102228 0+10 R_X86_64_DTPMOD64 +0+
|
||||
0+102238 0+12 R_X86_64_TPOFF64 +0+44
|
||||
0+1021f8 0+1200000012 R_X86_64_TPOFF64 +0+10 sg5 \+ 0
|
||||
0+102200 0+1400000010 R_X86_64_DTPMOD64 +0+ sg1 \+ 0
|
||||
0+102208 0+1400000011 R_X86_64_DTPOFF64 +0+ sg1 \+ 0
|
||||
0+102220 0+1700000012 R_X86_64_TPOFF64 +0+4 sg2 \+ 0
|
||||
|
||||
Relocation section '.rela.plt' at offset 0x658 contains 1 entries:
|
||||
+Offset +Info +Type +Symbol's Value Symbol's Name \+ Addend
|
||||
0+[0-9a-f]+ 0+1300000007 R_X86_64_JUMP_SLOT +0+ __tls_get_addr \+ 0
|
||||
|
||||
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+102060 +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 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
|
||||
+20: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
|
||||
+21: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
|
||||
+22: 0+102240 +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
+23: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
|
||||
+24: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
|
||||
+25: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
|
||||
+26: 0+102240 +0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
+27: 0+102190 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
|
||||
+28: 0+102240 +0 NOTYPE GLOBAL DEFAULT ABS _end
|
||||
|
||||
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+102060 +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 NOTYPE GLOBAL DEFAULT UND __tls_get_addr
|
||||
+47: 0+ +0 TLS +GLOBAL DEFAULT +9 sg1
|
||||
+48: 0+1000 +0 FUNC +GLOBAL DEFAULT +7 fn1
|
||||
+49: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS __bss_start
|
||||
+50: 0+4 +0 TLS +GLOBAL DEFAULT +9 sg2
|
||||
+51: 0+14 +0 TLS +GLOBAL DEFAULT +9 sg6
|
||||
+52: 0+18 +0 TLS +GLOBAL DEFAULT +9 sg7
|
||||
+53: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _edata
|
||||
+54: 0+102190 +0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE_
|
||||
+55: [0-9a-f]+ +0 NOTYPE GLOBAL DEFAULT ABS _end
|
21
ld/testsuite/ld-x86-64/tlspic.sd
Normal file
21
ld/testsuite/ld-x86-64/tlspic.sd
Normal file
@ -0,0 +1,21 @@
|
||||
#source: tlspic1.s
|
||||
#source: tlspic2.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#objdump: -sj.got
|
||||
#target: x86_64-*-*
|
||||
|
||||
.*: +file format elf64-x86-64
|
||||
|
||||
Contents of section .got:
|
||||
102190 [0-9a-f]+ [0-9a-f]+ 00000000 00000000 .*
|
||||
1021a0 00000000 00000000 [0-9a-f]+ [0-9a-f]+ .*
|
||||
1021b0 00000000 00000000 20000000 00000000 .*
|
||||
1021c0 00000000 00000000 00000000 00000000 .*
|
||||
1021d0 00000000 00000000 00000000 00000000 .*
|
||||
1021e0 00000000 00000000 60000000 00000000 .*
|
||||
1021f0 00000000 00000000 00000000 00000000 .*
|
||||
102200 00000000 00000000 00000000 00000000 .*
|
||||
102210 00000000 00000000 00000000 00000000 .*
|
||||
102220 00000000 00000000 00000000 00000000 .*
|
||||
102230 40000000 00000000 00000000 00000000 .*
|
16
ld/testsuite/ld-x86-64/tlspic.td
Normal file
16
ld/testsuite/ld-x86-64/tlspic.td
Normal file
@ -0,0 +1,16 @@
|
||||
#source: tlspic1.s
|
||||
#source: tlspic2.s
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#objdump: -sj.tdata
|
||||
#target: x86_64-*-*
|
||||
|
||||
.*: +file format elf64-x86-64
|
||||
|
||||
Contents of section .tdata:
|
||||
102000 11000000 12000000 13000000 14000000 .*
|
||||
102010 15000000 16000000 17000000 18000000 .*
|
||||
102020 41000000 42000000 43000000 44000000 .*
|
||||
102030 45000000 46000000 47000000 48000000 .*
|
||||
102040 01010000 02010000 03010000 04010000 .*
|
||||
102050 05010000 06010000 07010000 08010000 .*
|
171
ld/testsuite/ld-x86-64/tlspic1.s
Normal file
171
ld/testsuite/ld-x86-64/tlspic1.s
Normal file
@ -0,0 +1,171 @@
|
||||
/* Force .data aligned to 4K, so .got very likely gets at 0x102190
|
||||
(0x60 bytes .tdata and 0x130 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 0x1000. */
|
||||
.text
|
||||
.balign 4096
|
||||
.globl fn1
|
||||
.type fn1,@function
|
||||
fn1:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD */
|
||||
.long 0x66666666
|
||||
leaq sg1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> IE because variable is referenced through IE too */
|
||||
.long 0x66666666
|
||||
leaq sg2@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD against local variable */
|
||||
.long 0x66666666
|
||||
leaq sl1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> IE against local variable referenced through IE too */
|
||||
.long 0x66666666
|
||||
leaq sl2@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD against hidden and local variable */
|
||||
.long 0x66666666
|
||||
leaq sh1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> IE against hidden and local variable referenced through
|
||||
IE too */
|
||||
.long 0x66666666
|
||||
leaq sh2@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD against hidden but not local variable */
|
||||
.long 0x66666666
|
||||
leaq sH1@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* GD -> IE against hidden but not local variable referenced through
|
||||
IE too */
|
||||
.long 0x66666666
|
||||
leaq sH2@tlsgd(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LD */
|
||||
leaq sl1@tlsld(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop
|
||||
leaq sl1@dtpoff(%rax), %rdx
|
||||
nop;nop
|
||||
leaq 2+sl2@dtpoff(%rax), %r9
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LD against hidden and local variables */
|
||||
leaq sh1@tlsld(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop
|
||||
leaq sh1@dtpoff(%rax), %rdx
|
||||
nop;nop
|
||||
leaq sh2@dtpoff+3(%rax), %rcx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* LD against hidden but not local variables */
|
||||
leaq sH1@tlsld(%rip), %rdi
|
||||
call __tls_get_addr@plt
|
||||
nop;nop
|
||||
leaq sH1@dtpoff(%rax), %r12
|
||||
nop;nop
|
||||
leaq sH2@dtpoff+1(%rax), %rcx
|
||||
nop;nop
|
||||
|
||||
/* IE against global var */
|
||||
movq %fs:0, %rcx
|
||||
nop;nop
|
||||
addq sg2@gottpoff(%rip), %rcx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against local var */
|
||||
movq %fs:0, %r14
|
||||
nop;nop
|
||||
addq sl2@gottpoff(%rip), %r14
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against hidden and local var */
|
||||
movq %fs:0, %rcx
|
||||
nop;nop
|
||||
addq sh2@gottpoff(%rip), %rcx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against hidden but not local var */
|
||||
movq %fs:0, %rcx
|
||||
nop;nop
|
||||
addq sH2@gottpoff(%rip), %rcx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* Direct access through %fs */
|
||||
|
||||
/* IE against global var */
|
||||
movq sg5@gottpoff(%rip), %rcx
|
||||
nop;nop
|
||||
movq %fs:(%rcx), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against local var */
|
||||
movq sl5@gottpoff(%rip), %r10
|
||||
nop;nop
|
||||
movq %fs:(%r10), %r12
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against hidden and local var */
|
||||
movq sh5@gottpoff(%rip), %rdx
|
||||
nop;nop
|
||||
movq %fs:(%rdx), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
/* IE against hidden but not local var */
|
||||
movq sH5@gottpoff(%rip), %rcx
|
||||
nop;nop
|
||||
movq %fs:(%rcx), %rdx
|
||||
nop;nop;nop;nop
|
||||
|
||||
leave
|
||||
ret
|
11
ld/testsuite/ld-x86-64/tlspic2.s
Normal file
11
ld/testsuite/ld-x86-64/tlspic2.s
Normal file
@ -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
|
51
ld/testsuite/ld-x86-64/x86-64.exp
Normal file
51
ld/testsuite/ld-x86-64/x86-64.exp
Normal file
@ -0,0 +1,51 @@
|
||||
# Expect script for ld-x86_64 tests
|
||||
# Copyright (C) 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 x86_64 linking; all types of relocs. This tests the assembler and
|
||||
# tools like objdump as well as the linker.
|
||||
|
||||
if { !([istarget "x86_64-*-elf*"]
|
||||
|| [istarget "x86_64-*-linux*"]) } {
|
||||
return
|
||||
}
|
||||
|
||||
# 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 x86_64tests {
|
||||
{"TLS -fpic -shared transitions" "-shared -melf_x86_64"
|
||||
"--64" {tlspic1.s tlspic2.s}
|
||||
{{readelf -WSsrl tlspic.rd} {objdump -drj.text tlspic.dd}
|
||||
{objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}}
|
||||
"libtlspic.so"}
|
||||
{"Helper shared library" "-shared -melf_x86_64"
|
||||
"--64" {tlslib.s} {} "libtlslib.so"}
|
||||
{"TLS -fpic and -fno-pic exec transitions"
|
||||
"-melf_x86_64 tmpdir/libtlslib.so" "--64" {tlsbinpic.s tlsbin.s}
|
||||
{{readelf -WSsrl tlsbin.rd} {objdump -drj.text tlsbin.dd}
|
||||
{objdump -sj.got tlsbin.sd} {objdump -sj.tdata tlsbin.td}}
|
||||
"tlsbin"}
|
||||
}
|
||||
|
||||
run_ld_link_tests $x86_64tests
|
@ -961,6 +961,136 @@ proc file_contents { filename } {
|
||||
return $contents
|
||||
}
|
||||
|
||||
# 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).
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc verbose_eval { expr { level 1 } } {
|
||||
global verbose
|
||||
if $verbose>$level then { eval verbose "$expr" $level }
|
||||
|
Loading…
Reference in New Issue
Block a user