[GAS PATCH]: Some SunPRO compat items...

David Miller davem@davemloft.net
Fri Apr 18 11:24:00 GMT 2008


I was reading over some SunPRO compiler assembler output
while working on something, and wanted to see how well
GAS could cope with this output.

It did mostly well, except for a few items, some of which are
addressed in this patch.  I figured it does no harm to support
these things.

First, SunPRO outputs section directives like:

	.section	".text",#alloc,#execinstr,#progbits

that is, it specifies section types using "#" notation instead
of "@" notation.

Next, it uses integers to specify section types in ".type"
declarations.  For example:

	.type		bar,2

where this "2" means STT_FUNC.

There is one more directive necessary to get all the examples I have
through gas, and that is the mnemonic %section_symbol().  I haven't
figured out how to implemented that bit yet, but you can use it like:

	.section ".debug_info"
  ...
	.uaword %section_symbol(".debug_abbrev")

instead of the song and dance GCC currently has to output:

	.section	".debug_abbrev"
.LLdebug_abbrev0:
 ...
	.section	".debug_info"
 ...
	.uaword	.LLdebug_abbrev0

Any objections?

2008-04-18  David S. Miller  <davem@davemloft.net>

	* config/obj-elf.c (obj_elf_section_type): Move before
	obj_elf_section_word and add 'warn' arg.
	(obj_elf_section_word): Add type pointer arg, and if no #SECTION
	is matched, try checking for #SECTION_TYPE.
	(obj_elf_section): Adjust for new args.
	(obj_elf_type_name): New function.
	(obj_elf_type): Call it, and accept STT_foo number strings
	in .type statements as output by SunPRO compiler.
	
Index: config/obj-elf.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-elf.c,v
retrieving revision 1.108
diff -u -p -r1.108 obj-elf.c
--- config/obj-elf.c	27 Oct 2007 17:45:53 -0000	1.108
+++ config/obj-elf.c	18 Apr 2008 11:13:37 -0000
@@ -782,31 +782,7 @@ obj_elf_parse_section_letters (char *str
 }
 
 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, int warn)
 {
   if (len == 8 && strncmp (str, "progbits", 8) == 0)
     return SHT_PROGBITS;
@@ -829,7 +805,41 @@ obj_elf_section_type (char *str, size_t 
   }
 #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, 0);
+  if (ret != 0)
+    {
+      *type = ret;
+      return 0;
+    }
+
+  as_warn (_("unrecognized section attribute"));
   return 0;
 }
 
@@ -965,14 +975,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), 1);
 		}
 	      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, 1);
 		}
 	      else
 		input_line_pointer = save;
@@ -1035,7 +1045,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 +1553,7 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSE
 }
 
 /* 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,7 +1565,30 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSE
        .type SYM,%function
    The fifth (used on SVR4/860) is
        .type SYM,"function"
+   The sizth (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,24 +1617,28 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSE
       || *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, "STT_FUNC") == 0)
+      || strcmp (typename, "STT_FUNC") == 0
+      || strcmp (typename, "2") == 0)
     type = BSF_FUNCTION;
   else if (strcmp (typename, "object") == 0
-	   || strcmp (typename, "STT_OBJECT") == 0)
+	   || strcmp (typename, "STT_OBJECT") == 0
+	   || strcmp (typename, "1") == 0)
     type = BSF_OBJECT;
   else if (strcmp (typename, "tls_object") == 0
-	   || strcmp (typename, "STT_TLS") == 0)
+	   || strcmp (typename, "STT_TLS") == 0
+	   || strcmp (typename, "6") == 0)
     type = BSF_OBJECT | BSF_THREAD_LOCAL;
   else if (strcmp (typename, "notype") == 0
-	   || strcmp (typename, "STT_NOTYPE") == 0)
+	   || strcmp (typename, "STT_NOTYPE") == 0
+	   || strcmp (typename, "0") == 0)
     ;
   else if (strcmp (typename, "common") == 0
-	   || strcmp (typename, "STT_COMMON") == 0)
+	   || strcmp (typename, "STT_COMMON") == 0
+	   || strcmp (typename, "5") == 0)
     {
       type = BSF_OBJECT;
 



More information about the Binutils mailing list