aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-05-30 22:01:38 +0000
committerRichard Henderson <rth@redhat.com>2002-05-30 22:01:38 +0000
commit3765b1be13d34da8aae366959c3601a09afa193b (patch)
tree7b2ce41ab018a2991eb62806cf965c9cd9c00df4 /gas
parent0085b5a8ab186588ad7ae8baba6e82794837fbaf (diff)
downloadgdb-3765b1be13d34da8aae366959c3601a09afa193b.zip
gdb-3765b1be13d34da8aae366959c3601a09afa193b.tar.gz
gdb-3765b1be13d34da8aae366959c3601a09afa193b.tar.bz2
include/elf/
* alpha.h (R_ALPHA_TLSGD, R_ALPHA_TLSLDM, R_ALPHA_DTPMOD64, R_ALPHA_GOTDTPREL, R_ALPHA_DTPREL64, R_ALPHA_DTPRELHI, R_ALPHA_DTPRELLO, R_ALPHA_DTPREL16, R_ALPHA_GOTTPREL, R_ALPHA_TPREL64, R_ALPHA_TPRELHI, R_ALPHA_TPRELLO, R_ALPHA_TPREL16): New. bfd/ * elf64-alpha.c (ALPHA_ELF_LINK_HASH_LU_TLSGD, ALPHA_ELF_LINK_HASH_LU_TLSLDM, ALPHA_ELF_LINK_HASH_LU_FUNC): New. (ALPHA_ELF_GOT_ENTRY_RELOCS_DONE): Remove. (ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED): Remove. (struct alpha_elf_got_entry): Add reloc_type, reloc_done, reloc_xlated. (struct alpha_elf_obj_tdata): Rename total_got_entries and n_local_got_entries to total_got_size and local_got_size. (elf64_alpha_howto, elf64_alpha_reloc_map): Update for TLS relocs. (alpha_got_entry_size): New. (elf64_alpha_relax_with_lituse): Use it. (elf64_alpha_relax_without_lituse): Likewise. (MAX_GOT_SIZE): Rename from MAX_GOT_ENTRIES. (get_got_entry): New. (elf64_alpha_check_relocs): Handle TLS relocs. Reorganize. (elf64_alpha_adjust_dynamic_symbol): Test LU_FUNC as a mask. (elf64_alpha_merge_ind_symbols): Check gotent->reloc_type. (elf64_alpha_can_merge_gots, elf64_alpha_merge_gots): Likewise. (elf64_alpha_calc_got_offsets_for_symbol): Use alpha_got_entry_size. (elf64_alpha_calc_got_offsets): Likewise. (alpha_dynamic_entries_for_reloc): New. (elf64_alpha_calc_dynrel_sizes): Use it. (elf64_alpha_size_dynamic_sections): Likewise. (elf64_alpha_relocate_section): Handle TLS relocations. * reloc.c: Add Alpha TLS relocations. * bfd-in2.h, libbfd.h: Rebuild. gas/ * expr.h (operatorT): Add O_md17..O_md32. * config/tc-alpha.c (O_lituse_tlsgd, O_lituse_tlsldm, O_tlsgd, O_tlsldm, O_gotdtprel, O_dtprelhi, O_dtprello, O_dtprel, O_gottprel, O_tprelhi, O_tprello, O_tprel): New. (USER_RELOC_P, alpha_reloc_op_tag, debug_exp): Include them. (DUMMY_RELOC_LITUSE_TLSGD, DUMMY_RELOC_LITUSE_TLSLDM): New. (LITUSE_TLSGD, LITUSE_TLSLDM): New. (struct alpha_reloc_tag): Add master, saw_tlsgd, saw_tlsld, saw_lu_tlsgd, saw_lu_tlsldm. Make multi_section_p a bit field. (md_apply_fix3): Handle TLS relocations. (alpha_force_relocation, alpha_fix_adjustable): Likewise. (alpha_adjust_symtab_relocs): Sort LITERAL relocs after the associated TLS reloc. Check lituse_tls relocs match up. (emit_insn): Handle TLS relocations. (ldX_op): Remove. gas/testsuite/ * gas/alpha/elf-tls-1.s, gas/alpha/elf-tls-1.d: New. * gas/alpha/elf-tls-2.s, gas/alpha/elf-tls-1.l: New. * gas/alpha/elf-tls-3.s, gas/alpha/elf-tls-1.l: New. * gas/alpha/alpha.exp: Run them.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog18
-rw-r--r--gas/config/tc-alpha.c223
-rw-r--r--gas/expr.h2
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/alpha/alpha.exp3
-rw-r--r--gas/testsuite/gas/alpha/elf-tls-1.d29
-rw-r--r--gas/testsuite/gas/alpha/elf-tls-1.s24
-rw-r--r--gas/testsuite/gas/alpha/elf-tls-2.l9
-rw-r--r--gas/testsuite/gas/alpha/elf-tls-2.s32
-rw-r--r--gas/testsuite/gas/alpha/elf-tls-3.l7
-rw-r--r--gas/testsuite/gas/alpha/elf-tls-3.s22
11 files changed, 351 insertions, 25 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 979573b..84fac45 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,21 @@
+2002-05-30 Richard Henderson <rth@redhat.com>
+
+ * expr.h (operatorT): Add O_md17..O_md32.
+ * config/tc-alpha.c (O_lituse_tlsgd, O_lituse_tlsldm, O_tlsgd,
+ O_tlsldm, O_gotdtprel, O_dtprelhi, O_dtprello, O_dtprel, O_gottprel,
+ O_tprelhi, O_tprello, O_tprel): New.
+ (USER_RELOC_P, alpha_reloc_op_tag, debug_exp): Include them.
+ (DUMMY_RELOC_LITUSE_TLSGD, DUMMY_RELOC_LITUSE_TLSLDM): New.
+ (LITUSE_TLSGD, LITUSE_TLSLDM): New.
+ (struct alpha_reloc_tag): Add master, saw_tlsgd, saw_tlsld,
+ saw_lu_tlsgd, saw_lu_tlsldm. Make multi_section_p a bit field.
+ (md_apply_fix3): Handle TLS relocations.
+ (alpha_force_relocation, alpha_fix_adjustable): Likewise.
+ (alpha_adjust_symtab_relocs): Sort LITERAL relocs after the
+ associated TLS reloc. Check lituse_tls relocs match up.
+ (emit_insn): Handle TLS relocations.
+ (ldX_op): Remove.
+
2002-05-30 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* config/tc-mips.c (mips_gprel_offset): New variable.
diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c
index 7746f99..1ba7aca 100644
--- a/gas/config/tc-alpha.c
+++ b/gas/config/tc-alpha.c
@@ -106,30 +106,45 @@ struct alpha_macro {
#define O_pregister O_md1 /* O_register, in parentheses */
#define O_cpregister O_md2 /* + a leading comma */
-/* Note, the alpha_reloc_op table below depends on the ordering
- of O_literal .. O_gpre16. */
+/* The alpha_reloc_op table below depends on the ordering of these. */
#define O_literal O_md3 /* !literal relocation */
#define O_lituse_addr O_md4 /* !lituse_addr relocation */
#define O_lituse_base O_md5 /* !lituse_base relocation */
#define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
#define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
-#define O_gpdisp O_md8 /* !gpdisp relocation */
-#define O_gprelhigh O_md9 /* !gprelhigh relocation */
-#define O_gprellow O_md10 /* !gprellow relocation */
-#define O_gprel O_md11 /* !gprel relocation */
-#define O_samegp O_md12 /* !samegp relocation */
+#define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
+#define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
+#define O_gpdisp O_md10 /* !gpdisp relocation */
+#define O_gprelhigh O_md11 /* !gprelhigh relocation */
+#define O_gprellow O_md12 /* !gprellow relocation */
+#define O_gprel O_md13 /* !gprel relocation */
+#define O_samegp O_md14 /* !samegp relocation */
+#define O_tlsgd O_md15 /* !tlsgd relocation */
+#define O_tlsldm O_md16 /* !tlsldm relocation */
+#define O_gotdtprel O_md17 /* !gotdtprel relocation */
+#define O_dtprelhi O_md18 /* !dtprelhi relocation */
+#define O_dtprello O_md19 /* !dtprello relocation */
+#define O_dtprel O_md20 /* !dtprel relocation */
+#define O_gottprel O_md21 /* !gottprel relocation */
+#define O_tprelhi O_md22 /* !tprelhi relocation */
+#define O_tprello O_md23 /* !tprello relocation */
+#define O_tprel O_md24 /* !tprel relocation */
#define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
#define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
#define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
#define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
+#define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
+#define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
#define LITUSE_ADDR 0
#define LITUSE_BASE 1
#define LITUSE_BYTOFF 2
#define LITUSE_JSR 3
+#define LITUSE_TLSGD 4
+#define LITUSE_TLSLDM 5
-#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_samegp)
+#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
/* Macros for extracting the type and number of encoded register tokens */
@@ -496,11 +511,23 @@ static const struct alpha_reloc_op_tag {
DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
+ DEF(lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
+ DEF(lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
DEF(gprel, BFD_RELOC_GPREL16, 0, 0),
- DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0)
+ DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
+ DEF(tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
+ DEF(tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
+ DEF(gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
+ DEF(dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
+ DEF(dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
+ DEF(dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
+ DEF(gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
+ DEF(tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
+ DEF(tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
+ DEF(tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
};
#undef DEF
@@ -515,12 +542,17 @@ static const int alpha_num_reloc_op
/* Structure to hold explict sequence information. */
struct alpha_reloc_tag
{
- fixS *slaves; /* head of linked list of !literals */
+ fixS *master; /* the literal reloc */
+ fixS *slaves; /* head of linked list of lituses */
segT segment; /* segment relocs are in or undefined_section*/
long sequence; /* sequence # */
unsigned n_master; /* # of literals */
unsigned n_slaves; /* # of lituses */
- char multi_section_p; /* True if more than one section was used */
+ unsigned saw_tlsgd : 1; /* true if ... */
+ unsigned saw_tlsldm : 1;
+ unsigned saw_lu_tlsgd : 1;
+ unsigned saw_lu_tlsldm : 1;
+ unsigned multi_section_p : 1; /* true if more than one section was used */
char string[1]; /* printable form of sequence to hash with */
};
@@ -1223,6 +1255,16 @@ md_apply_fix3 (fixP, valP, seg)
#ifdef OBJ_ELF
case BFD_RELOC_ALPHA_BRSGP:
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
return;
#endif
@@ -1441,6 +1483,16 @@ alpha_force_relocation (f)
case BFD_RELOC_ALPHA_BRSGP:
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
return 1;
case BFD_RELOC_23_PCREL_S2:
@@ -1497,6 +1549,20 @@ alpha_fix_adjustable (f)
case BFD_RELOC_ALPHA_HINT:
return 1;
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
+ /* ??? No idea why we can't return a reference to .tbss+10, but
+ we're preventing this in the other assemblers. Follow for now. */
+ return 0;
+
default:
return 1;
}
@@ -1666,7 +1732,6 @@ alpha_adjust_symtab_relocs (abfd, sec, ptr)
fixS *fixp;
fixS *next;
fixS *slave;
- unsigned long n_slaves = 0;
/* If seginfo is NULL, we did not create this section; don't do
anything with it. By using a pointer to a pointer, we can update
@@ -1689,21 +1754,39 @@ alpha_adjust_symtab_relocs (abfd, sec, ptr)
switch (fixp->fx_r_type)
{
case BFD_RELOC_ALPHA_LITUSE:
- n_slaves++;
if (fixp->tc_fix_data.info->n_master == 0)
as_bad_where (fixp->fx_file, fixp->fx_line,
_("No !literal!%ld was found"),
fixp->tc_fix_data.info->sequence);
+ if (fixp->fx_offset == LITUSE_TLSGD)
+ {
+ if (! fixp->tc_fix_data.info->saw_tlsgd)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No !tlsgd!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+ }
+ else if (fixp->fx_offset == LITUSE_TLSLDM)
+ {
+ if (! fixp->tc_fix_data.info->saw_tlsldm)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("No !tlsldm!%ld was found"),
+ fixp->tc_fix_data.info->sequence);
+ }
break;
case BFD_RELOC_ALPHA_GPDISP_LO16:
- n_slaves++;
if (fixp->tc_fix_data.info->n_master == 0)
as_bad_where (fixp->fx_file, fixp->fx_line,
_("No ldah !gpdisp!%ld was found"),
fixp->tc_fix_data.info->sequence);
break;
+ case BFD_RELOC_ALPHA_ELF_LITERAL:
+ if (fixp->tc_fix_data.info->saw_tlsgd
+ || fixp->tc_fix_data.info->saw_tlsldm)
+ break;
+ /* FALLTHRU */
+
default:
*prevP = fixp;
prevP = &fixp->fx_next;
@@ -1711,10 +1794,10 @@ alpha_adjust_symtab_relocs (abfd, sec, ptr)
}
}
- /* If there were any dependent relocations, go and add them back to
- the chain. They are linked through the next_reloc field in
- reverse order, so as we go through the next_reloc chain, we
- effectively reverse the chain once again.
+ /* Go back and re-chain dependent relocations. They are currently
+ linked through the next_reloc field in reverse order, so as we
+ go through the next_reloc chain, we effectively reverse the chain
+ once again.
Except if there is more than one !literal for a given sequence
number. In that case, the programmer and/or compiler is not sure
@@ -1734,6 +1817,27 @@ alpha_adjust_symtab_relocs (abfd, sec, ptr)
next = fixp->fx_next;
switch (fixp->fx_r_type)
{
+ case BFD_RELOC_ALPHA_TLSGD:
+ case BFD_RELOC_ALPHA_TLSLDM:
+ if (!fixp->tc_fix_data.info)
+ break;
+ if (fixp->tc_fix_data.info->n_master == 0)
+ break;
+ else if (fixp->tc_fix_data.info->n_master > 1)
+ {
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("too many !literal!%ld for %s"),
+ fixp->tc_fix_data.info->sequence,
+ (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
+ ? "!tlsgd" : "!tlsldm"));
+ break;
+ }
+
+ fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
+ fixp->fx_next = fixp->tc_fix_data.info->master;
+ fixp = fixp->fx_next;
+ /* FALLTHRU */
+
case BFD_RELOC_ALPHA_ELF_LITERAL:
if (fixp->tc_fix_data.info->n_master == 1
&& ! fixp->tc_fix_data.info->multi_section_p)
@@ -1820,15 +1924,23 @@ debug_exp (tok, ntok)
case O_lituse_base: name = "O_lituse_base"; break;
case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
case O_lituse_jsr: name = "O_lituse_jsr"; break;
+ case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
+ case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
case O_gpdisp: name = "O_gpdisp"; break;
case O_gprelhigh: name = "O_gprelhigh"; break;
case O_gprellow: name = "O_gprellow"; break;
case O_gprel: name = "O_gprel"; break;
case O_samegp: name = "O_samegp"; break;
- case O_md13: name = "O_md13"; break;
- case O_md14: name = "O_md14"; break;
- case O_md15: name = "O_md15"; break;
- case O_md16: name = "O_md16"; break;
+ case O_tlsgd: name = "O_tlsgd"; break;
+ case O_tlsldm: name = "O_tlsldm"; break;
+ case O_gotdtprel: name = "O_gotdtprel"; break;
+ case O_dtprelhi: name = "O_dtprelhi"; break;
+ case O_dtprello: name = "O_dtprello"; break;
+ case O_dtprel: name = "O_dtprel"; break;
+ case O_gottprel: name = "O_gottprel"; break;
+ case O_tprelhi: name = "O_tprelhi"; break;
+ case O_tprello: name = "O_tprello"; break;
+ case O_tprel: name = "O_tprel"; break;
}
fprintf (stderr, ", %s(%s, %s, %d)", name,
@@ -2479,7 +2591,7 @@ emit_insn (insn)
{
const struct alpha_operand *operand = (const struct alpha_operand *) 0;
struct alpha_fixup *fixup = &insn->fixups[i];
- struct alpha_reloc_tag *info;
+ struct alpha_reloc_tag *info = NULL;
int size, pcrel;
fixS *fixP;
@@ -2521,6 +2633,14 @@ emit_insn (insn)
case BFD_RELOC_GPREL16:
case BFD_RELOC_ALPHA_GPREL_HI16:
case BFD_RELOC_ALPHA_GPREL_LO16:
+ case BFD_RELOC_ALPHA_GOTDTPREL16:
+ case BFD_RELOC_ALPHA_DTPREL_HI16:
+ case BFD_RELOC_ALPHA_DTPREL_LO16:
+ case BFD_RELOC_ALPHA_DTPREL16:
+ case BFD_RELOC_ALPHA_GOTTPREL16:
+ case BFD_RELOC_ALPHA_TPREL_HI16:
+ case BFD_RELOC_ALPHA_TPREL_LO16:
+ case BFD_RELOC_ALPHA_TPREL16:
fixP->fx_no_overflow = 1;
break;
@@ -2555,7 +2675,10 @@ emit_insn (insn)
case BFD_RELOC_ALPHA_ELF_LITERAL:
fixP->fx_no_overflow = 1;
+ if (insn->sequence == 0)
+ break;
info = get_alpha_reloc_tag (insn->sequence);
+ info->master = fixP;
info->n_master++;
if (info->segment != now_seg)
info->multi_section_p = 1;
@@ -2573,12 +2696,31 @@ emit_insn (insn)
goto do_lituse;
case DUMMY_RELOC_LITUSE_JSR:
fixP->fx_offset = LITUSE_JSR;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_TLSGD:
+ fixP->fx_offset = LITUSE_TLSGD;
+ goto do_lituse;
+ case DUMMY_RELOC_LITUSE_TLSLDM:
+ fixP->fx_offset = LITUSE_TLSLDM;
+ goto do_lituse;
do_lituse:
fixP->fx_addsy = section_symbol (now_seg);
fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
info = get_alpha_reloc_tag (insn->sequence);
- info->n_slaves++;
+ if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
+ info->saw_lu_tlsgd = 1;
+ else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
+ info->saw_lu_tlsldm = 1;
+ if (++info->n_slaves > 1)
+ {
+ if (info->saw_lu_tlsgd)
+ as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
+ insn->sequence);
+ else if (info->saw_lu_tlsldm)
+ as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
+ insn->sequence);
+ }
fixP->tc_fix_data.info = info;
fixP->tc_fix_data.next_reloc = info->slaves;
info->slaves = fixP;
@@ -2586,6 +2728,38 @@ emit_insn (insn)
info->multi_section_p = 1;
break;
+ case BFD_RELOC_ALPHA_TLSGD:
+ fixP->fx_no_overflow = 1;
+
+ if (insn->sequence == 0)
+ break;
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (info->saw_tlsgd)
+ as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
+ else if (info->saw_tlsldm)
+ as_bad (_("sequence number in use for !tlsldm!%ld"),
+ insn->sequence);
+ else
+ info->saw_tlsgd = 1;
+ fixP->tc_fix_data.info = info;
+ break;
+
+ case BFD_RELOC_ALPHA_TLSLDM:
+ fixP->fx_no_overflow = 1;
+
+ if (insn->sequence == 0)
+ break;
+ info = get_alpha_reloc_tag (insn->sequence);
+ if (info->saw_tlsldm)
+ as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
+ else if (info->saw_tlsgd)
+ as_bad (_("sequence number in use for !tlsgd!%ld"),
+ insn->sequence);
+ else
+ info->saw_tlsldm = 1;
+ fixP->tc_fix_data.info = info;
+ break;
+
default:
if ((int) fixup->reloc < 0)
{
@@ -2715,7 +2889,6 @@ static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
-static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
/* Implement the ldgp macro. */
diff --git a/gas/expr.h b/gas/expr.h
index 9483caf..3a4c931 100644
--- a/gas/expr.h
+++ b/gas/expr.h
@@ -107,6 +107,8 @@ typedef enum {
/* machine dependent operators */
O_md1, O_md2, O_md3, O_md4, O_md5, O_md6, O_md7, O_md8,
O_md9, O_md10, O_md11, O_md12, O_md13, O_md14, O_md15, O_md16,
+ O_md17, O_md18, O_md19, O_md20, O_md21, O_md22, O_md23, O_md24,
+ O_md25, O_md26, O_md27, O_md28, O_md29, O_md30, O_md31, O_md32,
/* this must be the largest value */
O_max
} operatorT;
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index ff91d8d..9554e69 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2002-05-30 Richard Henderson <rth@redhat.com>
+
+ * gas/alpha/elf-tls-1.s, gas/alpha/elf-tls-1.d: New.
+ * gas/alpha/elf-tls-2.s, gas/alpha/elf-tls-1.l: New.
+ * gas/alpha/elf-tls-3.s, gas/alpha/elf-tls-1.l: New.
+ * gas/alpha/alpha.exp: Run them.
+
2002-05-30 Tom Rix <trix@redhat.com>
* gas/d10v/d10v.exp: Add -gstabs packing, sequence control
diff --git a/gas/testsuite/gas/alpha/alpha.exp b/gas/testsuite/gas/alpha/alpha.exp
index 89a6334..6564cf9 100644
--- a/gas/testsuite/gas/alpha/alpha.exp
+++ b/gas/testsuite/gas/alpha/alpha.exp
@@ -29,6 +29,9 @@ if { [istarget alpha*-*-*] } then {
run_dump_test "elf-reloc-4"
run_dump_test "elf-reloc-5"
run_list_test "elf-reloc-6" ""
+ run_dump_test "elf-tls-1"
+ run_list_test "elf-tls-2" ""
+ run_list_test "elf-tls-3" ""
}
run_dump_test "fp"
diff --git a/gas/testsuite/gas/alpha/elf-tls-1.d b/gas/testsuite/gas/alpha/elf-tls-1.d
new file mode 100644
index 0000000..7f80de7
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-tls-1.d
@@ -0,0 +1,29 @@
+#objdump: -r
+#name: alpha elf-tls-1
+
+.*: file format elf64-alpha
+
+RELOCATION RECORDS FOR \[\.text\]:
+OFFSET TYPE VALUE
+0*0000004 TLSGD a
+0*0000000 ELF_LITERAL __tls_get_addr
+0*0000008 LITUSE \.text\+0x0*0000004
+0*0000008 HINT __tls_get_addr
+0*000000c HINT __tls_get_addr
+0*0000014 TLSLDM b
+0*0000010 ELF_LITERAL __tls_get_addr
+0*000000c LITUSE \.text\+0x0*0000005
+0*0000018 TLSGD c
+0*000001c TLSLDM d
+0*0000020 TLSGD e
+0*0000024 TLSLDM f
+0*0000028 GOTDTPREL g
+0*000002c DTPRELHI h
+0*0000030 DTPRELLO i
+0*0000034 DTPREL16 j
+0*0000038 GOTTPREL k
+0*000003c TPRELHI l
+0*0000040 TPRELLO m
+0*0000044 TPREL16 n
+
+
diff --git a/gas/testsuite/gas/alpha/elf-tls-1.s b/gas/testsuite/gas/alpha/elf-tls-1.s
new file mode 100644
index 0000000..42385d7
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-tls-1.s
@@ -0,0 +1,24 @@
+ .set nomacro
+ ldq $27, __tls_get_addr($29) !literal!1
+ ldq $16, a($29) !tlsgd!1
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!1
+
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!2
+ ldq $27, __tls_get_addr($29) !literal!2
+ ldq $16, b($29) !tlsldm!2
+
+ ldq $16, c($29) !tlsgd
+ ldq $16, d($29) !tlsldm
+
+ ldq $16, e($29) !tlsgd!3
+ ldq $16, f($29) !tlsldm!4
+
+ ldq $16, g($29) !gotdtprel
+ ldah $16, h($31) !dtprelhi
+ lda $16, i($16) !dtprello
+ lda $16, j($31) !dtprel
+
+ ldq $16, k($29) !gottprel
+ ldah $16, l($31) !tprelhi
+ lda $16, m($16) !tprello
+ lda $16, n($31) !tprel
diff --git a/gas/testsuite/gas/alpha/elf-tls-2.l b/gas/testsuite/gas/alpha/elf-tls-2.l
new file mode 100644
index 0000000..4fcee79
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-tls-2.l
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*:5: Error: too many lituse insns for !lituse_tlsgd!1
+.*:10: Error: too many lituse insns for !lituse_tlsldm!2
+.*:15: Error: too many lituse insns for !lituse_tlsgd!3
+.*:20: Error: too many lituse insns for !lituse_tlsldm!4
+.*:23: Error: duplicate !tlsgd!5
+.*:26: Error: duplicate !tlsldm!6
+.*:29: Error: sequence number in use for !tlsgd!7
+.*:32: Error: sequence number in use for !tlsldm!8
diff --git a/gas/testsuite/gas/alpha/elf-tls-2.s b/gas/testsuite/gas/alpha/elf-tls-2.s
new file mode 100644
index 0000000..214fe3a
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-tls-2.s
@@ -0,0 +1,32 @@
+ .set nomacro
+ ldq $16, c($29) !tlsgd!1
+ ldq $27, __tls_get_addr($29) !literal!1
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!1
+ jsr $26, ($27), __tls_get_addr !lituse_jsr!1
+
+ ldq $16, d($29) !tlsldm!2
+ ldq $27, __tls_get_addr($29) !literal!2
+ jsr $26, ($27), __tls_get_addr !lituse_jsr!2
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!2
+
+ ldq $16, g($29) !tlsgd!3
+ ldq $27, __tls_get_addr($29) !literal!3
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!3
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!3
+
+ ldq $16, h($29) !tlsldm!4
+ ldq $27, __tls_get_addr($29) !literal!4
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!4
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!4
+
+ ldq $16, i($29) !tlsgd!5
+ ldq $16, i($29) !tlsgd!5
+
+ ldq $16, j($29) !tlsldm!6
+ ldq $16, j($29) !tlsldm!6
+
+ ldq $16, k($29) !tlsgd!7
+ ldq $16, k($29) !tlsldm!7
+
+ ldq $16, l($29) !tlsldm!8
+ ldq $16, l($29) !tlsgd!8
diff --git a/gas/testsuite/gas/alpha/elf-tls-3.l b/gas/testsuite/gas/alpha/elf-tls-3.l
new file mode 100644
index 0000000..51d93e7
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-tls-3.l
@@ -0,0 +1,7 @@
+.*: Assembler messages:
+.*:3: Error: No !tlsgd!1 was found
+.*:6: Error: No !tlsldm!2 was found
+.*:18: Error: No !tlsldm!5 was found
+.*:22: Error: No !tlsgd!6 was found
+.*:8: Error: too many !literal!3 for !tlsgd
+.*:12: Error: too many !literal!4 for !tlsldm
diff --git a/gas/testsuite/gas/alpha/elf-tls-3.s b/gas/testsuite/gas/alpha/elf-tls-3.s
new file mode 100644
index 0000000..31480da
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-tls-3.s
@@ -0,0 +1,22 @@
+ .set nomacro
+ ldq $27, __tls_get_addr($29) !literal!1
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!1
+
+ ldq $27, __tls_get_addr($29) !literal!2
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!2
+
+ ldq $16, a($29) !tlsgd!3
+ ldq $27, __tls_get_addr($29) !literal!3
+ ldq $27, __tls_get_addr($29) !literal!3
+
+ ldq $16, b($29) !tlsldm!4
+ ldq $27, __tls_get_addr($29) !literal!4
+ ldq $27, __tls_get_addr($29) !literal!4
+
+ ldq $16, e($29) !tlsgd!5
+ ldq $27, __tls_get_addr($29) !literal!5
+ jsr $26, ($27), __tls_get_addr !lituse_tlsldm!5
+
+ ldq $16, f($29) !tlsldm!6
+ ldq $27, __tls_get_addr($29) !literal!6
+ jsr $26, ($27), __tls_get_addr !lituse_tlsgd!6