aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/obj-elf.c52
-rw-r--r--gas/config/tc-alpha.c5
-rw-r--r--gas/config/tc-i386.c38
-rw-r--r--gas/config/tc-ia64.c115
-rw-r--r--gas/config/tc-ppc.c2
-rw-r--r--gas/config/tc-sparc.c1
6 files changed, 189 insertions, 24 deletions
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 8aca056..5524b07 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -61,6 +61,7 @@ static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
static void build_group_lists PARAMS ((bfd *, asection *, PTR));
static int elf_separate_stab_sections PARAMS ((void));
static void elf_init_stab_section PARAMS ((segT));
+static symbolS *elf_common PARAMS ((int));
#ifdef NEED_ECOFF_DEBUG
static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
@@ -84,6 +85,7 @@ static int obj_elf_section_type PARAMS ((char *, size_t));
static void obj_elf_symver PARAMS ((int));
static void obj_elf_subsection PARAMS ((int));
static void obj_elf_popsection PARAMS ((int));
+static void obj_elf_tls_common PARAMS ((int));
static const pseudo_typeS elf_pseudo_table[] =
{
@@ -130,6 +132,8 @@ static const pseudo_typeS elf_pseudo_table[] =
{"data", obj_elf_data, 0},
{"text", obj_elf_text, 0},
+ {"tls_common", obj_elf_tls_common, 0},
+
/* End sentinel. */
{NULL, NULL, 0},
};
@@ -280,8 +284,8 @@ elf_file_symbol (s)
#endif
}
-void
-obj_elf_common (is_common)
+static symbolS *
+elf_common (is_common)
int is_common;
{
char *name;
@@ -294,7 +298,7 @@ obj_elf_common (is_common)
if (flag_mri && is_common)
{
s_mri_common (0);
- return;
+ return NULL;
}
name = input_line_pointer;
@@ -307,14 +311,14 @@ obj_elf_common (is_common)
{
as_bad (_("expected comma after symbol-name"));
ignore_rest_of_line ();
- return;
+ return NULL;
}
input_line_pointer++; /* skip ',' */
if ((temp = get_absolute_expression ()) < 0)
{
as_bad (_(".COMMon length (%d.) <0! Ignored."), temp);
ignore_rest_of_line ();
- return;
+ return NULL;
}
size = temp;
*p = 0;
@@ -324,7 +328,7 @@ obj_elf_common (is_common)
{
as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
ignore_rest_of_line ();
- return;
+ return NULL;
}
if (S_GET_VALUE (symbolP) != 0)
{
@@ -374,7 +378,7 @@ obj_elf_common (is_common)
{
as_bad (_("common alignment not a power of 2"));
ignore_rest_of_line ();
- return;
+ return NULL;
}
}
else
@@ -426,7 +430,7 @@ obj_elf_common (is_common)
symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
demand_empty_rest_of_line ();
- return;
+ return symbolP;
{
bad_common_segment:
@@ -439,10 +443,27 @@ obj_elf_common (is_common)
*p = c;
input_line_pointer = p;
ignore_rest_of_line ();
- return;
+ return NULL;
}
}
+void
+obj_elf_common (is_common)
+ int is_common;
+{
+ elf_common (is_common);
+}
+
+static void
+obj_elf_tls_common (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ symbolS *symbolP = elf_common (0);
+
+ if (symbolP)
+ symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
+}
+
static void
obj_elf_local (ignore)
int ignore ATTRIBUTE_UNUSED;
@@ -594,6 +615,8 @@ static struct special_section const special_sections[] =
{ ".note", SHT_NOTE, 0 },
{ ".rodata", SHT_PROGBITS, SHF_ALLOC },
{ ".rodata1", SHT_PROGBITS, SHF_ALLOC },
+ { ".tbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
+ { ".tdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
{ ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
#if 0
/* FIXME: The current gcc, as of 2002-03-03, will emit
@@ -717,7 +740,8 @@ obj_elf_change_section (name, type, attr, entsize, group_name, push)
| (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
| ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
| ((attr & SHF_MERGE) ? SEC_MERGE : 0)
- | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0));
+ | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
+ | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
#ifdef md_elf_section_flags
flags = md_elf_section_flags (flags, attr, type);
#endif
@@ -749,7 +773,8 @@ obj_elf_change_section (name, type, attr, entsize, group_name, push)
saw the first time. */
if ((old_sec->flags ^ flags)
& (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
- | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS))
+ | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
+ | SEC_THREAD_LOCAL))
as_warn (_("ignoring changed section attributes for %s"), name);
else if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
as_warn (_("ignoring changed section entity size for %s"), name);
@@ -792,6 +817,9 @@ obj_elf_parse_section_letters (str, len)
case 'G':
attr |= SHF_GROUP;
break;
+ case 'T':
+ attr |= SHF_TLS;
+ break;
/* Compatibility. */
case 'm':
if (*(str - 1) == 'a')
@@ -806,7 +834,7 @@ obj_elf_parse_section_letters (str, len)
}
default:
{
- char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G");
+ char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T");
#ifdef md_elf_section_letter
int md_attr = md_elf_section_letter (*str, &bad_msg);
if (md_attr >= 0)
diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c
index ab2d40b..7746f99 100644
--- a/gas/config/tc-alpha.c
+++ b/gas/config/tc-alpha.c
@@ -1556,7 +1556,8 @@ tc_gen_reloc (sec, fixp)
* of thing, and as a result we need to fake it out here.
*/
if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
- || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
+ || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
+ || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
&& !S_IS_COMMON (fixp->fx_addsy))
reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
#endif
@@ -5467,7 +5468,7 @@ alpha_elf_section_letter (letter, ptr_msg)
if (letter == 's')
return SHF_ALPHA_GPREL;
- *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S in string");
+ *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
return 0;
}
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index f681014..653245f 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1219,6 +1219,12 @@ tc_i386_fix_adjustable (fixP)
if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
|| fixP->fx_r_type == BFD_RELOC_386_PLT32
|| fixP->fx_r_type == BFD_RELOC_386_GOT32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
|| fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
@@ -1236,6 +1242,12 @@ tc_i386_fix_adjustable (fixP)
#define BFD_RELOC_386_PLT32 0
#define BFD_RELOC_386_GOT32 0
#define BFD_RELOC_386_GOTOFF 0
+#define BFD_RELOC_386_TLS_GD 0
+#define BFD_RELOC_386_TLS_LDM 0
+#define BFD_RELOC_386_TLS_LDO_32 0
+#define BFD_RELOC_386_TLS_IE_32 0
+#define BFD_RELOC_386_TLS_LE_32 0
+#define BFD_RELOC_386_TLS_LE 0
#define BFD_RELOC_X86_64_PLT32 0
#define BFD_RELOC_X86_64_GOT32 0
#define BFD_RELOC_X86_64_GOTPCREL 0
@@ -3371,10 +3383,16 @@ lex_got (reloc, adjust)
const char *str;
const RELOC_ENUM rel[NUM_FLAG_CODE];
} gotrel[] = {
- { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
- { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
- { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
- { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
+ { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
+ { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
+ { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
+ { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, 0 } },
+ { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } },
+ { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, 0 } },
+ { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, 0 } },
+ { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } },
+ { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, 0 } },
+ { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
};
char *cp;
unsigned int j;
@@ -4577,6 +4595,12 @@ md_apply_fix3 (fixP, valP, seg)
value -= 1;
break;
case BFD_RELOC_386_GOT32:
+ case BFD_RELOC_386_TLS_GD:
+ case BFD_RELOC_386_TLS_LDM:
+ case BFD_RELOC_386_TLS_LDO_32:
+ case BFD_RELOC_386_TLS_IE_32:
+ case BFD_RELOC_386_TLS_LE_32:
+ case BFD_RELOC_386_TLS_LE:
case BFD_RELOC_X86_64_GOT32:
value = 0; /* Fully resolved at runtime. No addend. */
break;
@@ -5045,6 +5069,12 @@ tc_gen_reloc (section, fixp)
case BFD_RELOC_386_GOT32:
case BFD_RELOC_386_GOTOFF:
case BFD_RELOC_386_GOTPC:
+ case BFD_RELOC_386_TLS_GD:
+ case BFD_RELOC_386_TLS_LDM:
+ case BFD_RELOC_386_TLS_LDO_32:
+ case BFD_RELOC_386_TLS_IE_32:
+ case BFD_RELOC_386_TLS_LE_32:
+ case BFD_RELOC_386_TLS_LE:
case BFD_RELOC_X86_64_32S:
case BFD_RELOC_RVA:
case BFD_RELOC_VTABLE_ENTRY:
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index cbbc914..ae26ada 100644
--- a/gas/config/tc-ia64.c
+++ b/gas/config/tc-ia64.c
@@ -77,6 +77,8 @@ enum special_section
enum reloc_func
{
+ FUNC_DTP_MODULE,
+ FUNC_DTP_RELATIVE,
FUNC_FPTR_RELATIVE,
FUNC_GP_RELATIVE,
FUNC_LT_RELATIVE,
@@ -84,8 +86,12 @@ enum reloc_func
FUNC_PLT_RELATIVE,
FUNC_SEC_RELATIVE,
FUNC_SEG_RELATIVE,
+ FUNC_TP_RELATIVE,
FUNC_LTV_RELATIVE,
FUNC_LT_FPTR_RELATIVE,
+ FUNC_LT_DTP_MODULE,
+ FUNC_LT_DTP_RELATIVE,
+ FUNC_LT_TP_RELATIVE,
FUNC_IPLT_RELOC,
};
@@ -476,6 +482,8 @@ static struct
pseudo_func[] =
{
/* reloc pseudo functions (these must come first!): */
+ { "dtpmod", PSEUDO_FUNC_RELOC, { 0 } },
+ { "dtprel", PSEUDO_FUNC_RELOC, { 0 } },
{ "fptr", PSEUDO_FUNC_RELOC, { 0 } },
{ "gprel", PSEUDO_FUNC_RELOC, { 0 } },
{ "ltoff", PSEUDO_FUNC_RELOC, { 0 } },
@@ -483,8 +491,12 @@ pseudo_func[] =
{ "pltoff", PSEUDO_FUNC_RELOC, { 0 } },
{ "secrel", PSEUDO_FUNC_RELOC, { 0 } },
{ "segrel", PSEUDO_FUNC_RELOC, { 0 } },
+ { "tprel", PSEUDO_FUNC_RELOC, { 0 } },
{ "ltv", PSEUDO_FUNC_RELOC, { 0 } },
{ "", 0, { 0 } }, /* placeholder for FUNC_LT_FPTR_RELATIVE */
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_DTP_MODULE */
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_DTP_RELATIVE */
+ { "", 0, { 0 } }, /* placeholder for FUNC_LT_TP_RELATIVE */
{ "iplt", PSEUDO_FUNC_RELOC, { 0 } },
/* mbtype4 constants: */
@@ -943,7 +955,7 @@ ia64_elf_section_letter (letter, ptr_msg)
if (letter == 's')
return SHF_IA_64_SHORT;
- *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S in string");
+ *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
return 0;
}
@@ -6494,6 +6506,14 @@ md_begin ()
bfd_set_section_alignment (stdoutput, text_section, 4);
target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+ pseudo_func[FUNC_DTP_MODULE].u.sym =
+ symbol_new (".<dtpmod>", undefined_section, FUNC_DTP_MODULE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_DTP_RELATIVE].u.sym =
+ symbol_new (".<dtprel>", undefined_section, FUNC_DTP_RELATIVE,
+ &zero_address_frag);
+
pseudo_func[FUNC_FPTR_RELATIVE].u.sym =
symbol_new (".<fptr>", undefined_section, FUNC_FPTR_RELATIVE,
&zero_address_frag);
@@ -6522,6 +6542,10 @@ md_begin ()
symbol_new (".<segrel>", undefined_section, FUNC_SEG_RELATIVE,
&zero_address_frag);
+ pseudo_func[FUNC_TP_RELATIVE].u.sym =
+ symbol_new (".<tprel>", undefined_section, FUNC_TP_RELATIVE,
+ &zero_address_frag);
+
pseudo_func[FUNC_LTV_RELATIVE].u.sym =
symbol_new (".<ltv>", undefined_section, FUNC_LTV_RELATIVE,
&zero_address_frag);
@@ -6530,6 +6554,18 @@ md_begin ()
symbol_new (".<ltoff.fptr>", undefined_section, FUNC_LT_FPTR_RELATIVE,
&zero_address_frag);
+ pseudo_func[FUNC_LT_DTP_MODULE].u.sym =
+ symbol_new (".<ltoff.dtpmod>", undefined_section, FUNC_LT_DTP_MODULE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_DTP_RELATIVE].u.sym =
+ symbol_new (".<ltoff.dptrel>", undefined_section, FUNC_LT_DTP_RELATIVE,
+ &zero_address_frag);
+
+ pseudo_func[FUNC_LT_TP_RELATIVE].u.sym =
+ symbol_new (".<ltoff.tprel>", undefined_section, FUNC_LT_TP_RELATIVE,
+ &zero_address_frag);
+
pseudo_func[FUNC_IPLT_RELOC].u.sym =
symbol_new (".<iplt>", undefined_section, FUNC_IPLT_RELOC,
&zero_address_frag);
@@ -9826,11 +9862,22 @@ md_operand (e)
as_bad ("Not a symbolic expression");
goto err;
}
- if (S_GET_VALUE (e->X_op_symbol) == FUNC_FPTR_RELATIVE
- && i == FUNC_LT_RELATIVE)
- i = FUNC_LT_FPTR_RELATIVE;
- else
+ if (i != FUNC_LT_RELATIVE)
+ {
+ as_bad ("Illegal combination of relocation functions");
+ goto err;
+ }
+ switch (S_GET_VALUE (e->X_op_symbol))
{
+ case FUNC_FPTR_RELATIVE:
+ i = FUNC_LT_FPTR_RELATIVE; break;
+ case FUNC_DTP_MODULE:
+ i = FUNC_LT_DTP_MODULE; break;
+ case FUNC_DTP_RELATIVE:
+ i = FUNC_LT_DTP_RELATIVE; break;
+ case FUNC_TP_RELATIVE:
+ i = FUNC_LT_TP_RELATIVE; break;
+ default:
as_bad ("Illegal combination of relocation functions");
goto err;
}
@@ -10163,6 +10210,64 @@ ia64_gen_real_reloc_type (sym, r_type)
}
break;
+ case FUNC_TP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM14:
+ new = BFD_RELOC_IA64_TPREL14; break;
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_TPREL22; break;
+ case BFD_RELOC_IA64_IMM64:
+ new = BFD_RELOC_IA64_TPREL64I; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_LT_TP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_TPREL22; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_LT_DTP_MODULE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_DTPMOD22; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_DTP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM14:
+ new = BFD_RELOC_IA64_DTPREL14; break;
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_DTPREL22; break;
+ case BFD_RELOC_IA64_IMM64:
+ new = BFD_RELOC_IA64_DTPREL64I; break;
+ default:
+ break;
+ }
+ break;
+
+ case FUNC_LT_DTP_RELATIVE:
+ switch (r_type)
+ {
+ case BFD_RELOC_IA64_IMM22:
+ new = BFD_RELOC_IA64_LTOFF_DTPREL22; break;
+ default:
+ break;
+ }
+ break;
+
case FUNC_IPLT_RELOC:
break;
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 808487b..e1c7c57 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -2485,7 +2485,7 @@ ppc_section_letter (letter, ptr_msg)
if (letter == 'e')
return SHF_EXCLUDE;
- *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S in string");
+ *ptr_msg = _("Bad .section directive: want a,e,w,x,M,S,G,T in string");
return 0;
}
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 2d75fef..80cf39e 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -2916,6 +2916,7 @@ md_apply_fix3 (fixP, valP, segment)
&& (S_IS_EXTERNAL (sym)
|| S_IS_WEAK (sym)
|| (seg->flags & SEC_MERGE)
+ || (seg->flags & SEC_THREAD_LOCAL)
|| (sparc_pic_code && ! fixP->fx_pcrel)
|| (seg != segment
&& (((bfd_get_section_flags (stdoutput, seg) & SEC_LINK_ONCE) != 0)