aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog22
-rw-r--r--gas/config/obj-elf.c136
-rw-r--r--gas/config/obj-elf.h1
-rw-r--r--gas/config/tc-arm.c2
-rw-r--r--gas/config/tc-tic6x.c2
-rw-r--r--gas/read.c139
-rw-r--r--gas/read.h1
7 files changed, 161 insertions, 142 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 32998bb..0e2a25b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,25 @@
+2012-11-09 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * read.h (s_vendor_attribute): Move to...
+ * config/obj-elf.h (obj_elf_vendor_attribute): ... here.
+ * read.c (potable): Remove "gnu_attribute".
+ (skip_whitespace, skip_past_char, skip_past_comma): Delete, move
+ to config/obj-elf.c.
+ (s_vendor_attribute): Delete, move to obj_elf_vendor_attribute
+ in config/obj-elf.c.
+ (s_gnu_attribute): Delete, move to obj_elf_gnu_attribute in
+ config/obj-elf.c.
+ * config/obj-elf.c (elf_pseudo_table): Add "gnu_attribute".
+ (skip_whitespace, skip_past_char, skip_past_comma): New, moved
+ from read.c.
+ (obj_elf_vendor_attribute): New, moved from s_vendor_attribute
+ in read.c.
+ (obj_elf_gnu_attribute): New, moved from s_gnu_attribute in
+ read.c.
+ * config/tc-arm.c (s_arm_eabi_attribute): Rename
+ s_vendor_attribute to obj_elf_vendor_attribute.
+ * config/tc-tic6x.c (s_tic6x_c6xabi_attribute): Likewise.
+
2012-11-09 Nick Clifton <nickc@redhat.com>
* config/obj-elf.c (obj_elf_change_section): Allow init array
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index d0fbcfb..6450328 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -72,6 +72,7 @@ static void obj_elf_visibility (int);
static void obj_elf_symver (int);
static void obj_elf_subsection (int);
static void obj_elf_popsection (int);
+static void obj_elf_gnu_attribute (int);
static void obj_elf_tls_common (int);
static void obj_elf_lcomm (int);
static void obj_elf_struct (int);
@@ -113,6 +114,9 @@ static const pseudo_typeS elf_pseudo_table[] =
{"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
{"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
+ /* A GNU extension for object attributes. */
+ {"gnu_attribute", obj_elf_gnu_attribute, 0},
+
/* These are used for dwarf. */
{"2byte", cons, 2},
{"4byte", cons, 4},
@@ -1437,6 +1441,138 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
BFD_RELOC_VTABLE_ENTRY);
}
+#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
+
+static inline int
+skip_past_char (char ** str, char c)
+{
+ if (**str == c)
+ {
+ (*str)++;
+ return 0;
+ }
+ else
+ return -1;
+}
+#define skip_past_comma(str) skip_past_char (str, ',')
+
+/* Parse an attribute directive for VENDOR.
+ Returns the attribute number read, or zero on error. */
+
+int
+obj_elf_vendor_attribute (int vendor)
+{
+ expressionS exp;
+ int type;
+ int tag;
+ unsigned int i = 0;
+ char *s = NULL;
+
+ /* Read the first number or name. */
+ skip_whitespace (input_line_pointer);
+ s = input_line_pointer;
+ if (ISDIGIT (*input_line_pointer))
+ {
+ expression (& exp);
+ if (exp.X_op != O_constant)
+ goto bad;
+ tag = exp.X_add_number;
+ }
+ else
+ {
+ char *name;
+
+ /* A name may contain '_', but no other punctuation. */
+ for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
+ ++input_line_pointer)
+ i++;
+ if (i == 0)
+ goto bad;
+
+ name = (char *) alloca (i + 1);
+ memcpy (name, s, i);
+ name[i] = '\0';
+
+#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
+#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
+#endif
+
+ tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
+ if (tag == -1)
+ {
+ as_bad (_("Attribute name not recognised: %s"), name);
+ ignore_rest_of_line ();
+ return 0;
+ }
+ }
+
+ type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
+
+ if (skip_past_comma (&input_line_pointer) == -1)
+ goto bad;
+ if (type & 1)
+ {
+ expression (& exp);
+ if (exp.X_op != O_constant)
+ {
+ as_bad (_("expected numeric constant"));
+ ignore_rest_of_line ();
+ return 0;
+ }
+ i = exp.X_add_number;
+ }
+ if ((type & 3) == 3
+ && skip_past_comma (&input_line_pointer) == -1)
+ {
+ as_bad (_("expected comma"));
+ ignore_rest_of_line ();
+ return 0;
+ }
+ if (type & 2)
+ {
+ int len;
+
+ skip_whitespace (input_line_pointer);
+ if (*input_line_pointer != '"')
+ goto bad_string;
+ s = demand_copy_C_string (&len);
+ }
+
+ switch (type & 3)
+ {
+ case 3:
+ bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
+ break;
+ case 2:
+ bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
+ break;
+ case 1:
+ bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
+ break;
+ default:
+ abort ();
+ }
+
+ demand_empty_rest_of_line ();
+ return tag;
+bad_string:
+ as_bad (_("bad string constant"));
+ ignore_rest_of_line ();
+ return 0;
+bad:
+ as_bad (_("expected <tag> , <value>"));
+ ignore_rest_of_line ();
+ return 0;
+}
+
+/* Parse a .gnu_attribute directive. */
+
+static void
+obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
+{
+ obj_elf_vendor_attribute (OBJ_ATTR_GNU);
+}
+
void
elf_obj_read_begin_hook (void)
{
diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h
index 0721654..d4fd4d5 100644
--- a/gas/config/obj-elf.h
+++ b/gas/config/obj-elf.h
@@ -167,6 +167,7 @@ extern void obj_elf_change_section
(const char *, int, bfd_vma, int, const char *, int, int);
extern struct fix *obj_elf_vtable_inherit (int);
extern struct fix *obj_elf_vtable_entry (int);
+extern int obj_elf_vendor_attribute (int);
/* BFD wants to write the udata field, which is a no-no for the
predefined section symbols in bfd/section.c. They are read-only. */
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1ce5459..971ac6f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -4336,7 +4336,7 @@ s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
static void
s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
{
- int tag = s_vendor_attribute (OBJ_ATTR_PROC);
+ int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
attributes_set_explicitly[tag] = 1;
diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c
index ddbfb50..65517a6 100644
--- a/gas/config/tc-tic6x.c
+++ b/gas/config/tc-tic6x.c
@@ -693,7 +693,7 @@ static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
static void
s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED)
{
- int tag = s_vendor_attribute (OBJ_ATTR_PROC);
+ int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
tic6x_attributes_set_explicitly[tag] = TRUE;
diff --git a/gas/read.c b/gas/read.c
index 21c42b2..dc91f0b 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -244,9 +244,6 @@ static void do_align (int, char *, int, int);
static void s_align (int, int);
static void s_altmacro (int);
static void s_bad_end (int);
-#ifdef OBJ_ELF
-static void s_gnu_attribute (int);
-#endif
static void s_reloc (int);
static int hex_float (int, char *);
static segT get_known_segmented_expression (expressionS * expP);
@@ -378,9 +375,6 @@ static const pseudo_typeS potable[] = {
{"func", s_func, 0},
{"global", s_globl, 0},
{"globl", s_globl, 0},
-#ifdef OBJ_ELF
- {"gnu_attribute", s_gnu_attribute, 0},
-#endif
{"hword", cons, 2},
{"if", s_if, (int) O_ne},
{"ifb", s_ifb, 1},
@@ -2292,139 +2286,6 @@ s_globl (int ignore ATTRIBUTE_UNUSED)
mri_comment_end (stop, stopc);
}
-#ifdef OBJ_ELF
-#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
-
-static inline int
-skip_past_char (char ** str, char c)
-{
- if (**str == c)
- {
- (*str)++;
- return 0;
- }
- else
- return -1;
-}
-#define skip_past_comma(str) skip_past_char (str, ',')
-
-/* Parse an attribute directive for VENDOR.
- Returns the attribute number read, or zero on error. */
-int
-s_vendor_attribute (int vendor)
-{
- expressionS exp;
- int type;
- int tag;
- unsigned int i = 0;
- char *s = NULL;
-
- /* Read the first number or name. */
- skip_whitespace (input_line_pointer);
- s = input_line_pointer;
- if (ISDIGIT (*input_line_pointer))
- {
- expression (& exp);
- if (exp.X_op != O_constant)
- goto bad;
- tag = exp.X_add_number;
- }
- else
- {
- char *name;
-
- /* A name may contain '_', but no other punctuation. */
- for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
- ++input_line_pointer)
- i++;
- if (i == 0)
- goto bad;
-
- name = (char *) alloca (i + 1);
- memcpy (name, s, i);
- name[i] = '\0';
-
-#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
-#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
-#endif
-
- tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
- if (tag == -1)
- {
- as_bad (_("Attribute name not recognised: %s"), name);
- ignore_rest_of_line ();
- return 0;
- }
- }
-
- type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
-
- if (skip_past_comma (&input_line_pointer) == -1)
- goto bad;
- if (type & 1)
- {
- expression (& exp);
- if (exp.X_op != O_constant)
- {
- as_bad (_("expected numeric constant"));
- ignore_rest_of_line ();
- return 0;
- }
- i = exp.X_add_number;
- }
- if ((type & 3) == 3
- && skip_past_comma (&input_line_pointer) == -1)
- {
- as_bad (_("expected comma"));
- ignore_rest_of_line ();
- return 0;
- }
- if (type & 2)
- {
- int len;
-
- skip_whitespace (input_line_pointer);
- if (*input_line_pointer != '"')
- goto bad_string;
- s = demand_copy_C_string (&len);
- }
-
- switch (type & 3)
- {
- case 3:
- bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
- break;
- case 2:
- bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
- break;
- case 1:
- bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
- break;
- default:
- abort ();
- }
-
- demand_empty_rest_of_line ();
- return tag;
-bad_string:
- as_bad (_("bad string constant"));
- ignore_rest_of_line ();
- return 0;
-bad:
- as_bad (_("expected <tag> , <value>"));
- ignore_rest_of_line ();
- return 0;
-}
-
-/* Parse a .gnu_attribute directive. */
-
-static void
-s_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
-{
- s_vendor_attribute (OBJ_ATTR_GNU);
-}
-#endif /* OBJ_ELF */
-
/* Handle the MRI IRP and IRPC pseudo-ops. */
void
diff --git a/gas/read.h b/gas/read.h
index 4e5d1bb..81b958a 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -190,5 +190,4 @@ extern void stringer (int append_zero);
extern void s_xstab (int what);
extern void s_rva (int);
extern void s_incbin (int);
-extern int s_vendor_attribute (int);
extern void s_weakref (int);