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.c100
1 files changed, 68 insertions, 32 deletions
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index ccae616..cf31770 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -782,31 +782,7 @@ obj_elf_parse_section_letters (char *str, size_t len)
}
static int
-obj_elf_section_word (char *str, size_t len)
-{
- if (len == 5 && strncmp (str, "write", 5) == 0)
- return SHF_WRITE;
- if (len == 5 && strncmp (str, "alloc", 5) == 0)
- return SHF_ALLOC;
- if (len == 9 && strncmp (str, "execinstr", 9) == 0)
- return SHF_EXECINSTR;
- if (len == 3 && strncmp (str, "tls", 3) == 0)
- return SHF_TLS;
-
-#ifdef md_elf_section_word
- {
- int md_attr = md_elf_section_word (str, len);
- if (md_attr >= 0)
- return md_attr;
- }
-#endif
-
- as_warn (_("unrecognized section attribute"));
- return 0;
-}
-
-static int
-obj_elf_section_type (char *str, size_t len)
+obj_elf_section_type (char *str, size_t len, bfd_boolean warn)
{
if (len == 8 && strncmp (str, "progbits", 8) == 0)
return SHT_PROGBITS;
@@ -829,7 +805,39 @@ obj_elf_section_type (char *str, size_t len)
}
#endif
- as_warn (_("unrecognized section type"));
+ if (warn)
+ as_warn (_("unrecognized section type"));
+ return 0;
+}
+
+static int
+obj_elf_section_word (char *str, size_t len, int *type)
+{
+ int ret;
+
+ if (len == 5 && strncmp (str, "write", 5) == 0)
+ return SHF_WRITE;
+ if (len == 5 && strncmp (str, "alloc", 5) == 0)
+ return SHF_ALLOC;
+ if (len == 9 && strncmp (str, "execinstr", 9) == 0)
+ return SHF_EXECINSTR;
+ if (len == 3 && strncmp (str, "tls", 3) == 0)
+ return SHF_TLS;
+
+#ifdef md_elf_section_word
+ {
+ int md_attr = md_elf_section_word (str, len);
+ if (md_attr >= 0)
+ return md_attr;
+ }
+#endif
+
+ ret = obj_elf_section_type (str, len, FALSE);
+ if (ret != 0)
+ *type = ret;
+ else
+ as_warn (_("unrecognized section attribute"));
+
return 0;
}
@@ -965,14 +973,14 @@ obj_elf_section (int push)
ignore_rest_of_line ();
return;
}
- type = obj_elf_section_type (beg, strlen (beg));
+ type = obj_elf_section_type (beg, strlen (beg), TRUE);
}
else if (c == '@' || c == '%')
{
beg = ++input_line_pointer;
c = get_symbol_end ();
*input_line_pointer = c;
- type = obj_elf_section_type (beg, input_line_pointer - beg);
+ type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
}
else
input_line_pointer = save;
@@ -1035,7 +1043,7 @@ obj_elf_section (int push)
c = get_symbol_end ();
*input_line_pointer = c;
- attr |= obj_elf_section_word (beg, input_line_pointer - beg);
+ attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
SKIP_WHITESPACE ();
}
@@ -1543,7 +1551,7 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED)
}
/* Handle the ELF .type pseudo-op. This sets the type of a symbol.
- There are five syntaxes:
+ There are six syntaxes:
The first (used on Solaris) is
.type SYM,#function
@@ -1555,8 +1563,32 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED)
.type SYM,%function
The fifth (used on SVR4/860) is
.type SYM,"function"
+ The sixth (emitted by recent SunPRO under Solaris) is
+ .type SYM,[0-9]
+ where the integer is the STT_* value.
*/
+static char *
+obj_elf_type_name (char *cp)
+{
+ char *p;
+
+ p = input_line_pointer;
+ if (*input_line_pointer >= '0'
+ && *input_line_pointer <= '9')
+ {
+ while (*input_line_pointer >= '0'
+ && *input_line_pointer <= '9')
+ ++input_line_pointer;
+ *cp = *input_line_pointer;
+ *input_line_pointer = '\0';
+ }
+ else
+ *cp = get_symbol_end ();
+
+ return p;
+}
+
static void
obj_elf_type (int ignore ATTRIBUTE_UNUSED)
{
@@ -1584,23 +1616,27 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
|| *input_line_pointer == '%')
++input_line_pointer;
- typename = input_line_pointer;
- c = get_symbol_end ();
+ typename = obj_elf_type_name (& c);
type = 0;
if (strcmp (typename, "function") == 0
+ || strcmp (typename, "2") == 0
|| strcmp (typename, "STT_FUNC") == 0)
type = BSF_FUNCTION;
else if (strcmp (typename, "object") == 0
+ || strcmp (typename, "1") == 0
|| strcmp (typename, "STT_OBJECT") == 0)
type = BSF_OBJECT;
else if (strcmp (typename, "tls_object") == 0
+ || strcmp (typename, "6") == 0
|| strcmp (typename, "STT_TLS") == 0)
type = BSF_OBJECT | BSF_THREAD_LOCAL;
else if (strcmp (typename, "notype") == 0
+ || strcmp (typename, "0") == 0
|| strcmp (typename, "STT_NOTYPE") == 0)
;
else if (strcmp (typename, "common") == 0
+ || strcmp (typename, "5") == 0
|| strcmp (typename, "STT_COMMON") == 0)
{
type = BSF_OBJECT;