diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2012-11-09 18:07:10 +0000 |
---|---|---|
committer | Maciej W. Rozycki <macro@linux-mips.org> | 2012-11-09 18:07:10 +0000 |
commit | 0420f52b9441ae498323d1656d5d2af66a1e13c7 (patch) | |
tree | 94d8720f0dced7178a6a90d972dcde6f0046a096 /gas/config | |
parent | de863c74750924a0c3e8fae251c49c69e3ddff36 (diff) | |
download | gdb-0420f52b9441ae498323d1656d5d2af66a1e13c7.zip gdb-0420f52b9441ae498323d1656d5d2af66a1e13c7.tar.gz gdb-0420f52b9441ae498323d1656d5d2af66a1e13c7.tar.bz2 |
* 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.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/obj-elf.c | 136 | ||||
-rw-r--r-- | gas/config/obj-elf.h | 1 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 2 | ||||
-rw-r--r-- | gas/config/tc-tic6x.c | 2 |
4 files changed, 139 insertions, 2 deletions
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; |