PATCH: Add .alias and .secalias

H. J. Lu hjl@lucon.org
Sat May 3 00:04:00 GMT 2003


This patch adds .alias and .secalias to ia64.


H.J.
-------------- next part --------------
gas/

2003-05-02  H.J. Lu <hjl@gnu.org>

	* config/tc-ia64.c: Include "struc-symbol.h".
	(alias_hash): New.
	(secalias_hash): New.
	(md_pseudo_table): Add "secalias".
	(md_begin): Initialize alias_hash and secalias_hash.
	(struct alias): New.
	(dot_alias): Implement .alias and .secalias directives.
	(do_alias): New.
	(ia64_adjust_symtab): New.
	(do_secalias): New.
	(ia64_frob_file): New.

	* config/tc-ia64.h (struct ia64_segment_info_type): Add alias.
	(struct ia64_symfield_type): New.
	(TC_SYMFIELD_TYPE): Defined.
	(ia64_adjust_symtab): New.
	(tc_adjust_symtab): Defined.
	(ia64_frob_file): New.
	(tc_frob_file): Defined.

gas/testsuite/

2003-05-02  H.J. Lu <hjl@gnu.org>

	* gas/ia64/ia64.exp: Add alias.

	* gas/ia64/alias.s: New. 
	* gas/ia64/alias.d: Likewise.

--- gas/config/tc-ia64.c.alias	2003-05-01 08:59:32.000000000 -0700
+++ gas/config/tc-ia64.c	2003-05-02 16:50:11.000000000 -0700
@@ -24,7 +24,6 @@
 
   - optional operands
   - directives:
-	.alias
 	.eb
 	.estate
 	.lb
@@ -46,6 +45,7 @@
 #include "safe-ctype.h"
 #include "dwarf2dbg.h"
 #include "subsegs.h"
+#include "struc-symbol.h"
 
 #include "opcode/ia64.h"
 
@@ -165,6 +165,9 @@ static void ia64_float_to_chars_littleen
 static void (*ia64_float_to_chars)
   PARAMS ((char *, LITTLENUM_TYPE *, int));
 
+static struct hash_control *alias_hash;
+static struct hash_control *secalias_hash;
+
 /* Characters which always start a comment.  */
 const char comment_chars[] = "";
 
@@ -4386,13 +4389,6 @@ dot_psr (dummy)
 }
 
 static void
-dot_alias (dummy)
-     int dummy ATTRIBUTE_UNUSED;
-{
-  as_bad (".alias not implemented yet");
-}
-
-static void
 dot_ln (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
@@ -4937,6 +4933,7 @@ const pseudo_typeS md_pseudo_table[] =
     { "msb", dot_byteorder, 1 },
     { "psr", dot_psr, 0 },
     { "alias", dot_alias, 0 },
+    { "secalias", dot_alias, 1 },
     { "ln", dot_ln, 0 },		/* source line info (for debugging) */
 
     { "xdata1", dot_xdata, 1 },
@@ -6580,6 +6577,9 @@ md_begin ()
   target_big_endian = -1;
   dot_byteorder (TARGET_BYTES_BIG_ENDIAN);
 
+  alias_hash = hash_new ();
+  secalias_hash = hash_new ();
+
   pseudo_func[FUNC_DTP_MODULE].u.sym =
     symbol_new (".<dtpmod>", undefined_section, FUNC_DTP_MODULE,
 		&zero_address_frag);
@@ -10739,3 +10739,242 @@ ia64_check_label (symbolS *label)
       input_line_pointer++;
     }
 }
