* [PATCH] Support for Thread Local Storage Descriptors in ARM platform
@ 2006-08-15 1:48 Glauber de Oliveira Costa
2006-08-15 11:48 ` Richard Earnshaw
0 siblings, 1 reply; 3+ messages in thread
From: Glauber de Oliveira Costa @ 2006-08-15 1:48 UTC (permalink / raw)
To: binutils, Richard Earnshaw, Alexandre Oliva, aldenor
[-- Attachment #1: Type: text/plain, Size: 894 bytes --]
Hello All,
Troughout the last months, Alexandre Oliva and I developed an ABI
extension to allow ARM binaries to benefit from his newly devised TLS
Descriptor method for accessing TLS variables
(http://www.lsd.ic.unicamp.br/~aoliva/writeups/TLS/paper-gcc2006.pdf).
Our proposed ABI can be found at
http://www.lsd.ic.unicamp.br/~aoliva/writeups/TLS/RFC-TLSDESC-ARM.txt
, and a paper describing the ARM implementation, to be presented at
Linux Kongress in the first week of September at
http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/paper-lk2006.pdf. We
there describes some results we've got, that indicates a speedup of
more than 2 times for the most common case.
Attached to this message, follows the GNU linker and assembler part of
the work. Please, feel free to send me feedbacks on the
implementation, and consider it for merging.
--
"Free as in Freedom"
Glauber de Oliveira Costa.
[-- Attachment #2: patch-binutils-final --]
[-- Type: application/octet-stream, Size: 62963 bytes --]
Index: bfd/ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.3588
diff -u -p -r1.3588 ChangeLog
--- bfd/ChangeLog 14 Aug 2006 12:19:20 -0000 1.3588
+++ bfd/ChangeLog 14 Aug 2006 21:16:39 -0000
@@ -1,3 +1,48 @@
+2006-08-14 Glauber de Oliveira Costa <glommer@gmail.com>
+
+ * Added support for gnu extensions for TLS handling
+ * bfd-in2.h (BFD_RELOC_ARM_TLS_GOTDESC): Added new relocation.
+ (BFD_RELOC_ARM_TLS_CALL): Likewise.
+ (BFD_RELOC_ARM_TLS_DESCSEQ): Likewise.
+ (BFD_RELOC_ARM_TLS_DESC): Likewise.
+ * libbfd.h : Likewise.
+ * reloc.c : Likewise.
+ * elf32-arm.c: (elf32_arm_howto_table_1): Added howto for new relocations.
+ (elf32_arm_reloc_map): Added mappings for new relocations.
+ (tls_trampoline): Added.
+ (dl_tlsdesc_lazy_trampoline): Likewise.
+ (elf32_arm_obj_tdata): Added local_tlsdesc_gotent, which is accessed
+ trough ...
+ (elf32_arm_local_tlsdesc_gotent): New macro added.
+ (GOT_TLS_DESC): New definition.
+ (GOT_TLS_GD_ANY_P): New macro, checks for one of GD TLS models.
+ (elf32_arm_link_hash_entry): Added tlsdesc_got.
+ (elf32_arm_compute_jump_table_size): New macro.
+ (elf32_arm_link_hash_table): Added next_tls_desc_index,
+ num_tls_desc, dt_tlsdesc_plt, dt_tlsdesc_got , tls_trampoline and
+ sgotplt_jump_table_size.
+ (elf32_arm_link_hash_newfunc): New initializations.
+ (elf32_arm_link_hash_table_create): Likewise.
+ (elf32_arm_tls_transition): New function. Checks relaxation
+ possibilites.
+ (elf32_arm_tls_relax): New function. Performs steps necessaries for
+ relaxing a TLS code sequence.
+ (elf32_arm_final_link_relocate): Deploy dynamic relocation for the TLS
+ gnu extensions. Generate R_ARM_TLS_DESC, adjust addend for
+ R_ARM_TLS_CALL, and fix addend for R_ARM_TLS_GOTDESC.
+ (IS_ARM_TLS_RELOC): Add new relocations to check.
+ (IS_ARM_TLS_GNU_RELOC): New check.
+ (elf32_arm_relocate_section): Try to relax the code sequence, and call
+ elf32_arm_final_link_relocate only if there is still work to be done.
+ (elf32_arm_check_relocs): Settle up needed steps for new relocations
+ placement and handling.
+ (allocate_dynrelocs): Find a place for R_ARM_TLS_DESC.
+ (elf32_arm_size_dynamic_sections): Likewise. Also creates the lazy
+ trampoline whenever needed.
+ (elf32_arm_always_size_sections): Create entry for _TLS_MODULE_BASE_
+ (elf32_arm_finish_dynamic_symbol): Fill the contents of dynamic table
+ entries and sets up .plt entries for the trampolines.
+
2006-08-14 Thiemo Seufer <ths@mips.com>
* elfxx-mips.c (_bfd_mips_elf_symbol_processing,
Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.397
diff -u -p -r1.397 bfd-in2.h
--- bfd/bfd-in2.h 19 Jul 2006 01:50:23 -0000 1.397
+++ bfd/bfd-in2.h 14 Aug 2006 21:16:55 -0000
@@ -2936,6 +2936,10 @@ pc-relative or some form of GOT-indirect
BFD_RELOC_ARM_TLS_TPOFF32,
BFD_RELOC_ARM_TLS_IE32,
BFD_RELOC_ARM_TLS_LE32,
+ BFD_RELOC_ARM_TLS_GOTDESC,
+ BFD_RELOC_ARM_TLS_CALL,
+ BFD_RELOC_ARM_TLS_DESCSEQ,
+ BFD_RELOC_ARM_TLS_DESC,
/* ARM group relocations. */
BFD_RELOC_ARM_ALU_PC_G0_NC,
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.83
diff -u -p -r1.83 elf32-arm.c
--- bfd/elf32-arm.c 23 Jun 2006 02:58:00 -0000 1.83
+++ bfd/elf32-arm.c 14 Aug 2006 21:17:52 -0000
@@ -1351,10 +1351,61 @@ static reloc_howto_type elf32_arm_howto_
0x040f70ff, /* dst_mask */
FALSE), /* pcrel_offset */
- EMPTY_HOWTO (90), /* unallocated */
- EMPTY_HOWTO (91),
- EMPTY_HOWTO (92),
- EMPTY_HOWTO (93),
+ HOWTO (R_ARM_TLS_GOTDESC, /* 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_GOTDESC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_CALL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_DESCSEQ, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_DESCSEQ", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_DESC, /* 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_DESC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
HOWTO (R_ARM_PLT32_ABS, /* type */
0, /* rightshift */
@@ -1728,6 +1779,10 @@ static const struct elf32_arm_reloc_map
{BFD_RELOC_ARM_PREL31, R_ARM_PREL31},
{BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2},
{BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
+ {BFD_RELOC_ARM_TLS_GOTDESC, R_ARM_TLS_GOTDESC},
+ {BFD_RELOC_ARM_TLS_CALL, R_ARM_TLS_CALL},
+ {BFD_RELOC_ARM_TLS_DESCSEQ, R_ARM_TLS_DESCSEQ},
+ {BFD_RELOC_ARM_TLS_DESC, R_ARM_TLS_DESC},
{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},
@@ -1880,6 +1935,25 @@ typedef unsigned short int insn16;
section. */
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+static const unsigned long tls_trampoline [] =
+ {
+ 0xe08e0000, /* add r0, lr, r0 */
+ 0xe5901004, /* ldr r1, [r0,#4] */
+ 0xe12fff11, /* bx r1 */
+ };
+
+static const unsigned long dl_tlsdesc_lazy_trampoline [] =
+ {
+ 0xe92d0004, /* stmdb sp!, {r2} */
+ 0xe59f200c, /* ldr r2, [pc, #.Lt0 - . - 8] */
+ 0xe59f100c, /* ldr r1, [pc, #.Lt1 - . - 8] */
+ 0xe79f2002, /* .L0: ldr r2, [pc, r2]*/
+ 0xe08f1001, /* .L1: add r1, pc, r1 */
+ 0xe12fff12, /* bx r2 */
+ 0x00000000, /* .Lt0: .word _GLOBAL_OFFSET_TABLE_ - .L0 - 8 +
+ dl_tlsdesc_lazy_resolver(GOT) */
+ 0x00000000, /* .Lt1: .word _GLOBAL_OFFSET_TABLE_ - .L1 - 8 */
+ };
#ifdef FOUR_WORD_PLT
/* The first entry in a procedure linkage table looks like
@@ -2025,6 +2099,9 @@ struct elf32_arm_obj_tdata
/* tls_type for each local got entry. */
char *local_got_tls_type;
+ /* GOTPLT entries for TLS descriptors. */
+ bfd_vma *local_tlsdesc_gotent;
+
aeabi_attribute known_eabi_attributes[NUM_KNOWN_ATTRIBUTES];
aeabi_attribute_list *other_eabi_attributes;
};
@@ -2035,6 +2112,9 @@ struct elf32_arm_obj_tdata
#define elf32_arm_local_got_tls_type(abfd) \
(elf32_arm_tdata (abfd)->local_got_tls_type)
+#define elf32_arm_local_tlsdesc_gotent(abfd) \
+ (elf32_arm_tdata (abfd)->local_tlsdesc_gotent)
+
static bfd_boolean
elf32_arm_mkobject (bfd *abfd)
{
@@ -2091,7 +2171,14 @@ struct elf32_arm_link_hash_entry
#define GOT_NORMAL 1
#define GOT_TLS_GD 2
#define GOT_TLS_IE 4
+#define GOT_TLS_GDESC 8
+#define GOT_TLS_GD_ANY_P(type) \
+ ((type & GOT_TLS_GD) || (type & GOT_TLS_GDESC))
unsigned char tls_type;
+
+ /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+ starting at the end of the jump table. */
+ bfd_vma tlsdesc_got;
};
/* Traverse an arm ELF linker hash table. */
@@ -2105,6 +2192,9 @@ struct elf32_arm_link_hash_entry
#define elf32_arm_hash_table(info) \
((struct elf32_arm_link_hash_table *) ((info)->hash))
+#define elf32_arm_compute_jump_table_size(htab) \
+ ((htab)->next_tls_desc_index * 4)
+
/* ARM ELF linker hash table. */
struct elf32_arm_link_hash_table
{
@@ -2151,6 +2241,12 @@ struct elf32_arm_link_hash_table
/* True if the target uses REL relocations. */
int use_rel;
+ /* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt. */
+ bfd_vma next_tls_desc_index;
+
+ /* How many R_ARM_TLS_DESC relocations were generated so far */
+ bfd_vma num_tls_desc;
+
/* Short-cuts to get to dynamic linker sections. */
asection *sgot;
asection *sgotplt;
@@ -2163,6 +2259,19 @@ struct elf32_arm_link_hash_table
/* The (unloaded but important) VxWorks .rela.plt.unloaded section. */
asection *srelplt2;
+ /* The offset into splt of the PLT entry for the TLS descriptor
+ * resolver. Special values are 0, if not necessary (or not found
+ * to be necessary yet), and -1 if needed but not determined
+ * yet. */
+ bfd_vma dt_tlsdesc_plt;
+
+ /* The offset into sgot of the GOT entry used by the PLT entry
+ * above. */
+ bfd_vma dt_tlsdesc_got;
+
+ /* Offset in .plt section of tls_trampoline */
+ bfd_vma tls_trampoline;
+
/* Data for R_ARM_TLS_LDM32 relocations. */
union {
bfd_signed_vma refcount;
@@ -2174,6 +2283,10 @@ struct elf32_arm_link_hash_table
/* For convenience in allocate_dynrelocs. */
bfd * obfd;
+
+ /* The amount of space used by the reserved portion of the sgotplt
+ * section, plus whatever space is used by the jump slots. */
+ bfd_vma sgotplt_jump_table_size;
};
/* Create an entry in an ARM ELF linker hash table. */
@@ -2201,6 +2314,7 @@ elf32_arm_link_hash_newfunc (struct bfd_
{
ret->relocs_copied = NULL;
ret->tls_type = GOT_UNKNOWN;
+ ret->tlsdesc_got = (bfd_vma) -1;
ret->plt_thumb_refcount = 0;
ret->plt_got_offset = -1;
}
@@ -2393,6 +2507,11 @@ elf32_arm_link_hash_table_create (bfd *a
ret->sdynbss = NULL;
ret->srelbss = NULL;
ret->srelplt2 = NULL;
+ ret->dt_tlsdesc_plt = 0;
+ ret->dt_tlsdesc_got = 0;
+ ret->tls_trampoline = 0;
+ ret->next_tls_desc_index = 0;
+ ret->num_tls_desc = 0;
ret->thumb_glue_size = 0;
ret->arm_glue_size = 0;
ret->bfd_of_glue_owner = NULL;
@@ -3323,6 +3442,31 @@ arm_real_reloc_type (struct elf32_arm_li
return r_type;
}
}
+/* Checks wether it's possible to change to a more efficient access
+ * model, given the information we have about the current link */
+static int
+elf32_arm_tls_transition (struct bfd_link_info *info, int r_type,
+ struct elf_link_hash_entry *h)
+{
+ int is_local = (h == NULL);
+
+ if ((h && (h->root.type == bfd_link_hash_undefweak))
+ || info->shared)
+ return r_type;
+
+ /* We do not support relaxations for Old TLS models */
+ switch (r_type)
+ {
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_CALL:
+ case R_ARM_TLS_DESCSEQ:
+ if (is_local)
+ return R_ARM_TLS_LE32;
+ return R_ARM_TLS_IE32;
+ }
+
+ return r_type;
+}
/* Return the base VMA address which should be subtracted from real addresses
when resolving @dtpoff relocation.
@@ -3367,6 +3511,111 @@ elf32_arm_abs12_reloc (bfd *abfd, void *
return bfd_reloc_ok;
}
+/* Function that handles TLS relaxations. Relaxing is possible for symbols
+ * that uses R_ARM_GOTDESC, R_ARM_TLS_CALL and R_ARM_TLS_DESCSEQ relocations,
+ * during a static link.
+ *
+ * The status parameter receives TRUE if no more work needs to be done or
+ * an error happened and FALSE if after exiting it's still desirable to call
+ * final_link_relocate. */
+static bfd_reloc_status_type
+elf32_arm_tls_relax ( bfd_byte * contents,
+ bfd * input_bfd,
+ Elf_Internal_Rela * rel,
+ unsigned long is_local,
+ bfd_boolean * status)
+
+ {
+ unsigned long insn;
+ unsigned long op;
+
+ *status = TRUE;
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_ARM_TLS_GOTDESC:
+ /* No addend adjustments for local exec relaxation */
+ if (!is_local)
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ BFD_ASSERT (insn - 8 < insn);
+
+ bfd_put_32 (input_bfd, insn - 8,contents + rel->r_offset);
+ }
+ *status = FALSE;
+ break;
+ case R_ARM_TLS_DESCSEQ:
+ if (is_local)
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ op = insn >> (32 - 8);
+ switch (op)
+ {
+ case 0xe0: /* add */
+ /* mov rx,rt */
+ bfd_put_32 (input_bfd, 0xe1a00000 | (0x0000ffff & insn),
+ contents + rel->r_offset);
+ break;
+ case 0xe1: /* blx */
+ case 0xe5: /* ldr */
+ /* mov r0,r0 */
+ bfd_put_32 (input_bfd, 0xe1a00000, contents + rel->r_offset);
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("Unexpected instruction in TLS trampoline '0x%x'."),
+ insn);
+ return bfd_reloc_notsupported;
+ }
+
+ }
+ else
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ op = insn >> (32 - 8);
+ switch (op)
+ {
+ case 0xe0: /* add */
+ /* keep it */
+ break;
+ case 0xe5: /* ldr */
+ /* get rid of #4, in case it's there */
+ BFD_ASSERT ((insn & 0xff) == 0x4);
+ bfd_put_32 (input_bfd, (insn & 0xffffff00), contents +
+ rel->r_offset);
+ break;
+ case 0xe1: /* blx */
+ /* mov */
+ insn &= 0xf;
+ insn |= 0xe1a00000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("Unexpected instruction in TLS trampoline '0x%x'."),
+ insn);
+ return bfd_reloc_notsupported;
+ }
+ }
+ break;
+ case R_ARM_TLS_CALL:
+ if (is_local)
+ {
+ /* mov r0,r0 */
+ bfd_put_32 (input_bfd, 0xe1a00000, contents + rel->r_offset);
+ }
+ else
+ {
+ /* GD->IE relaxation
+ * turn the instruction into a ldr one
+ * ldr r0, [pc,r0] */
+ bfd_put_32 (input_bfd, 0xe79f0000, contents + rel->r_offset);
+ }
+ break;
+ }
+ return bfd_reloc_ok;
+ }
+
/* For a given value of n, calculate the value of G_n as required to
deal with group relocations. We return it in the form of an
encoded constant-and-rotation, together with the final residual. If n is
@@ -3459,6 +3708,7 @@ elf32_arm_final_link_relocate (reloc_how
Elf_Internal_Shdr * symtab_hdr;
struct elf_link_hash_entry ** sym_hashes;
bfd_vma * local_got_offsets;
+ bfd_vma * local_tlsdesc_gotents;
asection * sgot = NULL;
asection * splt = NULL;
asection * sreloc = NULL;
@@ -3471,6 +3721,11 @@ elf32_arm_final_link_relocate (reloc_how
/* Some relocation type map to different relocations depending on the
target. We pick the right one here. */
r_type = arm_real_reloc_type (globals, r_type);
+
+ /* Besides that, it is possible to have linker relaxations on some
+ * TLS acces models. Update our information here */
+ r_type = elf32_arm_tls_transition (info, r_type, h);
+
if (r_type != howto->type)
howto = elf32_arm_howto_from_type (r_type);
@@ -3495,6 +3750,8 @@ elf32_arm_final_link_relocate (reloc_how
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
local_got_offsets = elf_local_got_offsets (input_bfd);
+ local_tlsdesc_gotents = elf32_arm_local_tlsdesc_gotent (input_bfd);
+
r_symndx = ELF32_R_SYM (rel->r_info);
if (globals->use_rel)
@@ -4398,10 +4655,13 @@ elf32_arm_final_link_relocate (reloc_how
rel->r_addend);
}
+ case R_ARM_TLS_CALL:
case R_ARM_TLS_GD32:
case R_ARM_TLS_IE32:
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_DESCSEQ:
{
- bfd_vma off;
+ bfd_vma off,offplt;
int indx;
char tls_type;
@@ -4421,6 +4681,7 @@ elf32_arm_final_link_relocate (reloc_how
indx = h->dynindx;
}
off = h->got.offset;
+ offplt = elf32_arm_hash_entry (h)->tlsdesc_got;
tls_type = ((struct elf32_arm_link_hash_entry *) h)->tls_type;
}
else
@@ -4428,9 +4689,16 @@ elf32_arm_final_link_relocate (reloc_how
if (local_got_offsets == NULL)
abort ();
off = local_got_offsets[r_symndx];
+ offplt = local_tlsdesc_gotents[r_symndx];
tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
}
+ /* linker relaxations happens from one of the
+ * R_ARM_{GOTDESC,CALL,DESCSEQ} relocations to IE or LE */
+ if (ELF32_R_TYPE(rel->r_info) != r_type){
+ tls_type = GOT_TLS_IE;
+ }
+
if (tls_type == GOT_UNKNOWN)
abort ();
@@ -4455,10 +4723,57 @@ elf32_arm_final_link_relocate (reloc_how
need_relocs = TRUE;
if (globals->srelgot == NULL)
abort ();
- loc = globals->srelgot->contents;
- loc += globals->srelgot->reloc_count * RELOC_SIZE (globals);
}
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ /* We should have relaxed, unless we're talking about an
+ * undefined weak symbol */
+ BFD_ASSERT (info->shared ||
+ (h && (h->root.type == bfd_link_hash_undefweak)));
+
+ bfd_vma param;
+
+ BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8
+ <= globals->sgotplt->size);
+
+ outrel.r_addend = 0;
+ outrel.r_offset = ( globals->sgotplt->output_section->vma
+ + globals->sgotplt->output_offset
+ + offplt
+ + globals->sgotplt_jump_table_size);
+
+ outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DESC);
+ sreloc = globals->srelplt;
+ loc = sreloc->contents;
+ loc += (globals->next_tls_desc_index++
+ * RELOC_SIZE(globals)) ;
+ BFD_ASSERT(loc + RELOC_SIZE (globals)
+ <= sreloc->contents + sreloc->size);
+
+
+ SWAP_RELOC_OUT(globals) (output_bfd,&outrel,loc);
+
+ /* With lazy relocations on, there's still work to do,
+ * and we store the relocation index in the first
+ * parameter, to allow it to be done. Otherwise, store 0 */
+ if ((info->flags & DF_BIND_NOW))
+ param = 0;
+ else
+ param = ELF32_R_SYM (outrel.r_info);
+
+ /* First word in the relocation gets the relocation index,
+ * or zero, if we're not allowing lazy relocs */
+ bfd_put_32 (output_bfd, param,
+ globals->sgotplt->contents + offplt +
+ globals->sgotplt_jump_table_size);
+
+ /* Second word in the relocation is always zero */
+ bfd_put_32 (output_bfd, 0,
+ globals->sgotplt->contents + offplt +
+ globals->sgotplt_jump_table_size + 4);
+
+ }
if (tls_type & GOT_TLS_GD)
{
if (need_relocs)
@@ -4472,10 +4787,10 @@ elf32_arm_final_link_relocate (reloc_how
if (globals->use_rel)
bfd_put_32 (output_bfd, outrel.r_addend,
globals->sgot->contents + cur_off);
+ loc = globals->srelgot->contents;
+ loc += (globals->srelgot->reloc_count++ * RELOC_SIZE (globals));
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- globals->srelgot->reloc_count++;
- loc += RELOC_SIZE (globals);
if (indx == 0)
bfd_put_32 (output_bfd, value - dtpoff_base (info),
@@ -4491,10 +4806,10 @@ elf32_arm_final_link_relocate (reloc_how
bfd_put_32 (output_bfd, outrel.r_addend,
globals->sgot->contents + cur_off + 4);
+ loc = globals->srelgot->contents;
+ loc += (globals->srelgot->reloc_count++ * RELOC_SIZE (globals));
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- globals->srelgot->reloc_count++;
- loc += RELOC_SIZE (globals);
}
}
else
@@ -4530,9 +4845,10 @@ elf32_arm_final_link_relocate (reloc_how
bfd_put_32 (output_bfd, outrel.r_addend,
globals->sgot->contents + cur_off);
+ loc = globals->srelgot->contents;
+ loc += (globals->srelgot->reloc_count++ * RELOC_SIZE (globals));
+
SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- globals->srelgot->reloc_count++;
- loc += RELOC_SIZE (globals);
}
else
bfd_put_32 (output_bfd, tpoff (info, value),
@@ -4548,9 +4864,63 @@ elf32_arm_final_link_relocate (reloc_how
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);
+ else if (tls_type & GOT_TLS_GDESC )
+ off = offplt;
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL)
+ {
+ long inst;
+
+ inst = (globals->splt->output_section->vma +
+ globals->splt->output_offset + globals->tls_trampoline) -
+ (input_section->output_section->vma +
+ input_section->output_offset + rel->r_offset) - 8;
+
+
+ /* Make sure we're not throwing any useful data away */
+ BFD_ASSERT ((inst & 3) == 0);
+ inst >>= 2;
+ /* The offset have to fit in a howto->bitsize sized field. Otherwise, we
+ * may be computing a branch to the wrong place. We then refuse t
+ * relocate */
+ BFD_ASSERT (inst < (1 << howto->bitsize));
+ BFD_ASSERT (inst > -(1 << howto->bitsize));
+
+ inst &= ((1 << howto->bitsize) - 1);
+ inst |= 0xeb000000; /* branch & link */
+
+ value = inst;
+ }
+ /* These relocations needs special care, as besides the fact they
+ * point somewhere in .gotplt, the addend must be adjusted accordingly
+ * depending on the type of instruction we refer to */
+ else if ((r_type == R_ARM_TLS_GOTDESC) && (tls_type & GOT_TLS_GDESC))
+ {
+ unsigned long data,insn;
+ data = bfd_get_32 (input_bfd, hit_data);
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset - data);
+ insn >>= 32 - 8;
+
+ if (insn == 0xeb) /* branch */
+ value = -4;
+ else /* add */
+ {
+ BFD_ASSERT (insn == 0xe0);
+ value = -8;
+ }
+
+ value += globals->sgotplt->output_section->vma +
+ globals->sgotplt->output_offset + off -
+ (input_section->output_section->vma +
+ input_section->output_offset +
+ rel->r_offset) +
+ globals->sgotplt_jump_table_size;
+ }
+
+ else
+ 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,
rel->r_addend);
@@ -4567,7 +4937,7 @@ elf32_arm_final_link_relocate (reloc_how
}
else
value = tpoff (info, value);
-
+
return _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset, value,
rel->r_addend);
@@ -5323,8 +5693,17 @@ arm_add_to_rel (bfd * abfd,
|| (R_TYPE) == R_ARM_TLS_DTPMOD32 \
|| (R_TYPE) == R_ARM_TLS_TPOFF32 \
|| (R_TYPE) == R_ARM_TLS_LE32 \
+ || (R_TYPE) == R_ARM_TLS_GOTDESC \
+ || (R_TYPE) == R_ARM_TLS_CALL \
+ || (R_TYPE) == R_ARM_TLS_DESCSEQ \
|| (R_TYPE) == R_ARM_TLS_IE32)
+/* Specific set of relocations for the gnu tls dialect */
+#define IS_ARM_TLS_GNU_RELOC(R_TYPE) \
+ ((R_TYPE) == R_ARM_TLS_GOTDESC \
+ || (R_TYPE) == R_ARM_TLS_CALL \
+ || (R_TYPE) == R_ARM_TLS_DESCSEQ)
+
/* Relocate an ARM ELF section. */
static bfd_boolean
elf32_arm_relocate_section (bfd * output_bfd,
@@ -5365,6 +5744,8 @@ elf32_arm_relocate_section (bfd *
arelent bfd_reloc;
char sym_type;
bfd_boolean unresolved_reloc = FALSE;
+ bfd_boolean tls_relaxed = FALSE;
+ int tls_type = 0;
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
@@ -5466,7 +5847,10 @@ elf32_arm_relocate_section (bfd *
}
if (h != NULL)
- name = h->root.root.string;
+ {
+ name = h->root.root.string;
+ tls_type = elf32_arm_hash_entry (h)->tls_type;
+ }
else
{
name = (bfd_elf_string_from_elf_section
@@ -5493,14 +5877,24 @@ elf32_arm_relocate_section (bfd *
name);
}
- r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
- input_section, contents, rel,
- relocation, info, sec, name,
- (h ? ELF_ST_TYPE (h->type) :
- ELF_ST_TYPE (sym->st_info)), h,
- &unresolved_reloc);
-
- /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ /* We call elf32_arm_final_link_relocate unless we're completely
+ * done, i.e., the relaxation produced the final output we want,
+ * and we won't let anybody mess with it. Also, we have to do
+ * addend adjustments in case of a R_ARM_TLS_GOTDESC relocation
+ * both in relaxed and non-relaxed cases */
+ if ((elf32_arm_tls_transition (info, r_type, h) != r_type) ||
+ (IS_ARM_TLS_GNU_RELOC (r_type) && !(tls_type & GOT_TLS_GDESC)))
+ r = elf32_arm_tls_relax (contents, input_bfd, rel, h == NULL,
+ &tls_relaxed);
+
+ if (tls_relaxed == FALSE)
+ r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel,
+ relocation, info, sec, name,
+ (h ? ELF_ST_TYPE (h->type) :
+ ELF_ST_TYPE (sym->st_info)), h,
+ &unresolved_reloc);
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
because such sections are not SEC_ALLOC and thus ld.so will
not process them. */
if (unresolved_reloc
@@ -6744,12 +7138,17 @@ elf32_arm_check_relocs (bfd *abfd, struc
eh = (struct elf32_arm_link_hash_entry *) h;
+ /* Could be done earlier, if h were already available */
+ r_type = elf32_arm_tls_transition(info, r_type, h);
switch (r_type)
{
case R_ARM_GOT32:
case R_ARM_GOT_PREL:
case R_ARM_TLS_GD32:
case R_ARM_TLS_IE32:
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_DESCSEQ:
+ case R_ARM_TLS_CALL:
/* This symbol requires a global offset table entry. */
{
int tls_type, old_tls_type;
@@ -6758,6 +7157,10 @@ elf32_arm_check_relocs (bfd *abfd, struc
{
case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_CALL:
+ case R_ARM_TLS_DESCSEQ:
+ tls_type = GOT_TLS_GDESC; break;
default: tls_type = GOT_NORMAL; break;
}
@@ -6777,25 +7180,38 @@ elf32_arm_check_relocs (bfd *abfd, struc
bfd_size_type size;
size = symtab_hdr->sh_info;
- size *= (sizeof (bfd_signed_vma) + sizeof(char));
+ size *= (sizeof (bfd_signed_vma) +
+ sizeof (bfd_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_tlsdesc_gotent (abfd)
+ = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
elf32_arm_local_got_tls_type (abfd)
- = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+ = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
}
local_got_refcounts[r_symndx] += 1;
old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
}
+ /* If a variable is accessed in both tld methods,
+ * two slots may be created */
+ if (GOT_TLS_GD_ANY_P (old_tls_type) && GOT_TLS_GD_ANY_P (tls_type))
+ tls_type |= old_tls_type;
+
/* 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. */
+ TLS / non-TLS mismatch, based on the symbol type. 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 the symbol is accessed in both IE and GDESC method, we're
+ * able to relax. Turn off the GDESC flag, without messing up with
+ * any other kind of tls types that may be involved */
+ if ((tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_GDESC))
+ tls_type &= ~GOT_TLS_GDESC;
if (old_tls_type != tls_type)
{
@@ -7361,12 +7777,13 @@ allocate_dynrelocs (struct elf_link_hash
{
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
- eh->plt_got_offset = htab->sgotplt->size;
+ eh->plt_got_offset = htab->sgotplt->size - 8* htab->num_tls_desc;
htab->sgotplt->size += 4;
}
/* We also need to make an entry in the .rel(a).plt section. */
htab->srelplt->size += RELOC_SIZE (htab);
+ htab->next_tls_desc_index++;
/* VxWorks executables have a second set of relocations for
each PLT entry. They go in a separate relocation section,
@@ -7396,6 +7813,9 @@ allocate_dynrelocs (struct elf_link_hash
h->needs_plt = 0;
}
+ eh = (struct elf32_arm_link_hash_entry *) h;
+ eh->tlsdesc_got = (bfd_vma) -1;
+
if (h->got.refcount > 0)
{
asection *s;
@@ -7425,8 +7845,21 @@ allocate_dynrelocs (struct elf_link_hash
s->size += 4;
else
{
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ /* R_ARM_TLS_DESC needs 2 GOT slots. */
+ eh->tlsdesc_got = htab->sgotplt->size
+ - elf32_arm_compute_jump_table_size (htab);
+ htab->sgotplt->size += 8;
+ h->got.offset = (bfd_vma) -2;
+ /* plt_got_offset needs to know there's a TLS_DESC reloc
+ * in the middle of .got.plt */
+ htab->num_tls_desc++;
+ }
if (tls_type & GOT_TLS_GD)
- /* R_ARM_TLS_GD32 needs 2 consecutive GOT slots. */
+ /* R_ARM_TLS_GD32 needs 2 consecutive GOT slots.
+ * If the symbol is both GD and GDESC, got.offset may have
+ * been overwritten */
s->size += 8;
if (tls_type & GOT_TLS_IE)
/* R_ARM_TLS_IE32 needs one GOT slot. */
@@ -7452,8 +7885,26 @@ allocate_dynrelocs (struct elf_link_hash
if (tls_type & GOT_TLS_GD)
htab->srelgot->size += RELOC_SIZE (htab);
- if ((tls_type & GOT_TLS_GD) && indx != 0)
- htab->srelgot->size += RELOC_SIZE (htab);
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ htab->dt_tlsdesc_plt = (bfd_vma)-1;
+ htab->srelplt->size += RELOC_SIZE (htab);
+ /* GDESC needs a trampoline to jump to. Allocate it if not
+ * yet done */
+ if (htab->tls_trampoline == 0)
+ {
+ if (htab->splt->size == 0)
+ htab->splt->size += htab->plt_header_size;
+
+ htab->tls_trampoline = htab->splt->size;
+ htab->splt->size += htab->plt_entry_size;
+
+ }
+ }
+
+ /* Only GD need it. GDESC just emits one relocation per 2 entries */
+ if ((tls_type & GOT_TLS_GD) && indx != 0)
+ htab->srelgot->size += RELOC_SIZE (htab);
}
else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
@@ -7635,6 +8086,7 @@ elf32_arm_size_dynamic_sections (bfd * o
bfd_signed_vma *local_got;
bfd_signed_vma *end_local_got;
char *local_tls_type;
+ bfd_vma *local_tlsdesc_gotent;
bfd_size_type locsymcount;
Elf_Internal_Shdr *symtab_hdr;
asection *srel;
@@ -7674,23 +8126,46 @@ elf32_arm_size_dynamic_sections (bfd * o
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
local_tls_type = elf32_arm_local_got_tls_type (ibfd);
+ local_tlsdesc_gotent = elf32_arm_local_tlsdesc_gotent (ibfd);
s = htab->sgot;
srel = htab->srelgot;
- for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ for (; local_got < end_local_got;
+ ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
{
+ *local_tlsdesc_gotent = (bfd_vma) -1;
if (*local_got > 0)
{
*local_got = s->size;
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_GDESC)
+ {
+ *local_tlsdesc_gotent = htab->sgotplt->size
+ - elf32_arm_compute_jump_table_size (htab);
+ htab->sgotplt->size += 8;
+ *local_got = (bfd_vma) -2;
+
+ }
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 += RELOC_SIZE (htab);
+ if (*local_tls_type & GOT_NORMAL)
+ {
+ /* If the symbol is both GD and GDESC, *local_got may have
+ * been overwritten */
+ *local_got = s->size;
+ s->size += 4;
+ }
+
+ if (info->shared)
+ {
+ if (*local_tls_type & GOT_TLS_GD)
+ srel->size += RELOC_SIZE (htab);
+
+ if (*local_tls_type & GOT_TLS_GDESC)
+ htab->srelplt->size += RELOC_SIZE (htab);
+ }
}
else
*local_got = (bfd_vma) -1;
@@ -7713,6 +8188,34 @@ elf32_arm_size_dynamic_sections (bfd * o
sym dynamic relocs. */
elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
+ /* For every jump slot reserved in the sgotplt, reloc_count is
+ * incremented. However, when we reserve space for TLS descriptors,
+ * it's not incremented, so in order to compute the space reserved
+ * for them, it suffices to multiply the reloc count by the jump
+ * slot size. */
+ if (htab->srelplt)
+ htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size(htab);
+
+ if (htab->dt_tlsdesc_plt)
+ {
+ /* If we're not using lazy TLS relocations, don't generate the
+ * PLT and GOT entries they require. */
+ if ((info->flags & DF_BIND_NOW))
+ htab->dt_tlsdesc_plt = 0;
+ else
+ {
+ htab->dt_tlsdesc_got = htab->sgot->size;
+ htab->sgot->size += 4;
+
+ /* FIXME: If it does not break anything, we could probably just not
+ * emit the DT_TLSDESC_{PLT,GOT} entries. Not sure :-(*/
+ if (htab->splt->size == 0)
+ htab->splt->size += htab->plt_header_size;
+ htab->dt_tlsdesc_plt = htab->splt->size;
+ htab->splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline);
+ }
+ }
+
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
@@ -7803,6 +8306,11 @@ elf32_arm_size_dynamic_sections (bfd * o
htab->use_rel ? DT_REL : DT_RELA)
|| !add_dynamic_entry (DT_JMPREL, 0))
return FALSE;
+
+ if (htab->dt_tlsdesc_plt &&
+ (!add_dynamic_entry(DT_TLSDESC_PLT,0)
+ || !add_dynamic_entry(DT_TLSDESC_GOT,0)))
+ return FALSE;
}
if (relocs)
@@ -7840,6 +8348,44 @@ elf32_arm_size_dynamic_sections (bfd * o
return TRUE;
}
+/* Size sections even tough they're not dynamic. We use it to setup
+ * _TLS_MODULE_BASE_ if needed */
+static bfd_boolean
+elf32_arm_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *tls_sec = elf_hash_table (info)->tls_sec;
+
+ if (tls_sec)
+ {
+ struct elf_link_hash_entry *tlsbase;
+
+ tlsbase = elf_link_hash_lookup (elf_hash_table (info),
+ "_TLS_MODULE_BASE_",
+ TRUE, TRUE, FALSE);
+
+ if (tlsbase)
+ {
+ struct bfd_link_hash_entry *bh = NULL;
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (output_bfd);
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ tls_sec, 0, NULL, FALSE,
+ bed->collect, &bh)))
+ return FALSE;
+
+ tlsbase->type = STT_TLS;
+ tlsbase = (struct elf_link_hash_entry *)bh;
+ tlsbase->def_regular = 1;
+ tlsbase->other = STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ }
+ }
+ return TRUE;
+}
+
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
@@ -8048,7 +8594,7 @@ elf32_arm_finish_dynamic_symbol (bfd * o
}
if (h->got.offset != (bfd_vma) -1
- && (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_GD) == 0
+ && (! GOT_TLS_GD_ANY_P (elf32_arm_hash_entry (h)->tls_type))
&& (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_IE) == 0)
{
asection * sgot;
@@ -8279,6 +8825,20 @@ elf32_arm_finish_dynamic_sections (bfd *
}
break;
+ case DT_TLSDESC_PLT:
+ s = htab->splt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset +
+ htab->dt_tlsdesc_plt;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_TLSDESC_GOT:
+ s = htab->sgot;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset +
+ htab->dt_tlsdesc_got;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
/* Set the bottom bit of DT_INIT/FINI if the
corresponding function is Thumb. */
case DT_INIT:
@@ -8366,7 +8926,54 @@ elf32_arm_finish_dynamic_sections (bfd *
/* UnixWare sets the entsize of .plt to 4, although that doesn't
really seem like the right value. */
elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+
+ if (htab->dt_tlsdesc_plt)
+ {
+ bfd_vma got_address,gotplt_address, plt_address;
+ got_address = sgot->output_section->vma +
+ sgot->output_offset;
+ gotplt_address = htab->sgot->output_section->vma +
+ htab->sgot->output_offset;
+ plt_address = splt->output_section->vma +
+ splt->output_offset;
+
+ bfd_put_32 (output_bfd, dl_tlsdesc_lazy_trampoline[0], splt->contents +
+ htab->dt_tlsdesc_plt);
+ bfd_put_32 (output_bfd, dl_tlsdesc_lazy_trampoline[1], splt->contents +
+ htab->dt_tlsdesc_plt+4);
+
+ bfd_put_32 (output_bfd, dl_tlsdesc_lazy_trampoline[2], splt->contents +
+ htab->dt_tlsdesc_plt+8);
+ bfd_put_32 (output_bfd, dl_tlsdesc_lazy_trampoline[3], splt->contents +
+ htab->dt_tlsdesc_plt+12);
+ bfd_put_32 (output_bfd, dl_tlsdesc_lazy_trampoline[4], splt->contents +
+ htab->dt_tlsdesc_plt+16);
+ bfd_put_32 (output_bfd, dl_tlsdesc_lazy_trampoline[5], splt->contents +
+ htab->dt_tlsdesc_plt+20);
+
+ /* the numbers being added to dt_tlsdesc_plt are .L0 and .L1 respectively */
+ bfd_put_32 (output_bfd, gotplt_address + htab->dt_tlsdesc_got
+ - (plt_address + htab->dt_tlsdesc_plt + 0xc) - 8,
+ splt->contents + htab->dt_tlsdesc_plt+24);
+ bfd_put_32 (output_bfd, got_address -
+ (plt_address + htab->dt_tlsdesc_plt + 0x10) - 8,
+ splt->contents + htab->dt_tlsdesc_plt+28);
+ }
+
+ if (htab->tls_trampoline)
+ {
+ bfd_put_32 (output_bfd, tls_trampoline[0], splt->contents +
+ htab->tls_trampoline);
+ bfd_put_32 (output_bfd, tls_trampoline[1], splt->contents +
+ htab->tls_trampoline + 4);
+ bfd_put_32 (output_bfd, tls_trampoline[2], splt->contents +
+ htab->tls_trampoline + 8);
+#ifdef FOUR_WORD_PLT
+ bfd_put_32 (output_bfd, 0x00000000, splt->contents +
+ htab->tls_trampoline + 0xc);
+#endif
+ }
if (htab->vxworks_p && !info->shared && htab->splt->size > 0)
{
/* Correct the .rel(a).plt.unloaded relocations. They will have
@@ -9312,6 +9919,7 @@ const struct elf_size_info elf32_arm_siz
#define elf_backend_finish_dynamic_sections elf32_arm_finish_dynamic_sections
#define elf_backend_link_output_symbol_hook elf32_arm_output_symbol_hook
#define elf_backend_size_dynamic_sections elf32_arm_size_dynamic_sections
+#define elf_backend_always_size_sections elf32_arm_always_size_sections
#define elf_backend_post_process_headers elf32_arm_post_process_headers
#define elf_backend_reloc_type_class elf32_arm_reloc_type_class
#define elf_backend_object_p elf32_arm_object_p
Index: bfd/libbfd.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.h,v
retrieving revision 1.185
diff -u -p -r1.185 libbfd.h
--- bfd/libbfd.h 18 Jul 2006 16:44:46 -0000 1.185
+++ bfd/libbfd.h 14 Aug 2006 21:17:57 -0000
@@ -1232,6 +1232,10 @@ static const char *const bfd_reloc_code_
"BFD_RELOC_ARM_TLS_TPOFF32",
"BFD_RELOC_ARM_TLS_IE32",
"BFD_RELOC_ARM_TLS_LE32",
+ "BFD_RELOC_ARM_TLS_GOTDESC",
+ "BFD_RELOC_ARM_TLS_CALL",
+ "BFD_RELOC_ARM_TLS_DESCSEQ",
+ "BFD_RELOC_ARM_TLS_DESC",
"BFD_RELOC_ARM_ALU_PC_G0_NC",
"BFD_RELOC_ARM_ALU_PC_G0",
"BFD_RELOC_ARM_ALU_PC_G1_NC",
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.156
diff -u -p -r1.156 reloc.c
--- bfd/reloc.c 18 Jul 2006 16:44:46 -0000 1.156
+++ bfd/reloc.c 14 Aug 2006 21:18:08 -0000
@@ -2753,6 +2753,14 @@ ENUMX
BFD_RELOC_ARM_TLS_IE32
ENUMX
BFD_RELOC_ARM_TLS_LE32
+ENUMX
+ BFD_RELOC_ARM_TLS_GOTDESC
+ENUMX
+ BFD_RELOC_ARM_TLS_CALL
+ENUMX
+ BFD_RELOC_ARM_TLS_DESCSEQ
+ENUMX
+ BFD_RELOC_ARM_TLS_DESC
ENUMDOC
ARM thread-local storage relocations.
Index: gas/ChangeLog
===================================================================
RCS file: /cvs/src/src/gas/ChangeLog,v
retrieving revision 1.2983
diff -u -p -r1.2983 ChangeLog
--- gas/ChangeLog 12 Aug 2006 23:00:34 -0000 1.2983
+++ gas/ChangeLog 14 Aug 2006 21:18:17 -0000
@@ -1,3 +1,13 @@
+2006-08-14 Glauber de Oliveira Costa <glommer@gmail.com>
+
+ * config/tc-arm.c (s_arm_tls_descseq): Handles new TLS_ARM_DESCSEQ
+ relocation.
+ (md_pseudo_table): Added string for the aforementioned relocation.
+ (encode_branch): Adds R_ARM_TLS_CALL to the allowed branch relocs.
+ (reloc_names): Adds new relocations.
+ (md_apply_fix): Sets symbols as thread local in face of new relocs.
+ (tc_gen_reloc): Handles new relocations.
+
2006-08-12 Thiemo Seufer <ths@networkno.de>
* config/tc-mips.c (mips16_ip): Fix argument register handling
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.284
diff -u -p -r1.284 tc-arm.c
--- gas/config/tc-arm.c 8 Aug 2006 08:23:25 -0000 1.284
+++ gas/config/tc-arm.c 14 Aug 2006 21:19:32 -0000
@@ -3874,6 +3874,28 @@ bad:
}
#endif /* OBJ_ELF */
+/* Emit a fix for the symbol */
+static void
+s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
+{
+ char *p;
+ expressionS exp;
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+#ifdef md_cons_align
+ md_cons_align (4);
+#endif
+
+ /* Since we're just labeling the code, there's no need to define
+ * a mapping symbol */
+ expression (&exp);
+ p = obstack_next_free (&frchain_now->frch_obstack);
+ fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
+ BFD_RELOC_ARM_TLS_DESCSEQ);
+}
+
static void s_arm_arch (int);
static void s_arm_cpu (int);
static void s_arm_fpu (int);
@@ -3946,6 +3968,7 @@ const pseudo_typeS md_pseudo_table[] =
{ "setfp", s_arm_unwind_setfp, 0 },
{ "unwind_raw", s_arm_unwind_raw, 0 },
{ "eabi_attribute", s_arm_eabi_attribute, 0 },
+ { "tlsdescseq", s_arm_tls_descseq, 0 },
#else
{ "word", cons, 4},
@@ -6622,9 +6645,17 @@ encode_branch (int default_reloc)
{
if (inst.operands[0].hasreloc)
{
- constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
- _("the only suffix valid here is '(plt)'"));
- inst.reloc.type = BFD_RELOC_ARM_PLT32;
+ constraint ((inst.operands[0].imm != BFD_RELOC_ARM_PLT32) &&
+ (inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL),
+ _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
+ if (inst.operands[0].imm == BFD_RELOC_ARM_PLT32)
+ {
+ inst.reloc.type = BFD_RELOC_ARM_PLT32;
+ }
+ else
+ {
+ inst.reloc.type = BFD_RELOC_ARM_TLS_CALL;
+ }
}
else
{
@@ -14187,17 +14218,20 @@ static const struct asm_shift_name shift
#ifdef OBJ_ELF
static struct reloc_entry reloc_names[] =
{
- { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
- { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
- { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
- { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
- { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
- { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
- { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
- { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
- { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
- { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
- { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32}
+ { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
+ { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
+ { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
+ { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
+ { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
+ { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
+ { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
+ { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
+ { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
+ { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
+ { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
+ { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC}, { "TLSDESC",BFD_RELOC_ARM_TLS_GOTDESC},
+ { "tlscall", BFD_RELOC_ARM_TLS_CALL}, { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
+ { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ}, { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ}
};
#endif
@@ -17926,6 +17960,12 @@ md_apply_fix (fixS * fixP,
break;
#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_TLS_CALL:
+ case BFD_RELOC_ARM_TLS_DESCSEQ:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_ARM_TLS_GOTDESC:
case BFD_RELOC_ARM_TLS_GD32:
case BFD_RELOC_ARM_TLS_LE32:
case BFD_RELOC_ARM_TLS_IE32:
@@ -18504,6 +18544,8 @@ tc_gen_reloc (asection *section, fixS *f
return NULL;
#ifdef OBJ_ELF
+ case BFD_RELOC_ARM_TLS_CALL:
+ case BFD_RELOC_ARM_TLS_DESCSEQ:
case BFD_RELOC_ARM_GOT32:
case BFD_RELOC_ARM_GOTOFF:
case BFD_RELOC_ARM_PLT32:
@@ -18547,6 +18589,7 @@ tc_gen_reloc (asection *section, fixS *f
code = fixp->fx_r_type;
break;
+ case BFD_RELOC_ARM_TLS_GOTDESC:
case BFD_RELOC_ARM_TLS_GD32:
case BFD_RELOC_ARM_TLS_IE32:
case BFD_RELOC_ARM_TLS_LDM32:
@@ -18801,6 +18844,10 @@ arm_fix_adjustable (fixS * fixP)
|| 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_TLS_GOTDESC
+ || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
+ || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
+ || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESC
|| fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
return 0;
Index: gas/testsuite/ChangeLog
===================================================================
RCS file: /cvs/src/src/gas/testsuite/ChangeLog,v
retrieving revision 1.1062
diff -u -p -r1.1062 ChangeLog
--- gas/testsuite/ChangeLog 12 Aug 2006 23:00:35 -0000 1.1062
+++ gas/testsuite/ChangeLog 14 Aug 2006 21:19:37 -0000
@@ -1,3 +1,8 @@
+2006-08-14 Glauber de Oliveira Costa <glommer@gmail.com>
+
+ * gas/arm/tls.s: Generate new relocation types.
+ * gas/arm/tls.d: Adds checks for new TLS relocation types.
+
2006-08-12 Thiemo Seufer <ths@networkno.de>
* gas/mips/mips16-save.d: Fix testcase.
Index: gas/testsuite/gas/arm/tls.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/tls.d,v
retrieving revision 1.3
diff -u -p -r1.3 tls.d
--- gas/testsuite/gas/arm/tls.d 4 Jul 2005 14:55:52 -0000 1.3
+++ gas/testsuite/gas/arm/tls.d 14 Aug 2006 21:19:39 -0000
@@ -14,12 +14,17 @@ 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
+ 4: R_ARM_TLS_DESCSEQ f
+ 8: eb000000 bl 8 .*
+ 8: R_ARM_TLS_CALL e
+ c: e1a0f00e mov pc, lr
10: 00000004 andeq r0, r0, r4
- 10: R_ARM_TLS_LDM32 b
+ 10: R_ARM_TLS_GD32 a
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: R_ARM_TLS_LDM32 b
+ 18: 0000000c andeq r0, r0, ip
+ 18: R_ARM_TLS_IE32 c
+ 1c: 00000000 andeq r0, r0, r0
+ 1c: R_ARM_TLS_LE32 d
+ 20: 0000001c andeq r0, r0, ip, lsl r0
+ 20: R_ARM_TLS_GOTDESC e
Index: gas/testsuite/gas/arm/tls.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/tls.s,v
retrieving revision 1.2
diff -u -p -r1.2 tls.s
--- gas/testsuite/gas/arm/tls.s 29 Mar 2005 16:54:22 -0000 1.2
+++ gas/testsuite/gas/arm/tls.s 14 Aug 2006 21:19:39 -0000
@@ -4,7 +4,9 @@
main:
nop
.L2:
+.tlsdescseq f
nop
+ bl e(tlscall)
mov pc, lr
.Lpool:
@@ -12,3 +14,5 @@ main:
.word b(tlsldm) + (. - .L2 - 8)
.word c(gottpoff) + (. - .L2 - 8)
.word d(tpoff)
+ .word e(tlsdesc) + (. - .L2)
+
Index: include/elf/ChangeLog
===================================================================
RCS file: /cvs/src/src/include/elf/ChangeLog,v
retrieving revision 1.272
diff -u -p -r1.272 ChangeLog
--- include/elf/ChangeLog 10 Jul 2006 21:40:23 -0000 1.272
+++ include/elf/ChangeLog 14 Aug 2006 21:19:58 -0000
@@ -1,3 +1,8 @@
+2006-08-14 Glauber de Oliveira Costa <glommer@gmail.com>
+
+ * arm.h: Assigned new relocation numbers for new TLS
+ relocations
+
2006-07-10 Jakub Jelinek <jakub@redhat.com>
* common.h (SHT_GNU_HASH, DT_GNU_HASH): Define.
Index: include/elf/arm.h
===================================================================
RCS file: /cvs/src/src/include/elf/arm.h,v
retrieving revision 1.30
diff -u -p -r1.30 arm.h
--- include/elf/arm.h 15 Jun 2006 11:03:01 -0000 1.30
+++ include/elf/arm.h 14 Aug 2006 21:20:00 -0000
@@ -178,7 +178,10 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC, 87)
RELOC_NUMBER (R_ARM_THM_MOVT_BREL, 88)
RELOC_NUMBER (R_ARM_THM_MOVW_BREL, 89)
- /* 90-93 unallocated */
+ RELOC_NUMBER (R_ARM_TLS_GOTDESC, 90)
+ RELOC_NUMBER (R_ARM_TLS_CALL, 91)
+ RELOC_NUMBER (R_ARM_TLS_DESCSEQ, 92)
+ RELOC_NUMBER (R_ARM_TLS_DESC, 93)
RELOC_NUMBER (R_ARM_PLT32_ABS, 94)
RELOC_NUMBER (R_ARM_GOT_ABS, 95)
RELOC_NUMBER (R_ARM_GOT_PREL, 96)
Index: ld/testsuite/ChangeLog
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ChangeLog,v
retrieving revision 1.671
diff -u -p -r1.671 ChangeLog
--- ld/testsuite/ChangeLog 11 Aug 2006 14:05:12 -0000 1.671
+++ ld/testsuite/ChangeLog 14 Aug 2006 21:20:07 -0000
@@ -1,3 +1,22 @@
+2006-08-14 Glauber de Oliveira Costa <glommer@gmail.com>
+
+ * ld-arm/arm-elf.exp: Added tests for new TLS handling relocations.
+ * ld-arm/tls-gdierelax.s: New file.
+ * ld-arm/tls-gdierelax.d: Likewise.
+ * ld-arm/tls-gdierelax2.s: Likewise.
+ * ld-arm/tls-gdierelax2.d: Likewise.
+ * ld-arm/tls-gdlerelax.s: Likewise.
+ * ld-arm/tls-gdlerelax.d: Likewise.
+ * ld-arm/tls-gdesc-nlazy.s: Likewise.
+ * ld-arm/tls-gdesc-nlazy.g: Likewise.
+ * ld-arm/tls-gdesc.r: Likewise.
+ * ld-arm/tls-descseq.d: Likewise.
+ * ld-arm/tls-descseq.r: Likewise.
+ * ld-arm/tls-descseq.s: Likewise.
+ * ld-arm/tls-gdesc.s: Likewise.
+ * ld-arm/tls-gdesc.r: Likewise.
+ * ld-arm/tls-gdesc.d: Likewise.
+
2006-08-11 Thiemo Seufer <ths@mips.com>
* ld-elfcomm/elfcomm.exp (dump_common1): Extend regexp to match also
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.16
diff -u -p -r1.16 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp 19 Jun 2006 14:22:27 -0000 1.16
+++ ld/testsuite/ld-arm/arm-elf.exp 14 Aug 2006 21:20:07 -0000
@@ -119,6 +119,27 @@ set armelftests {
{"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"}
+ {"TLS gnu shared library" "-shared -T arm-dyn.ld" "" {tls-gdesc.s}
+ {{objdump -fdw tls-gdesc.d} {objdump -Rw tls-gdesc.r}}
+ "tls-lib2.so"}
+ {"TLS gnu shared library inlined trampoline" "-shared -T arm-dyn.ld" "" {tls-descseq.s}
+ {{objdump -fdw tls-descseq.d} {objdump -Rw tls-descseq.r}}
+ "tls-lib2inline.so"}
+ {"TLS gnu shared library non-lazy" "-z now -shared -T arm-dyn.ld" "" {tls-gdesc.s}
+ {{readelf "-x .got" tls-gdesc-nlazy.g}}
+ "tls-lib2-nlazy.so"}
+ {"TLS gnu GD to IE relaxation" "-static -T arm-dyn.ld" "" {tls-gdierelax.s}
+ {{objdump -fdw tls-gdierelax.d}}
+ "tls-app-rel-ie"}
+ {"TLS gnu GD to IE shared relaxation" "-shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
+ {{objdump -fdw tls-gdierelax2.d}}
+ "tls-app-rel-ie2"}
+ {"TLS gnu GD to LE relaxation" "-T arm-dyn.ld" "" {tls-gdlerelax.s}
+ {{objdump -fdw tls-gdlerelax.d}}
+ "tls-app-rel-le"}
+ {"TLS mixed models shared lib" "-shared -T arm-dyn.ld" "" {tls-mixed.s}
+ {{objdump -Rw tls-mixed.r}}
+ "tls-mixed.so"}
{"Thumb entry point" "-T arm.ld" "" {thumb-entry.s}
{{readelf -h thumb-entry.d}}
"thumb-entry"}
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-descseq.d 2006-08-14 14:36:40.000000000 -0300
@@ -0,0 +1,34 @@
+
+tmpdir/tls-lib2inline.so: file format elf32-.*arm
+architecture: arm, flags 0x[0-9a-f]+:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x[0-9a-f]+
+
+Disassembly of section .plt:
+
+[0-9a-f]+ <.plt>:
+ [0-9a-f]+: e52de004 str lr, \[sp, #-4\]!
+ [0-9a-f]+: e59fe004 ldr lr, \[pc, #4\] ; .*
+ [0-9a-f]+: e08fe00e add lr, pc, lr
+ [0-9a-f]+: e5bef008 ldr pc, \[lr, #8\]!
+ [0-9a-f]+: 000080d4 ldreqd r8, \[r0\], -r4
+ [0-9a-f]+: e08e0000 add r0, lr, r0
+ [0-9a-f]+: e5901004 ldr r1, \[r0, #4\]
+ [0-9a-f]+: e12fff11 bx r1
+ [0-9a-f]+: e92d0004 stmdb sp!, {r2}
+ [0-9a-f]+: e59f200c ldr r2, \[pc, #12\] ; .*
+ [0-9a-f]+: e59f100c ldr r1, \[pc, #12\] ; .*
+ [0-9a-f]+: e79f2002 ldr r2, \[pc, r2\]
+ [0-9a-f]+: e08f1001 add r1, pc, r1
+ [0-9a-f]+: e12fff12 bx r2
+ [0-9a-f]+: 000080c4 andeq r8, r0, r4, asr #1
+ [0-9a-f]+: 000080ac andeq r8, r0, ip, lsr #1
+Dis[0-9a-f]+ssembly of section .text:
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: e08f0000 add r0, pc, r0
+ [0-9a-f]+: e5901004 ldr r1, \[r0, #4\]
+ [0-9a-f]+: e12fff31 blx r1
+ [0-9a-f]+: e1a0f00e mov pc, lr
+ [0-9a-f]+: 000080a4 andeq r8, r0, r4, lsr #1
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-descseq.r 2006-07-04 23:36:50.000000000 -0300
@@ -0,0 +1,6 @@
+
+.*: file format elf32-.*arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET TYPE VALUE
+[0-9a-f]+ R_ARM_TLS_DESC lib_gd2
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-descseq.s 2006-07-04 23:38:35.000000000 -0300
@@ -0,0 +1,22 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L2:
+.tlsdescseq lib_gd2
+ add r0,pc,r0
+.tlsdescseq lib_gd2
+ ldr r1,[r0,#4]
+.tlsdescseq lib_gd2
+ blx r1
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+
+ .section .tdata,"awT"
+ .global lib_gd2
+lib_gd2:
+ .space 4
+
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdesc.d 2006-08-14 14:34:41.000000000 -0300
@@ -0,0 +1,32 @@
+
+tmpdir/tls-lib2.so: file format elf32-littlearm
+architecture: arm, flags 0x[0-9a-f]+:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x[0-9a-f]+
+
+Disassembly of section .plt:
+
+[0-9a-f]+ <.plt>:
+ [0-9a-f]+: e52de004 str lr, \[sp, #-4\]!
+ [0-9a-f]+: e59fe004 ldr lr, \[pc, #4\] ; .*
+ [0-9a-f]+: e08fe00e add lr, pc, lr
+ [0-9a-f]+: e5bef008 ldr pc, \[lr, #8\]!
+ [0-9a-f]+: 000080cc andeq r8, r0, ip, asr #1
+ [0-9a-f]+: e08e0000 add r0, lr, r0
+ [0-9a-f]+: e5901004 ldr r1, \[r0, #4\]
+ [0-9a-f]+: e12fff11 bx r1
+ [0-9a-f]+: e92d0004 stmdb sp!, {r2}
+ [0-9a-f]+: e59f200c ldr r2, \[pc, #12\] ; .*
+ [0-9a-f]+: e59f100c ldr r1, \[pc, #12\] ; .*
+ [0-9a-f]+: e79f2002 ldr r2, \[pc, r2\]
+ [0-9a-f]+: e08f1001 add r1, pc, r1
+ [0-9a-f]+: e12fff12 bx r2
+ [0-9a-f]+: 000080bc streqh r8, \[r0\], -ip
+ [0-9a-f]+: 000080a4 andeq r8, r0, r4, lsr #1
+Disassembly of section .text:
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: ebfffff2 bl 81e0 .*
+ [0-9a-f]+: e1a0f00e mov pc, lr
+ [0-9a-f]+: 000080a0 andeq r8, r0, r0, lsr #1
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdesc.r 2006-07-04 23:26:09.000000000 -0300
@@ -0,0 +1,6 @@
+
+.*: file format elf32-.*arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET TYPE VALUE
+[0-9a-f]+ R_ARM_TLS_DESC lib_gd2
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdesc.s 2006-07-09 00:47:18.000000000 -0300
@@ -0,0 +1,17 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L2:
+ bl lib_gd2(tlscall)
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+
+ .section .tdata,"awT"
+ .global lib_gd2
+lib_gd2:
+ .space 4
+
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdesc-nlazy.g 2006-07-09 01:13:19.000000000 -0300
@@ -0,0 +1,4 @@
+
+Hex dump of section '.got':
+ 0x[0-9a-f]+ 00000000 00000000 00000000 [0-9a-f]+ ................
+ 0x[0-9a-f]+ 00000000 ....
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdesc-nlazy.s 2006-07-04 23:53:15.000000000 -0300
@@ -0,0 +1,17 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L2:
+ blx lib_gd2(tlscall)
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+
+ .section .tdata,"awT"
+ .global lib_gd2
+lib_gd2:
+ .space 4
+
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdierelax.d 2006-07-10 00:25:30.000000000 -0300
@@ -0,0 +1,13 @@
+
+tmpdir/tls-app-rel-ie: file format elf32-.*arm
+architecture: arm, flags 0x[0-9a-f]+:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x[0-9a-f]+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: e79f0000 ldr r0, \[pc, r0\]
+ [0-9a-f]+: e1a0f00e mov pc, lr
+ [0-9a-f]+: 00008014 andeq r8, r0, r4, lsl r0
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdierelax.s 2006-07-05 10:31:04.000000000 -0300
@@ -0,0 +1,17 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L2:
+ blx lib_gd2(tlscall)
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+
+ .section .tdata,"awT"
+ .global lib_gd2
+lib_gd2:
+ .space 4
+
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdlerelax.d 2006-07-10 00:25:54.000000000 -0300
@@ -0,0 +1,13 @@
+
+tmpdir/tls-app-rel-le: file format elf32-.*arm
+architecture: arm, flags 0x[0-9a-f]+:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x[0-9a-f]+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: e1a0f00e mov pc, lr
+ [0-9a-f]+: 00000010 andeq r0, r0, r0, lsl r0
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdlerelax.s 2006-07-05 00:01:13.000000000 -0300
@@ -0,0 +1,16 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L2:
+ blx lib_gd2(tlscall)
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+
+ .section .tdata,"awT"
+lib_gd2:
+ .space 4
+
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdierelax2.d 2006-08-14 15:09:49.000000000 -0300
@@ -0,0 +1,15 @@
+
+tmpdir/tls-app-rel-ie2: file format elf32-.*arm
+architecture: arm, flags 0x[0-9a-f]+:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x[0-9a-f]+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <foo>:
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: e1a00000 nop \(mov r0,r0\)
+ [0-9a-f]+: e79f0000 ldr r0, \[pc, r0\]
+ [0-9a-f]+: e1a0f00e mov pc, lr
+ [0-9a-f]+: 00008088 andeq r8, r0, r8, lsl #1
+ [0-9a-f]+: 0000808c andeq r8, r0, ip, lsl #1
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-gdierelax2.s 2006-08-14 15:03:47.000000000 -0300
@@ -0,0 +1,19 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L1: nop
+.L2:
+ bl lib_gd2(tlscall)
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+ .word lib_gd2(gottpoff) + (. - .L1 - 8)
+
+ .section .tdata,"awT"
+ .global lib_gd2
+lib_gd2:
+ .space 4
+
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-mixed.r 2006-07-06 02:33:02.000000000 -0300
@@ -0,0 +1,10 @@
+
+.*: file format elf32-.*arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET TYPE VALUE
+[0-9a-f]+ R_ARM_TLS_DTPMOD32 lib_gd2
+[0-9a-f]+ R_ARM_TLS_DTPOFF32 lib_gd2
+[0-9a-f]+ R_ARM_TLS_DTPMOD32 lib_gd
+[0-9a-f]+ R_ARM_TLS_DTPOFF32 lib_gd
+[0-9a-f]+ R_ARM_TLS_DESC lib_gd2
--- /dev/null 2006-05-22 11:25:23.000000000 -0300
+++ ld/testsuite/ld-arm/tls-mixed.s 2006-07-09 01:14:10.000000000 -0300
@@ -0,0 +1,25 @@
+ .text
+ .globl foo
+ .type foo, %function
+foo:
+ nop
+.L1:
+ nop
+.L2:
+ bl lib_gd2(tlscall)
+ mov pc, lr
+
+.Lpool:
+ .word lib_gd(tlsgd) + (. - .L1 - 8)
+.Lpool2:
+ .word lib_gd2(tlsdesc) + (. - .L2)
+ .word lib_gd2(tlsgd) + (. - .L2 - 8)
+
+ .section .tdata,"awT"
+ .global lib_gd
+lib_gd:
+ .space 4
+ .global lib_gd2
+lib_gd2:
+ .space 4
+
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Support for Thread Local Storage Descriptors in ARM platform
2006-08-15 1:48 [PATCH] Support for Thread Local Storage Descriptors in ARM platform Glauber de Oliveira Costa
@ 2006-08-15 11:48 ` Richard Earnshaw
2006-08-15 16:40 ` Glauber de Oliveira Costa
0 siblings, 1 reply; 3+ messages in thread
From: Richard Earnshaw @ 2006-08-15 11:48 UTC (permalink / raw)
To: Glauber de Oliveira Costa; +Cc: binutils, Alexandre Oliva, aldenor
On Tue, 2006-08-15 at 01:29, Glauber de Oliveira Costa wrote:
> Hello All,
>
> Troughout the last months, Alexandre Oliva and I developed an ABI
> extension to allow ARM binaries to benefit from his newly devised TLS
> Descriptor method for accessing TLS variables
> (http://www.lsd.ic.unicamp.br/~aoliva/writeups/TLS/paper-gcc2006.pdf).
> Our proposed ABI can be found at
> http://www.lsd.ic.unicamp.br/~aoliva/writeups/TLS/RFC-TLSDESC-ARM.txt
> , and a paper describing the ARM implementation, to be presented at
> Linux Kongress in the first week of September at
> http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/paper-lk2006.pdf. We
> there describes some results we've got, that indicates a speedup of
> more than 2 times for the most common case.
>
> Attached to this message, follows the GNU linker and assembler part of
> the work. Please, feel free to send me feedbacks on the
> implementation, and consider it for merging.
Sorry, you can't just claim relocations like this. The allocation
process has to be co-ordinated by the ARM EABI, since the numbers you
have used may have been requested by some other third party. If you are
at the stage where you believe you have proved your model then you
should make a formal request (you can do that via me).
R.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Support for Thread Local Storage Descriptors in ARM platform
2006-08-15 11:48 ` Richard Earnshaw
@ 2006-08-15 16:40 ` Glauber de Oliveira Costa
0 siblings, 0 replies; 3+ messages in thread
From: Glauber de Oliveira Costa @ 2006-08-15 16:40 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: Alexandre Oliva, binutils, aldenor
> Sorry, you can't just claim relocations like this. The allocation
> process has to be co-ordinated by the ARM EABI, since the numbers you
> have used may have been requested by some other third party. If you are
> at the stage where you believe you have proved your model then you
> should make a formal request (you can do that via me).
>
> R.
Thanks Richard,
At this point, at least me and Oliva do think the model has been
proved, since we obtained very good practical results. I want to give
other people the chance to pronounce themselves about it, but our
relocations needs will probably be unchanged. I'd then would like to
start that formal process for number assigning, unless somebody
opposes.
How do we do that?
--
"Free as in Freedom"
Glauber de Oliveira Costa.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-08-15 13:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-15 1:48 [PATCH] Support for Thread Local Storage Descriptors in ARM platform Glauber de Oliveira Costa
2006-08-15 11:48 ` Richard Earnshaw
2006-08-15 16:40 ` Glauber de Oliveira Costa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).