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