[PATCH] GAS: Move .gnu_attribute to ELF object format support

Maciej W. Rozycki macro@codesourcery.com
Thu Nov 8 17:21:00 GMT 2012


Hi,

 While working on a new feature I have realised that code to handle the 
.gnu_attribute directive has been placed in the wrong place.  This 
pseudo-op is specific to ELF targets, but rather than with the rest of 
general ELF object format code it has been placed with generic code used 
for all targets.  This arrangement makes it more difficult to get that 
code work as expected, in particular it is currently broken for 
multi-format configurations (OBJ_MAYBE_ELF).

 The change below corrects it, by moving all the relevant pieces from 
generic code to ELF object support code.  There are no functional changes, 
merely relocating all the code verbatim, however I decided to rename 
s_vendor_attribute to obj_elf_vendor_attribute and s_gnu_attribute to 
obj_elf_gnu_attribute so as to make it clear this is an ELF object rather 
than generic feature.  The two targets that call it directly (rather than 
via the pseudo-op handler dispatcher) do not appear to support 
multi-format configurations at the moment.

 Regression-tested with no problems observed across the usual 134 targets.  
OK to apply?

2012-11-08  Maciej W. Rozycki  <macro@codesourcery.com>

	gas/
	* 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.

  Maciej

binutils-gas-gnu-attribute-fix.diff
Index: binutils-fsf-trunk-quilt/gas/config/obj-elf.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/obj-elf.c	2012-07-18 05:32:12.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/obj-elf.c	2012-10-22 01:37:12.251558767 +0100
@@ -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_tab
   {"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},
@@ -1429,6 +1433,138 @@ obj_elf_vtable_entry (int ignore ATTRIBU
 		  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)
 {
Index: binutils-fsf-trunk-quilt/gas/read.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/read.c	2012-07-04 12:07:28.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/read.c	2012-10-22 01:26:56.711073852 +0100
@@ -244,9 +244,6 @@ static void do_align (int, char *, 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
Index: binutils-fsf-trunk-quilt/gas/config/obj-elf.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/obj-elf.h	2011-10-04 15:29:07.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/obj-elf.h	2012-10-22 01:35:52.581209066 +0100
@@ -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.  */
Index: binutils-fsf-trunk-quilt/gas/config/tc-arm.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-arm.c	2012-09-20 16:21:49.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-arm.c	2012-10-22 01:34:18.310560318 +0100
@@ -4336,7 +4336,7 @@ s_arm_unwind_raw (int ignored ATTRIBUTE_
 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;
Index: binutils-fsf-trunk-quilt/gas/config/tc-tic6x.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/config/tc-tic6x.c	2012-07-04 12:07:28.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/config/tc-tic6x.c	2012-10-22 01:34:46.390871789 +0100
@@ -693,7 +693,7 @@ static bfd_boolean tic6x_attributes_set_
 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;
Index: binutils-fsf-trunk-quilt/gas/read.h
===================================================================
--- binutils-fsf-trunk-quilt.orig/gas/read.h	2012-07-04 12:07:28.000000000 +0100
+++ binutils-fsf-trunk-quilt/gas/read.h	2012-10-22 01:35:16.331277998 +0100
@@ -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);



More information about the Binutils mailing list