aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2003-05-07 19:31:10 +0000
committerH.J. Lu <hjl.tools@gmail.com>2003-05-07 19:31:10 +0000
commit35f5df7fe8004e03e2d9ae4b8de5186562e8caca (patch)
tree8e4b6de60d7864dab094433f5ed39afd3b81edd0 /gas/config
parentf6684c317073868d91f0659501fe08215784ab9d (diff)
downloadgdb-35f5df7fe8004e03e2d9ae4b8de5186562e8caca.zip
gdb-35f5df7fe8004e03e2d9ae4b8de5186562e8caca.tar.gz
gdb-35f5df7fe8004e03e2d9ae4b8de5186562e8caca.tar.bz2
gas/
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. gas/testsuite/ 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.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-ia64.c185
-rw-r--r--gas/config/tc-ia64.h6
2 files changed, 183 insertions, 8 deletions
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