aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog21
-rw-r--r--gas/config/tc-ia64.c185
-rw-r--r--gas/config/tc-ia64.h6
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/ia64/alias.d37
-rw-r--r--gas/testsuite/gas/ia64/alias.s11
-rw-r--r--gas/testsuite/gas/ia64/ia64.exp1
7 files changed, 260 insertions, 8 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a456e4e..ba00123 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,24 @@
+2003-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/tc-ia64.c (alias_hash): New.
+ (alias_name_hash): New.
+ (secalias_hash): New.
+ (secalias_name_hash): New.
+ (md_pseudo_table): Add "secalias".
+ (md_begin): Initialize alias_hash, alias_name_hash,
+ secalias_hash and secalias_name_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 (ia64_adjust_symtab): New.
+ (tc_adjust_symtab): Defined.
+ (ia64_frob_file): New.
+ (tc_frob_file): Defined.
+
2003-05-07 Dmitry Diky <diwil@mail.ru>
* tc-msp430.c: Add missing lines to known cpus list.
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index eacf471..9be19b9 100644
--- a/gas/config/tc-ia64.c
+++ b/gas/config/tc-ia64.c
@@ -24,7 +24,6 @@
- optional operands
- directives:
- .alias
.eb
.estate
.lb
@@ -165,6 +164,11 @@ static void ia64_float_to_chars_littleendian
static void (*ia64_float_to_chars)
PARAMS ((char *, LITTLENUM_TYPE *, int));
+static struct hash_control *alias_hash;
+static struct hash_control *alias_name_hash;
+static struct hash_control *secalias_hash;
+static struct hash_control *secalias_name_hash;
+
/* Characters which always start a comment. */
const char comment_chars[] = "";
@@ -4384,13 +4388,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;
{
@@ -4935,6 +4932,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 },
@@ -6578,6 +6576,11 @@ md_begin ()
target_big_endian = -1;
dot_byteorder (TARGET_BYTES_BIG_ENDIAN);
+ alias_hash = hash_new ();
+ alias_name_hash = hash_new ();
+ secalias_hash = hash_new ();
+ secalias_name_hash = hash_new ();
+
pseudo_func[FUNC_DTP_MODULE].u.sym =
symbol_new (".<dtpmod>", undefined_section, FUNC_DTP_MODULE,
&zero_address_frag);
@@ -10737,3 +10740,169 @@ ia64_check_label (symbolS *label)
input_line_pointer++;
}
}
+
+/* Used to remember where .alias and .secalias directives are seen. We
+ will rename symbol and section names when we are about to output
+ the relocatable file. */
+struct alias
+{
+ char *file; /* The file where the directive is seen. */
+ unsigned int line; /* The line number the directive is at. */
+ const char *name; /* The orignale name of the symbol. */
+};
+
+/* Called for .alias and .secalias directives. If SECTION is 1, it is
+ .secalias. Otherwise, it is .alias. */
+static void
+dot_alias (int section)
+{
+ char *name, *alias;
+ char delim;
+ char *end_name;
+ int len;
+ const char *error_string;
+ struct alias *h;
+ const char *a;
+ struct hash_control *ahash, *nhash;
+ const char *kind;
+
+ 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;
+
+ /* We call demand_copy_C_string to check if alias string is valid.
+ There should be a closing `"' and no `\0' in the string. */
+ alias = demand_copy_C_string (&len);
+ if (alias == NULL)
+ {
+ ignore_rest_of_line ();
+ return;
+ }
+
+ /* Make a copy of name string. */
+ len = strlen (name) + 1;
+ obstack_grow (&notes, name, len);
+ name = obstack_finish (&notes);
+
+ if (section)
+ {
+ kind = "section";
+ ahash = secalias_hash;
+ nhash = secalias_name_hash;
+ }
+ else
+ {
+ kind = "symbol";
+ ahash = alias_hash;
+ nhash = alias_name_hash;
+ }
+
+ /* Check if alias has been used before. */
+ h = (struct alias *) hash_find (ahash, alias);
+ if (h)
+ {
+ if (strcmp (h->name, name))
+ as_bad (_("`%s' is already the alias of %s `%s'"),
+ alias, kind, h->name);
+ goto out;
+ }
+
+ /* Check if name already has an alias. */
+ a = (const char *) hash_find (nhash, name);
+ if (a)
+ {
+ if (strcmp (a, alias))
+ as_bad (_("%s `%s' already has an alias `%s'"), kind, name, a);
+ goto out;
+ }
+
+ h = (struct alias *) xmalloc (sizeof (struct alias));
+ as_where (&h->file, &h->line);
+ h->name = name;
+
+ error_string = hash_jam (ahash, alias, (PTR) h);
+ if (error_string)
+ {
+ as_fatal (_("inserting \"%s\" into %s alias hash table failed: %s"),
+ alias, kind, error_string);
+ goto out;
+ }
+
+ error_string = hash_jam (nhash, name, (PTR) alias);
+ if (error_string)
+ {
+ as_fatal (_("inserting \"%s\" into %s name hash table failed: %s"),
+ alias, kind, error_string);
+out:
+ obstack_free (&notes, name);
+ obstack_free (&notes, alias);
+ }
+
+ demand_empty_rest_of_line ();
+}
+
+/* It renames the original symbol name to its alias. */
+static void
+do_alias (const char *alias, PTR value)
+{
+ struct alias *h = (struct alias *) value;
+ symbolS *sym = symbol_find (h->name);
+
+ if (sym == NULL)
+ as_warn_where (h->file, h->line,
+ _("symbol `%s' aliased to `%s' is not used"),
+ h->name, alias);
+ else
+ S_SET_NAME (sym, (char *) alias);
+}
+
+/* Called from write_object_file. */
+void
+ia64_adjust_symtab (void)
+{
+ hash_traverse (alias_hash, do_alias);
+}
+
+/* It renames the original section name to its alias. */
+static void
+do_secalias (const char *alias, PTR value)
+{
+ struct alias *h = (struct alias *) value;
+ segT sec = bfd_get_section_by_name (stdoutput, h->name);
+
+ if (sec == NULL)
+ as_warn_where (h->file, h->line,
+ _("section `%s' aliased to `%s' is not used"),
+ h->name, alias);
+ else
+ sec->name = alias;
+}
+
+/* Called from write_object_file. */
+void
+ia64_frob_file (void)
+{
+ hash_traverse (secalias_hash, do_secalias);
+}
diff --git a/gas/config/tc-ia64.h b/gas/config/tc-ia64.h
index 20940c0..884bfb7 100644
--- a/gas/config/tc-ia64.h
+++ b/gas/config/tc-ia64.h
@@ -48,6 +48,12 @@ struct ia64_segment_info_type
#define TC_SEGMENT_INFO_TYPE struct ia64_segment_info_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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index da94a1d..8baa6cd 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2003-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gas/ia64/ia64.exp: Add alias.
+
+ * gas/ia64/alias.s: New.
+ * gas/ia64/alias.d: Likewise.
+
2003-05-06 Alexandre Oliva <aoliva@redhat.com>
* gas/mips/abs.d, gas/mips/add.d, gas/mips/and.d,
diff --git a/gas/testsuite/gas/ia64/alias.d b/gas/testsuite/gas/ia64/alias.d
new file mode 100644
index 0000000..c943b3a
--- /dev/null
+++ b/gas/testsuite/gas/ia64/alias.d
@@ -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"
diff --git a/gas/testsuite/gas/ia64/alias.s b/gas/testsuite/gas/ia64/alias.s
new file mode 100644
index 0000000..9ac1801
--- /dev/null
+++ b/gas/testsuite/gas/ia64/alias.s
@@ -0,0 +1,11 @@
+ .section .foo,"aw","progbits"
+ .secalias .foo,"1234"
+ .secalias .foo,"1234"
+ .alias foo, "\"\80\84\""
+ .alias foo, "\"\80\84\""
+foo:
+ stringz "\"\80\84\""
+ .secalias .foo,"1234"
+ .secalias .foo,"1234"
+ .alias foo, "\"\80\84\""
+ .alias foo, "\"\80\84\""
diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp
index 4597ca1..967de12 100644
--- a/gas/testsuite/gas/ia64/ia64.exp
+++ b/gas/testsuite/gas/ia64/ia64.exp
@@ -48,4 +48,5 @@ if [istarget "ia64-*"] then {
run_dump_test "global"
run_dump_test "secname"
run_dump_test "unwind"
+ run_dump_test "alias"
}