aboutsummaryrefslogtreecommitdiff
path: root/gas/config/obj-elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config/obj-elf.c')
-rw-r--r--gas/config/obj-elf.c52
1 files changed, 40 insertions, 12 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)