diff options
-rw-r--r-- | gas/ChangeLog | 21 | ||||
-rw-r--r-- | gas/config/tc-ia64.c | 185 | ||||
-rw-r--r-- | gas/config/tc-ia64.h | 6 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/alias.d | 37 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/alias.s | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/ia64.exp | 1 |
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 (¬es, name, len); + name = obstack_finish (¬es); + + 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 (¬es, name); + obstack_free (¬es, 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" } |