+
+struct alias
+{
+  enum { alias_sec, alias_symbol, alias_name } type;
+
+  union
+  {
+    symbolS *symbol;
+    segT sec;
+    struct
+    {
+      char *file;
+      unsigned int line;
+      const char *name;
+    } name;
+  } ptr;
+};
+
+static void
+dot_alias (int section)
+{
+  const char *name, *alias;
+  char delim;
+  char *end_name;
+  int len;
+  const char *error_string;
+
+  name = input_line_pointer;
+  delim = get_symbol_end ();
+  end_name = input_line_pointer;
+  *end_name = delim;
+
+  if (name == end_name)
+    {
+      as_bad (_("expected symbol name"));
+      discard_rest_of_line ();
+      return;
+    }
+
+  SKIP_WHITESPACE ();
+
+  if (*input_line_pointer != ',')
+    {
+      *end_name = 0;
+      as_bad (_("expected comma after \"%s\""), name);
+      *end_name = delim;
+      ignore_rest_of_line ();
+      return;
+    }
+
+  input_line_pointer++;
+  *end_name = 0;
+
+  alias = demand_copy_C_string (&len);
+  if (alias == NULL)
+    {
+      ignore_rest_of_line ();
+      return;
+    }
+
+  if (section)
+    {
+      segT sec;
+      struct alias *h;
+
+      h = (struct alias *) hash_find (secalias_hash, alias);
+      if (h)
+	{
+	  const char *oldname = h->type == alias_sec
+				? bfd_get_section_name (stdoutput,
+							h->ptr.sec)
+				: h->ptr.name.name;
+
+	  if (strcmp (oldname, name))
+	      as_bad (_("`%s' is already the alias of `%s'"),
+		      alias, oldname);
+	  goto out;
+	}
+
+      sec = bfd_get_section_by_name (stdoutput, name);
+      if (sec)
+	{
+	  /* We have seen the section before.  */
+	  segment_info_type *seginfo = seg_info (sec);
+	  if (seginfo->tc_segment_info_data.alias)
+	    {
+	      if (strcmp (seginfo->tc_segment_info_data.alias, alias))
+		as_bad (_("section `%s' already has an alias `%s'"),
+			bfd_get_section_name (stdoutput, sec),
+			seginfo->tc_segment_info_data.alias);
+	      goto out;
+	    }
+	  
+	  seginfo->tc_segment_info_data.alias = alias;
+	  h = (struct alias *) xmalloc (sizeof (struct alias));
+	  h->type = alias_sec;
+	  h->ptr.sec = sec;
+	}
+      else
+	{
+	  /* We create a secaliase before we see the section
+	     first.  */
+	  char *file;
+	  unsigned int line;
+
+	  h = (struct alias *) xmalloc (sizeof (struct alias));
+
+	  as_where (&file, &line);
+	  h->type = alias_name;
+	  h->ptr.name.name = name;
+	  h->ptr.name.file = file;
+	  h->ptr.name.line = line;
+	}
+
+	error_string = hash_jam (secalias_hash, alias, (PTR) h);
+	if (error_string)
+	  as_fatal (_("inserting \"%s\" into secalias table failed: %s"),
+		    alias, error_string);
+    }
+  else
+    {
+      symbolS *symbol;
+      struct alias *h;
+
+      h = (struct alias *) hash_find (alias_hash, alias);
+      if (h)
+	{
+	  const char *oldname = h->type == alias_symbol
+				? S_GET_NAME (h->ptr.symbol)
+				: h->ptr.name.name;
+
+	  if (strcmp (oldname, name))
+	    as_bad (_("`%s' is already the alias of `%s'"),
+		    alias, oldname);
+	  goto out;
+	}
+
+      symbol = symbol_find (name);
+      if (symbol)
+	{
+	  /* We have seen the symbol before.  */
+	  if (symbol->sy_tc.alias)
+	    {
+	      if (strcmp (symbol->sy_tc.alias, alias))
+		as_bad (_("symbol `%s' already has an alias `%s'"),
+			S_GET_NAME (symbol), symbol->sy_tc.alias);
+	      goto out;
+	    }
+	  
+	  symbol->sy_tc.alias = alias;
+	  h = (struct alias *) xmalloc (sizeof (struct alias));
+	  h->type = alias_symbol;
+	  h->ptr.symbol = symbol;
+	}
+      else
+	{
+	  /* We create an aliase before we see the symbol first.  */
+	  char *file;
+	  unsigned int line;
+
+	  h = (struct alias *) xmalloc (sizeof (struct alias));
+
+	  as_where (&file, &line);
+	  h->type = alias_name;
+	  h->ptr.name.name = name;
+	  h->ptr.name.file = file;
+	  h->ptr.name.line = line;
+	}
+
+      error_string = hash_jam (alias_hash, alias, (PTR) h);
+      if (error_string)
+	as_fatal (_("inserting \"%s\" into alias table failed: %s"),
+		  alias, error_string);
+    }
+
+out:
+  demand_empty_rest_of_line ();
+}
+
+static void
+do_alias (const char *alias, PTR value)
+{
+  struct alias *h = (struct alias *) value;
+  symbolS *sym;
+ 
+  if (h->type == alias_name)
+    {
+      sym = symbol_find (h->ptr.name.name);
+      if (sym == NULL)
+	as_warn_where (h->ptr.name.file, h->ptr.name.line,
+		       _("symbol `%s' aliased to `%s' is not used"),
+		       h->ptr.name.name, alias);
+      else
+	S_SET_NAME (sym, (char *) alias);
+    }
+  else
+    {
+      sym = h->ptr.symbol;
+      S_SET_NAME (sym, (char *) sym->sy_tc.alias);
+    }
+}
+
+void
+ia64_adjust_symtab (void)
+{
+  hash_traverse (alias_hash, do_alias);
+}
+
+static void
+do_secalias (const char *alias, PTR value)
+{
+  struct alias *h = (struct alias *) value;
+  segT sec;
+ 
+  if (h->type == alias_name)
+    {
+      sec = bfd_get_section_by_name (stdoutput, h->ptr.name.name);
+      if (sec == NULL)
+	as_warn_where (h->ptr.name.file, h->ptr.name.line,
+		       _("section `%s' aliased to `%s' is not used"),
+		       h->ptr.name.name, alias);
+      else
+	sec->name = alias;
+    }
+  else
+    {
+      segment_info_type *seginfo;
+
+      sec = h->ptr.sec;
+      seginfo = seg_info (h->ptr.sec);
+      sec->name = seginfo->tc_segment_info_data.alias;
+    }
+}
+
+void
+ia64_frob_file (void)
+{
+  hash_traverse (secalias_hash, do_secalias);
+}
--- gas/config/tc-ia64.h.alias	2003-05-01 08:59:32.000000000 -0700
+++ gas/config/tc-ia64.h	2003-05-02 14:48:04.000000000 -0700
@@ -44,10 +44,27 @@ extern void ia64_elf_section_change_hook
 struct ia64_segment_info_type
 {
   unsigned int endian : 2;
+
+  /* The name specified by the .secalias directive.  */
+  const char *alias;
 };
 
 #define TC_SEGMENT_INFO_TYPE		struct ia64_segment_info_type
 
