mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-23 02:51:56 +00:00
bfd/
* bfd-in2.h, libbfd.h: Regenerated. * reloc.c: Add ARM TLS relocations. * elf32-arm.c (elf32_arm_howto_table): Add dynamic TLS relocations. (elf32_arm_tls_gd32_howto, elf32_arm_tls_ldo32_howto) (elf32_arm_tls_ldm32_howto, elf32_arm_tls_le32_howto) (elf32_arm_tls_ie32_howto): New. (elf32_arm_howto_from_type): Support TLS relocations. (elf32_arm_reloc_map): Likewise. (elf32_arm_reloc_type_lookup): Likewise. (TCB_SIZE): Define. (struct elf32_arm_obj_tdata): New. (elf32_arm_tdata, elf32_arm_local_got_tls_type): Define. (elf32_arm_mkobject): New function. (struct elf32_arm_relocs_copied): Add pc_count. (elf32_arm_hash_entry, GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD) (GOT_TLS_IE): Define. (struct elf32_arm_link_hash_table): Add tls_ldm_got. (elf32_arm_link_hash_newfunc): Initialize tls_type. (elf32_arm_copy_indirect_symbol): Copy pc_count and tls_type. (elf32_arm_link_hash_table_create): Initialize tls_ldm_got. (dtpoff_base, tpoff): New functions. (elf32_arm_final_link_relocate): Handle TLS relocations. (IS_ARM_TLS_RELOC): Define. (elf32_arm_relocate_section): Warn about TLS mismatches. (elf32_arm_gc_sweep_hook): Handle TLS relocations and pc_count. (elf32_arm_check_relocs): Detect invalid symbol indexes. Handle TLS relocations and pc_count. (elf32_arm_adjust_dynamic_symbol): Check non_got_ref. (allocate_dynrelocs): Handle TLS. Bind REL32 relocs to local calls. (elf32_arm_size_dynamic_sections): Handle TLS. (elf32_arm_finish_dynamic_symbol): Likewise. (bfd_elf32_mkobject): Define. gas/ * config/tc-arm.c (arm_parse_reloc): Add TLS relocations. (md_apply_fix3): Mark TLS symbols. (tc_gen_reloc): Handle TLS relocations. (arm_fix_adjustable): Ignore TLS relocations. (s_arm_elf_cons): Support expressions after decorated symbols. gas/testuite/ * gas/arm/tls.s, gas/arm/tls.d: New files. * gas/arm/arm.exp: Run TLS test. include/elf/ * arm.h: Add TLS relocations. ld/testsuite/ * ld-arm/tls-lib.s, ld-arm/tls-lib.d, ld-arm/tls-lib.r, ld-arm/tls-app.s, ld-arm/tls-app.d, ld-arm/tls-app.r: New files. * ld-arm/arm-lib.ld, ld-arm/arm-dyn.ld: Increase data segment alignment. * ld-arm/arm-elf.exp: Run TLS tests.
This commit is contained in:
parent
71a976dd82
commit
ba93b8aced
@ -1,3 +1,41 @@
|
||||
2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
Phil Blundell <philb@gnu.org>
|
||||
|
||||
* bfd-in2.h, libbfd.h: Regenerated.
|
||||
* reloc.c: Add ARM TLS relocations.
|
||||
* elf32-arm.c (elf32_arm_howto_table): Add dynamic TLS
|
||||
relocations.
|
||||
(elf32_arm_tls_gd32_howto, elf32_arm_tls_ldo32_howto)
|
||||
(elf32_arm_tls_ldm32_howto, elf32_arm_tls_le32_howto)
|
||||
(elf32_arm_tls_ie32_howto): New.
|
||||
(elf32_arm_howto_from_type): Support TLS relocations.
|
||||
(elf32_arm_reloc_map): Likewise.
|
||||
(elf32_arm_reloc_type_lookup): Likewise.
|
||||
(TCB_SIZE): Define.
|
||||
(struct elf32_arm_obj_tdata): New.
|
||||
(elf32_arm_tdata, elf32_arm_local_got_tls_type): Define.
|
||||
(elf32_arm_mkobject): New function.
|
||||
(struct elf32_arm_relocs_copied): Add pc_count.
|
||||
(elf32_arm_hash_entry, GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD)
|
||||
(GOT_TLS_IE): Define.
|
||||
(struct elf32_arm_link_hash_table): Add tls_ldm_got.
|
||||
(elf32_arm_link_hash_newfunc): Initialize tls_type.
|
||||
(elf32_arm_copy_indirect_symbol): Copy pc_count and tls_type.
|
||||
(elf32_arm_link_hash_table_create): Initialize tls_ldm_got.
|
||||
(dtpoff_base, tpoff): New functions.
|
||||
(elf32_arm_final_link_relocate): Handle TLS relocations.
|
||||
(IS_ARM_TLS_RELOC): Define.
|
||||
(elf32_arm_relocate_section): Warn about TLS mismatches.
|
||||
(elf32_arm_gc_sweep_hook): Handle TLS relocations and pc_count.
|
||||
(elf32_arm_check_relocs): Detect invalid symbol indexes. Handle
|
||||
TLS relocations and pc_count.
|
||||
(elf32_arm_adjust_dynamic_symbol): Check non_got_ref.
|
||||
(allocate_dynrelocs): Handle TLS. Bind REL32 relocs to local
|
||||
calls.
|
||||
(elf32_arm_size_dynamic_sections): Handle TLS.
|
||||
(elf32_arm_finish_dynamic_symbol): Likewise.
|
||||
(bfd_elf32_mkobject): Define.
|
||||
|
||||
2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_check_relocs): Increment count for all
|
||||
|
@ -2691,6 +2691,14 @@ field in the instruction. */
|
||||
BFD_RELOC_ARM_RELATIVE,
|
||||
BFD_RELOC_ARM_GOTOFF,
|
||||
BFD_RELOC_ARM_GOTPC,
|
||||
BFD_RELOC_ARM_TLS_GD32,
|
||||
BFD_RELOC_ARM_TLS_LDO32,
|
||||
BFD_RELOC_ARM_TLS_LDM32,
|
||||
BFD_RELOC_ARM_TLS_DTPOFF32,
|
||||
BFD_RELOC_ARM_TLS_DTPMOD32,
|
||||
BFD_RELOC_ARM_TLS_TPOFF32,
|
||||
BFD_RELOC_ARM_TLS_IE32,
|
||||
BFD_RELOC_ARM_TLS_LE32,
|
||||
|
||||
/* Pc-relative or absolute relocation depending on target. Used for
|
||||
entries in .init_array sections. */
|
||||
|
753
bfd/elf32-arm.c
753
bfd/elf32-arm.c
@ -294,49 +294,49 @@ static reloc_howto_type elf32_arm_howto_table[] =
|
||||
0x07ff07ff, /* dst_mask */
|
||||
TRUE), /* pcrel_offset */
|
||||
|
||||
/* These next three relocs are not defined, but we need to fill the space. */
|
||||
/* Dynamic TLS relocations. */
|
||||
|
||||
HOWTO (R_ARM_NONE, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_unknown_17", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
HOWTO (R_ARM_TLS_DTPMOD32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TLS_DTPMOD32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_NONE, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_unknown_18", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
HOWTO (R_ARM_TLS_DTPOFF32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TLS_DTPOFF32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_NONE, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_unknown_19", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
HOWTO (R_ARM_TLS_TPOFF32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TLS_TPOFF32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* Relocs used in ARM Linux */
|
||||
|
||||
@ -663,6 +663,81 @@ static reloc_howto_type elf32_arm_howto_table[] =
|
||||
TRUE), /* pcrel_offset */
|
||||
};
|
||||
|
||||
static reloc_howto_type elf32_arm_tls_gd32_howto =
|
||||
HOWTO (R_ARM_TLS_GD32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
NULL, /* special_function */
|
||||
"R_ARM_TLS_GD32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE); /* pcrel_offset */
|
||||
|
||||
static reloc_howto_type elf32_arm_tls_ldo32_howto =
|
||||
HOWTO (R_ARM_TLS_LDO32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TLS_LDO32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE); /* pcrel_offset */
|
||||
|
||||
static reloc_howto_type elf32_arm_tls_ldm32_howto =
|
||||
HOWTO (R_ARM_TLS_LDM32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TLS_LDM32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE); /* pcrel_offset */
|
||||
|
||||
static reloc_howto_type elf32_arm_tls_le32_howto =
|
||||
HOWTO (R_ARM_TLS_LE32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TLS_LE32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE); /* pcrel_offset */
|
||||
|
||||
static reloc_howto_type elf32_arm_tls_ie32_howto =
|
||||
HOWTO (R_ARM_TLS_IE32, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_bitfield,/* complain_on_overflow */
|
||||
NULL, /* special_function */
|
||||
"R_ARM_TLS_IE32", /* name */
|
||||
TRUE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE); /* pcrel_offset */
|
||||
|
||||
/* GNU extension to record C++ vtable hierarchy */
|
||||
static reloc_howto_type elf32_arm_vtinherit_howto =
|
||||
HOWTO (R_ARM_GNU_VTINHERIT, /* type */
|
||||
@ -825,6 +900,26 @@ elf32_arm_howto_from_type (unsigned int r_type)
|
||||
|
||||
case R_ARM_THM_PC9:
|
||||
return &elf32_arm_thm_pc9_howto;
|
||||
|
||||
case R_ARM_TLS_GD32:
|
||||
return &elf32_arm_tls_gd32_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_LDO32:
|
||||
return &elf32_arm_tls_ldo32_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_LDM32:
|
||||
return &elf32_arm_tls_ldm32_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_IE32:
|
||||
return &elf32_arm_tls_ie32_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_LE32:
|
||||
return &elf32_arm_tls_le32_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_RREL32:
|
||||
case R_ARM_RABS32:
|
||||
@ -879,7 +974,16 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
|
||||
{BFD_RELOC_ARM_ROSEGREL32, R_ARM_ROSEGREL32},
|
||||
{BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32},
|
||||
{BFD_RELOC_ARM_PREL31, R_ARM_PREL31},
|
||||
{BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2}
|
||||
{BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2},
|
||||
{BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
|
||||
{BFD_RELOC_ARM_TLS_GD32, R_ARM_TLS_GD32},
|
||||
{BFD_RELOC_ARM_TLS_LDO32, R_ARM_TLS_LDO32},
|
||||
{BFD_RELOC_ARM_TLS_LDM32, R_ARM_TLS_LDM32},
|
||||
{BFD_RELOC_ARM_TLS_DTPMOD32, R_ARM_TLS_DTPMOD32},
|
||||
{BFD_RELOC_ARM_TLS_DTPOFF32, R_ARM_TLS_DTPOFF32},
|
||||
{BFD_RELOC_ARM_TLS_TPOFF32, R_ARM_TLS_TPOFF32},
|
||||
{BFD_RELOC_ARM_TLS_IE32, R_ARM_TLS_IE32},
|
||||
{BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32},
|
||||
};
|
||||
|
||||
static reloc_howto_type *
|
||||
@ -903,6 +1007,21 @@ elf32_arm_reloc_type_lookup (abfd, code)
|
||||
case BFD_RELOC_THUMB_PCREL_BRANCH9:
|
||||
return & elf32_arm_thm_pc9_howto;
|
||||
|
||||
case BFD_RELOC_ARM_TLS_GD32:
|
||||
return & elf32_arm_tls_gd32_howto;
|
||||
|
||||
case BFD_RELOC_ARM_TLS_LDO32:
|
||||
return & elf32_arm_tls_ldo32_howto;
|
||||
|
||||
case BFD_RELOC_ARM_TLS_LDM32:
|
||||
return & elf32_arm_tls_ldm32_howto;
|
||||
|
||||
case BFD_RELOC_ARM_TLS_IE32:
|
||||
return & elf32_arm_tls_ie32_howto;
|
||||
|
||||
case BFD_RELOC_ARM_TLS_LE32:
|
||||
return & elf32_arm_tls_le32_howto;
|
||||
|
||||
default:
|
||||
for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
|
||||
if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
|
||||
@ -1093,14 +1212,41 @@ struct _arm_elf_section_data
|
||||
#define elf32_arm_section_data(sec) \
|
||||
((struct _arm_elf_section_data *) elf_section_data (sec))
|
||||
|
||||
/* The size of the thread control block. */
|
||||
#define TCB_SIZE 8
|
||||
|
||||
struct elf32_arm_obj_tdata
|
||||
{
|
||||
struct elf_obj_tdata root;
|
||||
|
||||
/* tls_type for each local got entry. */
|
||||
char *local_got_tls_type;
|
||||
};
|
||||
|
||||
#define elf32_arm_tdata(abfd) \
|
||||
((struct elf32_arm_obj_tdata *) (abfd)->tdata.any)
|
||||
|
||||
#define elf32_arm_local_got_tls_type(abfd) \
|
||||
(elf32_arm_tdata (abfd)->local_got_tls_type)
|
||||
|
||||
static bfd_boolean
|
||||
elf32_arm_mkobject (bfd *abfd)
|
||||
{
|
||||
bfd_size_type amt = sizeof (struct elf32_arm_obj_tdata);
|
||||
abfd->tdata.any = bfd_zalloc (abfd, amt);
|
||||
if (abfd->tdata.any == NULL)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* The ARM linker needs to keep track of the number of relocs that it
|
||||
decides to copy in check_relocs for each symbol. This is so that
|
||||
it can discard PC relative relocs if it doesn't need them when
|
||||
linking with -Bsymbolic. We store the information in a field
|
||||
extending the regular ELF linker hash table. */
|
||||
|
||||
/* This structure keeps track of the number of PC relative relocs we
|
||||
have copied for a given symbol. */
|
||||
/* This structure keeps track of the number of relocs we have copied
|
||||
for a given symbol. */
|
||||
struct elf32_arm_relocs_copied
|
||||
{
|
||||
/* Next section. */
|
||||
@ -1109,8 +1255,12 @@ struct elf32_arm_relocs_copied
|
||||
asection * section;
|
||||
/* Number of relocs copied in this section. */
|
||||
bfd_size_type count;
|
||||
/* Number of PC-relative relocs copied in this section. */
|
||||
bfd_size_type pc_count;
|
||||
};
|
||||
|
||||
#define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent))
|
||||
|
||||
/* Arm ELF linker hash entry. */
|
||||
struct elf32_arm_link_hash_entry
|
||||
{
|
||||
@ -1127,6 +1277,12 @@ struct elf32_arm_link_hash_entry
|
||||
used, we need to record the index into .got.plt instead of
|
||||
recomputing it from the PLT offset. */
|
||||
bfd_signed_vma plt_got_offset;
|
||||
|
||||
#define GOT_UNKNOWN 0
|
||||
#define GOT_NORMAL 1
|
||||
#define GOT_TLS_GD 2
|
||||
#define GOT_TLS_IE 4
|
||||
unsigned char tls_type;
|
||||
};
|
||||
|
||||
/* Traverse an arm ELF linker hash table. */
|
||||
@ -1189,6 +1345,12 @@ struct elf32_arm_link_hash_table
|
||||
asection *sdynbss;
|
||||
asection *srelbss;
|
||||
|
||||
/* Data for R_ARM_TLS_LDM32 relocations. */
|
||||
union {
|
||||
bfd_signed_vma refcount;
|
||||
bfd_vma offset;
|
||||
} tls_ldm_got;
|
||||
|
||||
/* Small local sym to section mapping cache. */
|
||||
struct sym_sec_cache sym_sec;
|
||||
|
||||
@ -1220,6 +1382,7 @@ elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
|
||||
if (ret != NULL)
|
||||
{
|
||||
ret->relocs_copied = NULL;
|
||||
ret->tls_type = GOT_UNKNOWN;
|
||||
ret->plt_thumb_refcount = 0;
|
||||
ret->plt_got_offset = -1;
|
||||
}
|
||||
@ -1321,6 +1484,7 @@ elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
|
||||
for (q = edir->relocs_copied; q != NULL; q = q->next)
|
||||
if (q->section == p->section)
|
||||
{
|
||||
q->pc_count += p->pc_count;
|
||||
q->count += p->count;
|
||||
*pp = p->next;
|
||||
break;
|
||||
@ -1346,6 +1510,13 @@ elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
|
||||
else
|
||||
BFD_ASSERT (eind->plt_thumb_refcount == 0);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1392,6 +1563,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
|
||||
ret->use_rel = 1;
|
||||
ret->sym_sec.abfd = NULL;
|
||||
ret->obfd = abfd;
|
||||
ret->tls_ldm_got.refcount = 0;
|
||||
|
||||
return &ret->root.root;
|
||||
}
|
||||
@ -2228,6 +2400,35 @@ arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
|
||||
#endif /* OLD_ARM_ABI */
|
||||
|
||||
|
||||
/* 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 (struct bfd_link_info *info)
|
||||
{
|
||||
/* If tls_sec is NULL, we should have signalled an error already. */
|
||||
if (elf_hash_table (info)->tls_sec == NULL)
|
||||
return 0;
|
||||
return elf_hash_table (info)->tls_sec->vma;
|
||||
}
|
||||
|
||||
/* Return the relocation value for @tpoff relocation
|
||||
if STT_TLS virtual address is ADDRESS. */
|
||||
|
||||
static bfd_vma
|
||||
tpoff (struct bfd_link_info *info, bfd_vma address)
|
||||
{
|
||||
struct elf_link_hash_table *htab = elf_hash_table (info);
|
||||
bfd_vma base;
|
||||
|
||||
/* If tls_sec is NULL, we should have signalled an error already. */
|
||||
if (htab->tls_sec == NULL)
|
||||
return 0;
|
||||
base = align_power ((bfd_vma) TCB_SIZE, htab->tls_sec->alignment_power);
|
||||
return address - htab->tls_sec->vma + base;
|
||||
}
|
||||
|
||||
/* Perform a relocation as part of a final link. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
@ -2979,6 +3180,222 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
contents, rel->r_offset, value,
|
||||
(bfd_vma) 0);
|
||||
|
||||
case R_ARM_TLS_LDO32:
|
||||
value = value - dtpoff_base (info);
|
||||
|
||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset, value, (bfd_vma) 0);
|
||||
|
||||
case R_ARM_TLS_LDM32:
|
||||
{
|
||||
bfd_vma off;
|
||||
|
||||
if (globals->sgot == NULL)
|
||||
abort ();
|
||||
|
||||
off = globals->tls_ldm_got.offset;
|
||||
|
||||
if ((off & 1) != 0)
|
||||
off &= ~1;
|
||||
else
|
||||
{
|
||||
/* If we don't know the module number, create a relocation
|
||||
for it. */
|
||||
if (info->shared)
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
bfd_byte *loc;
|
||||
|
||||
if (globals->srelgot == NULL)
|
||||
abort ();
|
||||
|
||||
outrel.r_offset = (globals->sgot->output_section->vma
|
||||
+ globals->sgot->output_offset + off);
|
||||
outrel.r_info = ELF32_R_INFO (0, R_ARM_TLS_DTPMOD32);
|
||||
|
||||
bfd_put_32 (output_bfd, 0, globals->sgot->contents + off);
|
||||
|
||||
loc = globals->srelgot->contents;
|
||||
loc += globals->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
|
||||
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
|
||||
}
|
||||
else
|
||||
bfd_put_32 (output_bfd, 1, globals->sgot->contents + off);
|
||||
|
||||
globals->tls_ldm_got.offset |= 1;
|
||||
}
|
||||
|
||||
value = globals->sgot->output_section->vma + globals->sgot->output_offset + off
|
||||
- (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
|
||||
|
||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset, value,
|
||||
(bfd_vma) 0);
|
||||
}
|
||||
|
||||
case R_ARM_TLS_GD32:
|
||||
case R_ARM_TLS_IE32:
|
||||
{
|
||||
bfd_vma off;
|
||||
int indx;
|
||||
char tls_type;
|
||||
|
||||
if (globals->sgot == NULL)
|
||||
abort ();
|
||||
|
||||
indx = 0;
|
||||
if (h != NULL)
|
||||
{
|
||||
bfd_boolean dyn;
|
||||
dyn = globals->root.dynamic_sections_created;
|
||||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
|
||||
&& (!info->shared
|
||||
|| !SYMBOL_REFERENCES_LOCAL (info, h)))
|
||||
{
|
||||
*unresolved_reloc_p = FALSE;
|
||||
indx = h->dynindx;
|
||||
}
|
||||
off = h->got.offset;
|
||||
tls_type = ((struct elf32_arm_link_hash_entry *) h)->tls_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (local_got_offsets == NULL)
|
||||
abort ();
|
||||
off = local_got_offsets[r_symndx];
|
||||
tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
|
||||
}
|
||||
|
||||
if (tls_type == GOT_UNKNOWN)
|
||||
abort ();
|
||||
|
||||
if ((off & 1) != 0)
|
||||
off &= ~1;
|
||||
else
|
||||
{
|
||||
bfd_boolean need_relocs = FALSE;
|
||||
Elf_Internal_Rela outrel;
|
||||
bfd_byte *loc = NULL;
|
||||
int cur_off = off;
|
||||
|
||||
/* The GOT entries have not been initialized yet. Do it
|
||||
now, and emit any relocations. If both an IE GOT and a
|
||||
GD GOT are necessary, we emit the GD first. */
|
||||
|
||||
if ((info->shared || indx != 0)
|
||||
&& (h == NULL
|
||||
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak))
|
||||
{
|
||||
need_relocs = TRUE;
|
||||
if (globals->srelgot == NULL)
|
||||
abort ();
|
||||
loc = globals->srelgot->contents;
|
||||
loc += globals->srelgot->reloc_count * sizeof (Elf32_External_Rel);
|
||||
}
|
||||
|
||||
if (tls_type & GOT_TLS_GD)
|
||||
{
|
||||
if (need_relocs)
|
||||
{
|
||||
outrel.r_offset = (globals->sgot->output_section->vma
|
||||
+ globals->sgot->output_offset + cur_off);
|
||||
outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32);
|
||||
bfd_put_32 (output_bfd, 0, globals->sgot->contents + cur_off);
|
||||
|
||||
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
|
||||
globals->srelgot->reloc_count++;
|
||||
loc += sizeof (Elf32_External_Rel);
|
||||
|
||||
if (indx == 0)
|
||||
bfd_put_32 (output_bfd, value - dtpoff_base (info),
|
||||
globals->sgot->contents + cur_off + 4);
|
||||
else
|
||||
{
|
||||
bfd_put_32 (output_bfd, 0,
|
||||
globals->sgot->contents + cur_off + 4);
|
||||
|
||||
outrel.r_info = ELF32_R_INFO (indx,
|
||||
R_ARM_TLS_DTPOFF32);
|
||||
outrel.r_offset += 4;
|
||||
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
|
||||
globals->srelgot->reloc_count++;
|
||||
loc += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we are not emitting relocations for a
|
||||
general dynamic reference, then we must be in a
|
||||
static link or an executable link with the
|
||||
symbol binding locally. Mark it as belonging
|
||||
to module 1, the executable. */
|
||||
bfd_put_32 (output_bfd, 1,
|
||||
globals->sgot->contents + cur_off);
|
||||
bfd_put_32 (output_bfd, value - dtpoff_base (info),
|
||||
globals->sgot->contents + cur_off + 4);
|
||||
}
|
||||
|
||||
cur_off += 8;
|
||||
}
|
||||
|
||||
if (tls_type & GOT_TLS_IE)
|
||||
{
|
||||
if (need_relocs)
|
||||
{
|
||||
outrel.r_offset = (globals->sgot->output_section->vma
|
||||
+ globals->sgot->output_offset
|
||||
+ cur_off);
|
||||
outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_TPOFF32);
|
||||
|
||||
if (indx == 0)
|
||||
bfd_put_32 (output_bfd, value - dtpoff_base (info),
|
||||
globals->sgot->contents + cur_off);
|
||||
else
|
||||
bfd_put_32 (output_bfd, 0,
|
||||
globals->sgot->contents + cur_off);
|
||||
|
||||
bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
|
||||
globals->srelgot->reloc_count++;
|
||||
loc += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
else
|
||||
bfd_put_32 (output_bfd, tpoff (info, value),
|
||||
globals->sgot->contents + cur_off);
|
||||
cur_off += 4;
|
||||
}
|
||||
|
||||
if (h != NULL)
|
||||
h->got.offset |= 1;
|
||||
else
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
}
|
||||
|
||||
if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
|
||||
off += 8;
|
||||
value = globals->sgot->output_section->vma + globals->sgot->output_offset + off
|
||||
- (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
|
||||
|
||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset, value,
|
||||
(bfd_vma) 0);
|
||||
}
|
||||
|
||||
case R_ARM_TLS_LE32:
|
||||
if (info->shared)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"),
|
||||
input_bfd, input_section,
|
||||
(long) rel->r_offset, howto->name);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
value = tpoff (info, value);
|
||||
|
||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset, value, (bfd_vma) 0);
|
||||
|
||||
case R_ARM_SBREL32:
|
||||
return bfd_reloc_notsupported;
|
||||
|
||||
@ -3098,6 +3515,16 @@ arm_add_to_rel (bfd * abfd,
|
||||
}
|
||||
}
|
||||
|
||||
#define IS_ARM_TLS_RELOC(R_TYPE) \
|
||||
((R_TYPE) == R_ARM_TLS_GD32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_LDO32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_LDM32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_DTPOFF32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_DTPMOD32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_TPOFF32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_LE32 \
|
||||
|| (R_TYPE) == R_ARM_TLS_IE32)
|
||||
|
||||
/* Relocate an ARM ELF section. */
|
||||
static bfd_boolean
|
||||
elf32_arm_relocate_section (bfd * output_bfd,
|
||||
@ -3136,6 +3563,7 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
||||
bfd_vma relocation;
|
||||
bfd_reloc_status_type r;
|
||||
arelent bfd_reloc;
|
||||
char sym_type;
|
||||
bfd_boolean unresolved_reloc = FALSE;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
@ -3179,6 +3607,7 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
{
|
||||
sym = local_syms + r_symndx;
|
||||
sym_type = ELF32_ST_TYPE (sym->st_info);
|
||||
sec = local_sections[r_symndx];
|
||||
if (globals->use_rel)
|
||||
{
|
||||
@ -3232,6 +3661,8 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
||||
r_symndx, symtab_hdr, sym_hashes,
|
||||
h, sec, relocation,
|
||||
unresolved_reloc, warned);
|
||||
|
||||
sym_type = h->type;
|
||||
}
|
||||
|
||||
if (h != NULL)
|
||||
@ -3244,6 +3675,24 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
||||
name = bfd_section_name (input_bfd, sec);
|
||||
}
|
||||
|
||||
if (r_symndx != 0
|
||||
&& r_type != R_ARM_NONE
|
||||
&& (h == NULL
|
||||
|| h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
&& IS_ARM_TLS_RELOC (r_type) != (sym_type == STT_TLS))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
((sym_type == STT_TLS
|
||||
? _("%B(%A+0x%lx): %s used with TLS symbol %s")
|
||||
: _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
|
||||
input_bfd,
|
||||
input_section,
|
||||
(long) rel->r_offset,
|
||||
howto->name,
|
||||
name);
|
||||
}
|
||||
|
||||
r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||
input_section, contents, rel,
|
||||
relocation, info, sec, name,
|
||||
@ -3823,10 +4272,10 @@ elf32_arm_gc_mark_hook (asection * sec,
|
||||
/* Update the got entry reference counts for the section being removed. */
|
||||
|
||||
static bfd_boolean
|
||||
elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
struct bfd_link_info * info ATTRIBUTE_UNUSED,
|
||||
asection * sec ATTRIBUTE_UNUSED,
|
||||
const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
|
||||
elf32_arm_gc_sweep_hook (bfd * abfd,
|
||||
struct bfd_link_info * info,
|
||||
asection * sec,
|
||||
const Elf_Internal_Rela * relocs)
|
||||
{
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
@ -3868,6 +4317,8 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_GOT_PREL:
|
||||
#endif
|
||||
case R_ARM_TLS_GD32:
|
||||
case R_ARM_TLS_IE32:
|
||||
if (h != NULL)
|
||||
{
|
||||
if (h->got.refcount > 0)
|
||||
@ -3880,6 +4331,10 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_LDM32:
|
||||
elf32_arm_hash_table (info)->tls_ldm_got.refcount -= 1;
|
||||
break;
|
||||
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_REL32:
|
||||
case R_ARM_PC24:
|
||||
@ -3915,6 +4370,8 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
if (p->section == sec)
|
||||
{
|
||||
p->count -= 1;
|
||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
|
||||
p->pc_count -= 1;
|
||||
if (p->count == 0)
|
||||
*pp = p->next;
|
||||
break;
|
||||
@ -3986,6 +4443,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
#ifndef OLD_ARM_ABI
|
||||
r_type = arm_real_reloc_type (htab, r_type);
|
||||
#endif
|
||||
|
||||
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
|
||||
{
|
||||
(*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
|
||||
r_symndx);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
h = NULL;
|
||||
else
|
||||
@ -3999,33 +4464,69 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_GOT_PREL:
|
||||
#endif
|
||||
case R_ARM_TLS_GD32:
|
||||
case R_ARM_TLS_IE32:
|
||||
/* This symbol requires a global offset table entry. */
|
||||
if (h != NULL)
|
||||
{
|
||||
h->got.refcount++;
|
||||
}
|
||||
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)
|
||||
{
|
||||
case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
|
||||
case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
|
||||
default: tls_type = GOT_NORMAL; break;
|
||||
}
|
||||
|
||||
size = symtab_hdr->sh_info;
|
||||
size *= (sizeof (bfd_signed_vma) + sizeof (char));
|
||||
local_got_refcounts = bfd_zalloc (abfd, size);
|
||||
if (local_got_refcounts == NULL)
|
||||
return FALSE;
|
||||
elf_local_got_refcounts (abfd) = local_got_refcounts;
|
||||
}
|
||||
local_got_refcounts[r_symndx] += 1;
|
||||
}
|
||||
if (r_type == R_ARM_GOT32)
|
||||
break;
|
||||
/* Fall through. */
|
||||
if (h != NULL)
|
||||
{
|
||||
h->got.refcount++;
|
||||
old_tls_type = elf32_arm_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_zalloc (abfd, size);
|
||||
if (local_got_refcounts == NULL)
|
||||
return FALSE;
|
||||
elf_local_got_refcounts (abfd) = local_got_refcounts;
|
||||
elf32_arm_local_got_tls_type (abfd)
|
||||
= (char *) (local_got_refcounts + symtab_hdr->sh_info);
|
||||
}
|
||||
local_got_refcounts[r_symndx] += 1;
|
||||
old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
|
||||
}
|
||||
|
||||
/* We will already have issued an error message if there is a
|
||||
TLS / non-TLS mismatch, based on the symbol type. We don't
|
||||
support any linker relaxations. So just combine any TLS
|
||||
types needed. */
|
||||
if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
|
||||
&& tls_type != GOT_NORMAL)
|
||||
tls_type |= old_tls_type;
|
||||
|
||||
if (old_tls_type != tls_type)
|
||||
{
|
||||
if (h != NULL)
|
||||
elf32_arm_hash_entry (h)->tls_type = tls_type;
|
||||
else
|
||||
elf32_arm_local_got_tls_type (abfd) [r_symndx] = tls_type;
|
||||
}
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case R_ARM_TLS_LDM32:
|
||||
if (r_type == R_ARM_TLS_LDM32)
|
||||
htab->tls_ldm_got.refcount++;
|
||||
/* Fall through */
|
||||
|
||||
case R_ARM_GOTOFF:
|
||||
case R_ARM_GOTPC:
|
||||
@ -4176,8 +4677,11 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
*head = p;
|
||||
p->section = sec;
|
||||
p->count = 0;
|
||||
p->pc_count = 0;
|
||||
}
|
||||
|
||||
if (r_type == R_ARM_REL32)
|
||||
p->pc_count += 1;
|
||||
p->count += 1;
|
||||
}
|
||||
break;
|
||||
@ -4404,6 +4908,11 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If there are no non-GOT references, we do not need a copy
|
||||
relocation. */
|
||||
if (!h->non_got_ref)
|
||||
return TRUE;
|
||||
|
||||
/* This is a reference to a symbol defined by a dynamic object which
|
||||
is not a function. */
|
||||
|
||||
@ -4571,6 +5080,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||
{
|
||||
asection *s;
|
||||
bfd_boolean dyn;
|
||||
int tls_type = elf32_arm_hash_entry (h)->tls_type;
|
||||
int indx;
|
||||
|
||||
/* Make sure this symbol is output as a dynamic symbol.
|
||||
Undefined weak syms won't yet be marked as dynamic. */
|
||||
@ -4585,12 +5096,49 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||
{
|
||||
s = htab->sgot;
|
||||
h->got.offset = s->size;
|
||||
s->size += 4;
|
||||
|
||||
if (tls_type == GOT_UNKNOWN)
|
||||
abort ();
|
||||
|
||||
if (tls_type == GOT_NORMAL)
|
||||
/* Non-TLS symbols need one GOT slot. */
|
||||
s->size += 4;
|
||||
else
|
||||
{
|
||||
if (tls_type & GOT_TLS_GD)
|
||||
/* R_ARM_TLS_GD32 needs 2 consecutive GOT slots. */
|
||||
s->size += 8;
|
||||
if (tls_type & GOT_TLS_IE)
|
||||
/* R_ARM_TLS_IE32 needs one GOT slot. */
|
||||
s->size += 4;
|
||||
}
|
||||
|
||||
dyn = htab->root.dynamic_sections_created;
|
||||
if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
&& (info->shared
|
||||
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
|
||||
|
||||
indx = 0;
|
||||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
|
||||
&& (!info->shared
|
||||
|| !SYMBOL_REFERENCES_LOCAL (info, h)))
|
||||
indx = h->dynindx;
|
||||
|
||||
if (tls_type != GOT_NORMAL
|
||||
&& (info->shared || indx != 0)
|
||||
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak))
|
||||
{
|
||||
if (tls_type & GOT_TLS_IE)
|
||||
htab->srelgot->size += sizeof (Elf32_External_Rel);
|
||||
|
||||
if (tls_type & GOT_TLS_GD)
|
||||
htab->srelgot->size += sizeof (Elf32_External_Rel);
|
||||
|
||||
if ((tls_type & GOT_TLS_GD) && indx != 0)
|
||||
htab->srelgot->size += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
&& (info->shared
|
||||
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
|
||||
htab->srelgot->size += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
}
|
||||
@ -4608,7 +5156,28 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|
||||
|
||||
if (info->shared || htab->root.is_relocatable_executable)
|
||||
{
|
||||
/* Discard relocs on undefined weak syms with non-default
|
||||
/* The only reloc that uses pc_count is R_ARM_REL32, which will
|
||||
appear on something like ".long foo - .". We want calls to
|
||||
protected symbols to resolve directly to the function rather
|
||||
than going via the plt. If people want function pointer
|
||||
comparisons to work as expected then they should avoid
|
||||
writing assembly like ".long foo - .". */
|
||||
if (SYMBOL_CALLS_LOCAL (info, h))
|
||||
{
|
||||
struct elf32_arm_relocs_copied **pp;
|
||||
|
||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL; )
|
||||
{
|
||||
p->count -= p->pc_count;
|
||||
p->pc_count = 0;
|
||||
if (p->count == 0)
|
||||
*pp = p->next;
|
||||
else
|
||||
pp = &p->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Also discard relocs on undefined weak syms with non-default
|
||||
visibility. */
|
||||
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
||||
&& h->root.type == bfd_link_hash_undefweak)
|
||||
@ -4773,6 +5342,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
|
||||
locsymcount = symtab_hdr->sh_info;
|
||||
end_local_got = local_got + locsymcount;
|
||||
local_tls_type = elf32_arm_local_got_tls_type (ibfd);
|
||||
s = htab->sgot;
|
||||
srel = htab->srelgot;
|
||||
for (; local_got < end_local_got; ++local_got, ++local_tls_type)
|
||||
@ -4780,8 +5350,15 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
if (*local_got > 0)
|
||||
{
|
||||
*local_got = s->size;
|
||||
s->size += 4;
|
||||
if (info->shared)
|
||||
if (*local_tls_type & GOT_TLS_GD)
|
||||
/* TLS_GD relocs need an 8-byte structure in the GOT. */
|
||||
s->size += 8;
|
||||
if (*local_tls_type & GOT_TLS_IE)
|
||||
s->size += 4;
|
||||
if (*local_tls_type == GOT_NORMAL)
|
||||
s->size += 4;
|
||||
|
||||
if (info->shared || *local_tls_type == GOT_TLS_GD)
|
||||
srel->size += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
else
|
||||
@ -4789,6 +5366,18 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
|
||||
}
|
||||
}
|
||||
|
||||
if (htab->tls_ldm_got.refcount > 0)
|
||||
{
|
||||
/* Allocate two GOT entries and one dynamic relocation (if necessary)
|
||||
for R_ARM_TLS_LDM32 relocations. */
|
||||
htab->tls_ldm_got.offset = htab->sgot->size;
|
||||
htab->sgot->size += 8;
|
||||
if (info->shared)
|
||||
htab->srelgot->size += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
else
|
||||
htab->tls_ldm_got.offset = -1;
|
||||
|
||||
/* Allocate global sym .plt and .got entries, and space for global
|
||||
sym dynamic relocs. */
|
||||
elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
|
||||
@ -5059,7 +5648,9 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
|
||||
}
|
||||
}
|
||||
|
||||
if (h->got.offset != (bfd_vma) -1)
|
||||
if (h->got.offset != (bfd_vma) -1
|
||||
&& (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_GD) == 0
|
||||
&& (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_IE) == 0)
|
||||
{
|
||||
asection * sgot;
|
||||
asection * srel;
|
||||
@ -5754,6 +6345,8 @@ const struct elf_size_info elf32_arm_size_info = {
|
||||
#endif
|
||||
#define ELF_MINPAGESIZE 0x1000
|
||||
|
||||
#define bfd_elf32_mkobject elf32_arm_mkobject
|
||||
|
||||
#define bfd_elf32_bfd_copy_private_bfd_data elf32_arm_copy_private_bfd_data
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data elf32_arm_merge_private_bfd_data
|
||||
#define bfd_elf32_bfd_set_private_flags elf32_arm_set_private_flags
|
||||
|
@ -1177,6 +1177,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_ARM_RELATIVE",
|
||||
"BFD_RELOC_ARM_GOTOFF",
|
||||
"BFD_RELOC_ARM_GOTPC",
|
||||
"BFD_RELOC_ARM_TLS_GD32",
|
||||
"BFD_RELOC_ARM_TLS_LDO32",
|
||||
"BFD_RELOC_ARM_TLS_LDM32",
|
||||
"BFD_RELOC_ARM_TLS_DTPOFF32",
|
||||
"BFD_RELOC_ARM_TLS_DTPMOD32",
|
||||
"BFD_RELOC_ARM_TLS_TPOFF32",
|
||||
"BFD_RELOC_ARM_TLS_IE32",
|
||||
"BFD_RELOC_ARM_TLS_LE32",
|
||||
"BFD_RELOC_ARM_TARGET1",
|
||||
"BFD_RELOC_ARM_ROSEGREL32",
|
||||
"BFD_RELOC_ARM_SBREL32",
|
||||
|
16
bfd/reloc.c
16
bfd/reloc.c
@ -2678,6 +2678,22 @@ ENUMX
|
||||
BFD_RELOC_ARM_GOTOFF
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_GOTPC
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_GD32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_LDO32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_LDM32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_DTPOFF32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_DTPMOD32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_TPOFF32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_IE32
|
||||
ENUMX
|
||||
BFD_RELOC_ARM_TLS_LE32
|
||||
ENUMDOC
|
||||
These relocs are only used within the ARM assembler. They are not
|
||||
(at present) written to any object files.
|
||||
|
@ -1,3 +1,12 @@
|
||||
2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
Phil Blundell <philb@gnu.org>
|
||||
|
||||
* config/tc-arm.c (arm_parse_reloc): Add TLS relocations.
|
||||
(md_apply_fix3): Mark TLS symbols.
|
||||
(tc_gen_reloc): Handle TLS relocations.
|
||||
(arm_fix_adjustable): Ignore TLS relocations.
|
||||
(s_arm_elf_cons): Support expressions after decorated symbols.
|
||||
|
||||
2005-03-29 Julian Brown <julian@codesourcery.com>
|
||||
|
||||
* config/tc-arm.c (marked_pr_dependency): New bitmap, bit N indicates
|
||||
|
@ -4881,6 +4881,11 @@ arm_parse_reloc (void)
|
||||
MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
|
||||
MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
|
||||
MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
|
||||
MAP ("(tlsgd)", BFD_RELOC_ARM_TLS_GD32),
|
||||
MAP ("(tlsldm)", BFD_RELOC_ARM_TLS_LDM32),
|
||||
MAP ("(tlsldo)", BFD_RELOC_ARM_TLS_LDO32),
|
||||
MAP ("(gottpoff)", BFD_RELOC_ARM_TLS_IE32),
|
||||
MAP ("(tpoff)", BFD_RELOC_ARM_TLS_LE32),
|
||||
{ NULL, 0, BFD_RELOC_UNUSED }
|
||||
#undef MAP
|
||||
};
|
||||
@ -12224,6 +12229,14 @@ md_apply_fix3 (fixS * fixP,
|
||||
break;
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
case BFD_RELOC_ARM_TLS_GD32:
|
||||
case BFD_RELOC_ARM_TLS_LE32:
|
||||
case BFD_RELOC_ARM_TLS_IE32:
|
||||
case BFD_RELOC_ARM_TLS_LDM32:
|
||||
case BFD_RELOC_ARM_TLS_LDO32:
|
||||
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
||||
/* fall through */
|
||||
|
||||
case BFD_RELOC_ARM_GOT32:
|
||||
case BFD_RELOC_ARM_GOTOFF:
|
||||
case BFD_RELOC_ARM_TARGET2:
|
||||
@ -12547,6 +12560,18 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
|
||||
case BFD_RELOC_ARM_SBREL32:
|
||||
case BFD_RELOC_ARM_PREL31:
|
||||
case BFD_RELOC_ARM_TARGET2:
|
||||
case BFD_RELOC_ARM_TLS_LE32:
|
||||
case BFD_RELOC_ARM_TLS_LDO32:
|
||||
code = fixp->fx_r_type;
|
||||
break;
|
||||
|
||||
case BFD_RELOC_ARM_TLS_GD32:
|
||||
case BFD_RELOC_ARM_TLS_IE32:
|
||||
case BFD_RELOC_ARM_TLS_LDM32:
|
||||
/* BFD will include the symbol's address in the addend.
|
||||
But we don't want that, so subtract it out again here. */
|
||||
if (!S_IS_COMMON (fixp->fx_addsy))
|
||||
reloc->addend -= (*reloc->sym_ptr_ptr)->value;
|
||||
code = fixp->fx_r_type;
|
||||
break;
|
||||
#endif
|
||||
@ -13843,6 +13868,11 @@ arm_fix_adjustable (fixS * fixP)
|
||||
if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_GOT32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
|
||||
return 0;
|
||||
|
||||
@ -13898,8 +13928,12 @@ s_arm_elf_cons (int nbytes)
|
||||
do
|
||||
{
|
||||
bfd_reloc_code_real_type reloc;
|
||||
char *sym_start;
|
||||
int sym_len;
|
||||
|
||||
sym_start = input_line_pointer;
|
||||
expression (& exp);
|
||||
sym_len = input_line_pointer - sym_start;
|
||||
|
||||
if (exp.X_op == O_symbol
|
||||
&& * input_line_pointer == '('
|
||||
@ -13913,9 +13947,22 @@ s_arm_elf_cons (int nbytes)
|
||||
howto->name, nbytes);
|
||||
else
|
||||
{
|
||||
char *p = frag_more ((int) nbytes);
|
||||
char *p;
|
||||
int offset = nbytes - size;
|
||||
char *saved_buf = alloca (sym_len), *saved_input;
|
||||
|
||||
/* We've parsed an expression stopping at O_symbol. But there
|
||||
may be more expression left now that we have parsed the
|
||||
relocation marker. Parse it again. */
|
||||
saved_input = input_line_pointer - sym_len;
|
||||
memcpy (saved_buf, saved_input, sym_len);
|
||||
memmove (saved_input, sym_start, sym_len);
|
||||
input_line_pointer = saved_input;
|
||||
expression (& exp);
|
||||
memcpy (saved_input, saved_buf, sym_len);
|
||||
assert (input_line_pointer >= saved_input + sym_len);
|
||||
|
||||
p = frag_more ((int) nbytes);
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
|
||||
&exp, 0, reloc);
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* gas/arm/tls.s, gas/arm/tls.d: New files.
|
||||
* gas/arm/arm.exp: Run TLS test.
|
||||
|
||||
2005-03-28 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR 803
|
||||
|
@ -72,6 +72,8 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then {
|
||||
run_dump_test "mapping"
|
||||
gas_test "bignum1.s" "" $stdoptlist "bignums"
|
||||
run_dump_test "unwind"
|
||||
|
||||
run_dump_test "tls"
|
||||
}
|
||||
|
||||
if {! [istarget arm*-*-aout] && ![istarget arm-*-pe]} then {
|
||||
|
21
gas/testsuite/gas/arm/tls.d
Normal file
21
gas/testsuite/gas/arm/tls.d
Normal file
@ -0,0 +1,21 @@
|
||||
#objdump: -dr
|
||||
#name: TLS
|
||||
|
||||
# Test generation of TLS relocations
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00+0 <main>:
|
||||
0: e1a00000 nop \(mov r0,r0\)
|
||||
4: e1a00000 nop \(mov r0,r0\)
|
||||
8: e1a0f00e mov pc, lr
|
||||
c: 00000000 andeq r0, r0, r0
|
||||
c: R_ARM_TLS_GD32 a
|
||||
10: 00000004 andeq r0, r0, r4
|
||||
10: R_ARM_TLS_LDM32 b
|
||||
14: 00000008 andeq r0, r0, r8
|
||||
14: R_ARM_TLS_IE32 c
|
||||
18: 00000000 andeq r0, r0, r0
|
||||
18: R_ARM_TLS_LE32 d
|
14
gas/testsuite/gas/arm/tls.s
Normal file
14
gas/testsuite/gas/arm/tls.s
Normal file
@ -0,0 +1,14 @@
|
||||
.text
|
||||
.globl main
|
||||
.type main, %function
|
||||
main:
|
||||
nop
|
||||
.L2:
|
||||
nop
|
||||
mov pc, lr
|
||||
|
||||
.Lpool:
|
||||
.word a(tlsgd) + (. - .L2 - 8)
|
||||
.word b(tlsldm) + (. - .L2 - 8)
|
||||
.word c(gottpoff) + (. - .L2 - 8)
|
||||
.word d(tpoff)
|
@ -1,3 +1,8 @@
|
||||
2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
Phil Blundell <philb@gnu.org>
|
||||
|
||||
* arm.h: Add TLS relocations.
|
||||
|
||||
2005-03-23 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
* dwarf.h: Merge with GCC's dwarf.h.
|
||||
|
@ -114,6 +114,9 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
|
||||
RELOC_NUMBER (R_ARM_THM_SWI8, 14)
|
||||
RELOC_NUMBER (R_ARM_XPC25, 15)
|
||||
RELOC_NUMBER (R_ARM_THM_XPC22, 16)
|
||||
RELOC_NUMBER (R_ARM_TLS_DTPMOD32, 17)
|
||||
RELOC_NUMBER (R_ARM_TLS_DTPOFF32, 18)
|
||||
RELOC_NUMBER (R_ARM_TLS_TPOFF32, 19)
|
||||
#endif /* not OLD_ARM_ABI */
|
||||
RELOC_NUMBER (R_ARM_COPY, 20) /* Copy symbol at runtime. */
|
||||
RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* Create GOT entry. */
|
||||
@ -153,7 +156,12 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
|
||||
RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101)
|
||||
RELOC_NUMBER (R_ARM_THM_PC11, 102) /* Cygnus extension to abi: Thumb unconditional branch. */
|
||||
RELOC_NUMBER (R_ARM_THM_PC9, 103) /* Cygnus extension to abi: Thumb conditional branch. */
|
||||
FAKE_RELOC (FIRST_INVALID_RELOC3, 104)
|
||||
RELOC_NUMBER (R_ARM_TLS_GD32, 104)
|
||||
RELOC_NUMBER (R_ARM_TLS_LDM32, 105)
|
||||
RELOC_NUMBER (R_ARM_TLS_LDO32, 106)
|
||||
RELOC_NUMBER (R_ARM_TLS_IE32, 107)
|
||||
RELOC_NUMBER (R_ARM_TLS_LE32, 108)
|
||||
FAKE_RELOC (FIRST_INVALID_RELOC3, 109)
|
||||
FAKE_RELOC (LAST_INVALID_RELOC3, 248)
|
||||
RELOC_NUMBER (R_ARM_RXPC25, 249)
|
||||
#endif /* not OLD_ARM_ABI */
|
||||
|
@ -1,3 +1,11 @@
|
||||
2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* ld-arm/tls-lib.s, ld-arm/tls-lib.d, ld-arm/tls-lib.r,
|
||||
ld-arm/tls-app.s, ld-arm/tls-app.d, ld-arm/tls-app.r: New files.
|
||||
* ld-arm/arm-lib.ld, ld-arm/arm-dyn.ld: Increase data segment
|
||||
alignment.
|
||||
* ld-arm/arm-elf.exp: Run TLS tests.
|
||||
|
||||
2005-03-28 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR 803
|
||||
|
@ -76,7 +76,7 @@ SECTIONS
|
||||
.gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN(256) + (. & (256 - 1));
|
||||
. = ALIGN (0x8000) - ((0x8000 - .) & (0x8000 - 1)); . = DATA_SEGMENT_ALIGN (0x8000, 0x1000);
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
|
||||
|
@ -75,6 +75,12 @@ set armelftests {
|
||||
{"arm-rel31" "-static -T arm.ld" "" {arm-rel31.s}
|
||||
{{objdump -s arm-rel31.d}}
|
||||
"arm-rel31"}
|
||||
{"TLS shared library" "-shared -T arm-lib.ld" "" {tls-lib.s}
|
||||
{{objdump -fdw tls-lib.d} {objdump -Rw tls-lib.r}}
|
||||
"tls-lib.so"}
|
||||
{"TLS dynamic application" "-T arm-dyn.ld tmpdir/tls-lib.so" "" {tls-app.s}
|
||||
{{objdump -fdw tls-app.d} {objdump -Rw tls-app.r}}
|
||||
"tls-app"}
|
||||
}
|
||||
|
||||
run_ld_link_tests $armelftests
|
||||
|
@ -75,7 +75,7 @@ SECTIONS
|
||||
.gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN(256) + (. & (256 - 1));
|
||||
. = ALIGN (0x8000) - ((0x8000 - .) & (0x8000 - 1)); . = DATA_SEGMENT_ALIGN (0x8000, 0x1000);
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) }
|
||||
|
18
ld/testsuite/ld-arm/tls-app.d
Normal file
18
ld/testsuite/ld-arm/tls-app.d
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
.*: file format elf32-.*arm
|
||||
architecture: arm, flags 0x00000112:
|
||||
EXEC_P, HAS_SYMS, D_PAGED
|
||||
start address 0x00008274
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00008274 <foo>:
|
||||
8274: e1a00000 nop \(mov r0,r0\)
|
||||
8278: e1a00000 nop \(mov r0,r0\)
|
||||
827c: e1a0f00e mov pc, lr
|
||||
8280: 000080bc streqh r8, \[r0\], -ip
|
||||
8284: 000080b4 streqh r8, \[r0\], -r4
|
||||
8288: 000080ac andeq r8, r0, ip, lsr #1
|
||||
828c: 00000004 andeq r0, r0, r4
|
||||
8290: 000080c4 andeq r8, r0, r4, asr #1
|
||||
8294: 00000014 andeq r0, r0, r4, lsl r0
|
12
ld/testsuite/ld-arm/tls-app.r
Normal file
12
ld/testsuite/ld-arm/tls-app.r
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
.*: file format elf32-.*arm
|
||||
|
||||
DYNAMIC RELOCATION RECORDS
|
||||
OFFSET TYPE VALUE
|
||||
00010334 R_ARM_TLS_DTPMOD32 app_gd
|
||||
00010338 R_ARM_TLS_DTPOFF32 app_gd
|
||||
0001033c R_ARM_TLS_DTPMOD32 lib_gd
|
||||
00010340 R_ARM_TLS_DTPOFF32 lib_gd
|
||||
00010344 R_ARM_TLS_TPOFF32 app_ie
|
||||
|
||||
|
34
ld/testsuite/ld-arm/tls-app.s
Normal file
34
ld/testsuite/ld-arm/tls-app.s
Normal file
@ -0,0 +1,34 @@
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, %function
|
||||
foo:
|
||||
nop
|
||||
.L2:
|
||||
nop
|
||||
mov pc, lr
|
||||
|
||||
.Lpool:
|
||||
.word lib_gd(tlsgd) + (. - .L2 - 8)
|
||||
.word app_gd(tlsgd) + (. - .L2 - 8)
|
||||
.word app_ld(tlsldm) + (. - .L2 - 8)
|
||||
.word app_ld(tlsldo)
|
||||
.word app_ie(gottpoff) + (. - .L2 - 8)
|
||||
.word app_le(tpoff)
|
||||
|
||||
.section .tdata,"awT"
|
||||
.global app_gd
|
||||
app_gd:
|
||||
.space 4
|
||||
|
||||
.global app_ld
|
||||
app_ld:
|
||||
.space 4
|
||||
|
||||
.section .tbss,"awT",%nobits
|
||||
.global app_ie
|
||||
app_ie:
|
||||
.space 4
|
||||
|
||||
.global app_le
|
||||
app_le:
|
||||
.space 4
|
15
ld/testsuite/ld-arm/tls-lib.d
Normal file
15
ld/testsuite/ld-arm/tls-lib.d
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
.*: file format elf32-.*arm
|
||||
architecture: arm, flags 0x00000150:
|
||||
HAS_SYMS, DYNAMIC, D_PAGED
|
||||
start address 0x.*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00000328 <foo>:
|
||||
328: e1a00000 nop \(mov r0,r0\)
|
||||
32c: e1a00000 nop \(mov r0,r0\)
|
||||
330: e1a0f00e mov pc, lr
|
||||
334: 00008098 muleq r0, r8, r0
|
||||
338: 0000808c andeq r8, r0, ip, lsl #1
|
||||
33c: 00000004 andeq r0, r0, r4
|
10
ld/testsuite/ld-arm/tls-lib.r
Normal file
10
ld/testsuite/ld-arm/tls-lib.r
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.*: file format elf32-.*arm
|
||||
|
||||
DYNAMIC RELOCATION RECORDS
|
||||
OFFSET TYPE VALUE
|
||||
000083c4 R_ARM_TLS_DTPMOD32 \*ABS\*
|
||||
000083cc R_ARM_TLS_DTPMOD32 lib_gd
|
||||
000083d0 R_ARM_TLS_DTPOFF32 lib_gd
|
||||
|
||||
|
22
ld/testsuite/ld-arm/tls-lib.s
Normal file
22
ld/testsuite/ld-arm/tls-lib.s
Normal file
@ -0,0 +1,22 @@
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, %function
|
||||
foo:
|
||||
nop
|
||||
.L2:
|
||||
nop
|
||||
mov pc, lr
|
||||
|
||||
.Lpool:
|
||||
.word lib_gd(tlsgd) + (. - .L2 - 8)
|
||||
.word lib_ld(tlsldm) + (. - .L2 - 8)
|
||||
.word lib_ld(tlsldo)
|
||||
|
||||
.section .tdata,"awT"
|
||||
.global lib_gd
|
||||
lib_gd:
|
||||
.space 4
|
||||
|
||||
.global lib_ld
|
||||
lib_ld:
|
||||
.space 4
|
Loading…
x
Reference in New Issue
Block a user