+struct ia64_symfield_type
+{
+  /* The name specified by the .alias directive.  */
+  const char *alias;
+};
+
+#define TC_SYMFIELD_TYPE		struct ia64_symfield_type
+
+extern void ia64_adjust_symtab PARAMS ((void));
+#define tc_adjust_symtab()	ia64_adjust_symtab ()
+
+extern void ia64_frob_file PARAMS ((void));
+#define tc_frob_file()		ia64_frob_file ()
+
 /* We need to set the default object file format in ia64_init and not in
    md_begin.  This is because parse_args is called before md_begin, and we
    do not want md_begin to wipe out the flag settings set by options parsed in
--- gas/testsuite/gas/ia64/alias.d.alias	2003-05-02 16:29:20.000000000 -0700
+++ gas/testsuite/gas/ia64/alias.d	2003-05-02 16:46:36.000000000 -0700
@@ -0,0 +1,37 @@
+#readelf: -Ss
+#name: ia64 alias and secalias
+
+There are 8 section headers, starting at offset 0x78:
+
+Section Headers:
+  \[Nr\] Name              Type             Address           Offset
+       Size              EntSize          Flags  Link  Info  Align
+  \[ 0\]                   NULL             0000000000000000  00000000
+       0000000000000000  0000000000000000           0     0     0
+  \[ 1\] \.text             PROGBITS         0000000000000000  00000040
+       0000000000000000  0000000000000000  AX       0     0     16
+  \[ 2\] \.data             PROGBITS         0000000000000000  00000040
+       0000000000000000  0000000000000000  WA       0     0     1
+  \[ 3\] \.bss              NOBITS           0000000000000000  00000040
+       0000000000000000  0000000000000000  WA       0     0     1
+  \[ 4\] 1234              PROGBITS         0000000000000000  00000040
+       0000000000000005  0000000000000000  WA       0     0     1
+  \[ 5\] \.shstrtab         STRTAB           0000000000000000  00000045
+       0000000000000031  0000000000000000           0     0     1
+  \[ 6\] \.symtab           SYMTAB           0000000000000000  00000278
+       0000000000000090  0000000000000018           7     6     8
+  \[ 7\] \.strtab           STRTAB           0000000000000000  00000308
+       0000000000000006  0000000000000000           0     0     1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\)
+  I \(info\), L \(link order\), G \(group\), x \(unknown\)
+  O \(extra OS processing required) o \(OS specific\), p \(processor specific\)
+
+Symbol table '\.symtab' contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
+     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
+     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
+     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
+     5: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    4 "@D"
--- gas/testsuite/gas/ia64/alias.s.alias	2003-05-02 16:29:23.000000000 -0700
+++ gas/testsuite/gas/ia64/alias.s	2003-05-02 16:40:52.000000000 -0700
@@ -0,0 +1,11 @@
+	.section .foo,"aw","progbits"
+	.secalias .foo,"1234"
+	.secalias .foo,"1234"
+	.alias foo, "\"\80\84\""
+	.alias foo, "\"\80\84\""
+foo:
+	.asciz "\"\80\84\""
+	.secalias .foo,"1234"
+	.secalias .foo,"1234"
+	.alias foo, "\"\80\84\""
+	.alias foo, "\"\80\84\""
--- gas/testsuite/gas/ia64/ia64.exp.alias	2003-05-01 08:59:32.000000000 -0700
+++ gas/testsuite/gas/ia64/ia64.exp	2003-05-02 16:42:49.000000000 -0700
@@ -48,4 +48,5 @@ if [istarget "ia64-*"] then {
     run_dump_test "unwind"
     run_dump_test "secname"
     run_dump_test "global"
+    run_dump_test "alias"
 }


More information about the Binutils mailing list