aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-tic54x.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-08-22 17:59:57 +0930
committerAlan Modra <amodra@gmail.com>2020-08-23 21:38:05 +0930
commitfe0e921f00237abd926cd9efaeedf758b17170de (patch)
treeeb20c7e2834f06e114323d816077d4c99884a3ab /gas/config/tc-tic54x.c
parentb8fff44e0e2e43e1823413eec7c5f6fa9d219ce7 (diff)
downloadfsf-binutils-gdb-fe0e921f00237abd926cd9efaeedf758b17170de.zip
fsf-binutils-gdb-fe0e921f00237abd926cd9efaeedf758b17170de.tar.gz
fsf-binutils-gdb-fe0e921f00237abd926cd9efaeedf758b17170de.tar.bz2
PR26513, 629310abec breaks assembling PowerPC Linux kernels
Inserting with replacement is wrong for some gas hash table uses. This patch implements an htab_insert that conditionally replaces, and similarly for str_hash_insert. str_hash_insert with replace=0 is roughly equivalent to the older hash_insert, and str_hash_insert with replace=1 to the older hash_jam, but return values are different. I found it useful to know whether the slot was occupied prior to inserting/replacing. I've also reinstated the fatal errors on messing up opcode tables with duplicates. PR 26513 * hash.h (htab_insert): Update prototype and comment. (struct string_tuple): Make "value" a const void*. (string_tuple_alloc): Likewise. (str_hash_find, str_hash_find_n): Cast returned value. (str_hash_insert): Add "replace" parameter, and return slot pointer. Free alloc'd element when not inserted. * hash.c (htab_insert): Likewise. Return slot when element exists, otherwise return NULL. * read.c (pop_insert): Insert into hash table without first searching. * config/tc-avr.c (md_begin): Likewise. * config/tc-msp430.c (md_begin): Likewise. * config/tc-nds32.c (nds32_init_nds32_pseudo_opcodes): Likewise. * config/tc-v850.c (md_begin): Likewise. * macro.c (do_formals, define_macro, macro_expand_body): Likewise. (delete_macro): Delete from hash table. * config/tc-tic54x.c (subsym_create_or_replace): Correct logic. * symbols.c (local_symbol_make, symbol_table_insert): Allow replacement of hash table entries. * config/obj-coff-seh.c (seh_hash_insert): Likewise. * config/obj-coff.c (tag_insert): Likewise. * config/tc-iq2000.c (iq2000_add_macro): Likewise. * config/tc-m68k.c (md_begin): Likewise for aliases. * config/tc-tic4x.c (tic4x_asg): Likewise. * config/tc-tic6x.c (md_begin): Likewise. * dw2gencfi.c (dwcfi_hash_find_or_make): Disallow replacement of hash table entries. * ecoff.c (add_string, get_tag): Likewise. * macro.c (expand_irp): Likewise. * config/obj-elf.c (build_additional_section_info): Likewise. * config/tc-aarch64.c (insert_reg_alias): Likewise. (checked_hash_insert): Likewise. * config/tc-alpha.c (get_alpha_reloc_tag, md_begin): Likewise. * config/tc-arc.c (arc_insert_opcode, declare_register): Likewise. (declare_addrtype, md_begin, arc_extcorereg): Likewise. * config/tc-arm.c (insert_reg_alias): Likewise. (arm_tc_equal_in_insn, md_begin): Likewise. * config/tc-cr16.c (initialise_reg_hash_table, md_begin): Likewise. * config/tc-cris.c (md_begin): Likewise. * config/tc-crx.c (md_begin): Likewise. * config/tc-csky.c (md_begin): Likewise. * config/tc-d10v.c (md_begin): Likewise. * config/tc-dlx.c (md_begin): Likewise. * config/tc-ft32.c (md_begin): Likewise. * config/tc-h8300.c (md_begin): Likewise. * config/tc-hppa.c (md_begin): Likewise. * config/tc-i386.c (md_begin): Likewise. * config/tc-ia64.c (dot_rot, dot_entry, declare_register): Likewise. (md_begin, dot_alias): Likewise. * config/tc-m68hc11.c (md_begin): Likewise. * config/tc-m68k.c (md_begin): Likewise. * config/tc-mcore.c (md_begin): Likewise. * config/tc-microblaze.c (md_begin): Likewise. * config/tc-mips.c (md_begin): Likewise. * config/tc-mmix.c (md_begin): Likewise. * config/tc-mn10200.c (md_begin): Likewise. * config/tc-mn10300.c (md_begin): Likewise. * config/tc-moxie.c (md_begin): Likewise. * config/tc-nds32.c (nds32_relax_hint, md_begin): Likewise. * config/tc-nios2.c (md_begin): Likewise. * config/tc-ns32k.c (md_begin): Likewise. * config/tc-pdp11.c (md_begin): Likewise. * config/tc-pj.c (fake_opcode, md_begin): Likewise. * config/tc-ppc.c (ppc_setup_opcodes): Likewise. * config/tc-pru.c (md_begin): Likewise. * config/tc-riscv.c (init_ext_version_hash): Likewise. (init_opcode_names_hash, hash_reg_name, init_opcode_hash): Likewise. (riscv_init_csr_hash): Likewise. * config/tc-s390.c (s390_setup_opcodes, md_begin): Likewise. * config/tc-score.c (s3_insert_reg): Likewise. (s3_build_score_ops_hsh, s3_build_dependency_insn_hsh): Likewise. * config/tc-score7.c (s7_build_score_ops_hsh): Likewise. (s7_build_dependency_insn_hsh, s7_insert_reg): Likewise. * config/tc-sh.c (md_begin): Likewise. * config/tc-sparc.c (md_begin): Likewise. * config/tc-spu.c (md_begin): Likewise. * config/tc-tic30.c (md_begin): Likewise. * config/tc-tic4x.c (tic4x_inst_insert): Likewise. * config/tc-tic54x.c (stag_add_field_symbols, md_begin): Likewise. (tic54x_endstruct, tic54x_var, tic54x_macro_info): Likewise. (subsym_substitute): Likewise. * config/tc-tilegx.c (md_begin): Likewise. * config/tc-tilepro.c (md_begin): Likewise. * config/tc-vax.c (vip_begin): Likewise. * config/tc-wasm32.c (md_begin): Likewise. * config/tc-xgate.c (md_begin): Likewise. * config/tc-z8k.c (md_begin): Likewise. * testsuite/gas/ppc/dcbt.d, * testsuite/gas/ppc/dcbt.s: New test. * testsuite/gas/ppc/ppc.exp: Run it. * ecoff.c (add_string): Report fatal error on duplicates. * config/tc-alpha.c (md_begin): Likewise. * config/tc-arc.c (arc_insert_opcode, declare_register): Likewise. (declare_addrtype, md_begin, arc_extcorereg): Likewise. * config/tc-cr16.c (initialise_reg_hash_table, md_begin): Likewise. * config/tc-cris.c (md_begin): Likewise. * config/tc-crx.c (md_begin): Likewise. * config/tc-dlx.c (md_begin): Likewise. * config/tc-hppa.c (md_begin): Likewise. * config/tc-i386.c (md_begin): Likewise. * config/tc-ia64.c (dot_rot, dot_entry, declare_register): Likewise. (md_begin): Likewise. * config/tc-m68k.c (md_begin): Likewise. * config/tc-mips.c (md_begin): Likewise. * config/tc-nios2.c (md_begin): Likewise. * config/tc-ns32k.c (md_begin): Likewise. * config/tc-ppc.c (ppc_setup_opcodes): Likewise. * config/tc-pru.c (md_begin): Likewise. * config/tc-riscv.c (init_ext_version_hash): Likewise. (init_opcode_names_hash, hash_reg_name, init_opcode_hash): Likewise. * config/tc-s390.c (s390_setup_opcodes, md_begin): Likewise. * config/tc-sparc.c (md_begin): Likewise. * config/tc-tic30.c (md_begin): Likewise. * config/tc-tic4x.c (tic4x_inst_insert): Likewise. * config/tc-tilegx.c (md_begin): Likewise. * config/tc-tilepro.c (md_begin): Likewise. * config/tc-vax.c (vip_begin): Likewise. * config/tc-alpha.c, * config/tc-arm.c, * config/tc-avr.c, * config/tc-cr16.c, * config/tc-csky.c, * config/tc-i386.c, * config/tc-m68hc11.c, * config/tc-m68k.c, * config/tc-microblaze.c, * config/tc-ns32k.c, * config/tc-pj.c, * config/tc-ppc.c, * config/tc-score.c, * config/tc-score7.c, * config/tc-tic4x.c, * config/tc-tic54x.c, * config/tc-tilegx.c, * config/tc-tilepro.c, * config/tc-xgate.c: Formatting.
Diffstat (limited to 'gas/config/tc-tic54x.c')
-rw-r--r--gas/config/tc-tic54x.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/gas/config/tc-tic54x.c b/gas/config/tc-tic54x.c
index 6412d38..62d49d9 100644
--- a/gas/config/tc-tic54x.c
+++ b/gas/config/tc-tic54x.c
@@ -567,7 +567,7 @@ stag_add_field_symbols (struct stag *stag,
replacement = concat (S_GET_NAME (rootsym), "+", root_stag_name,
name + strlen (S_GET_NAME (rootsym)), NULL);
- str_hash_insert (subsym_hash[0], name, replacement);
+ str_hash_insert (subsym_hash[0], name, replacement, 0);
}
/* Recurse if the field is a structure.
@@ -738,7 +738,7 @@ tic54x_endstruct (int is_union)
/* Nested .structs don't get put in the stag table. */
if (current_stag->outer == NULL)
{
- str_hash_insert (stag_hash, current_stag->name, current_stag);
+ str_hash_insert (stag_hash, current_stag->name, current_stag, 0);
stag_add_field_symbols (current_stag, path,
S_GET_VALUE (current_stag->sym),
NULL, NULL);
@@ -2236,7 +2236,7 @@ tic54x_var (int ignore ATTRIBUTE_UNUSED)
c = get_symbol_name (&name);
/* .var symbols start out with a null string. */
name = xstrdup (name);
- str_hash_insert (subsym_hash[macro_level], name, empty);
+ str_hash_insert (subsym_hash[macro_level], name, empty, 0);
c = restore_line_pointer (c);
if (c == ',')
{
@@ -2521,7 +2521,7 @@ tic54x_macro_info (const macro_entry *macro)
name[entry->name.len] = '\0';
value[entry->actual.len] = '\0';
- str_hash_insert (subsym_hash[macro_level], name, value);
+ str_hash_insert (subsym_hash[macro_level], name, value, 0);
}
}
@@ -2991,18 +2991,12 @@ md_begin (void)
op_hash = str_htab_create ();
for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
- {
- if (str_hash_find (op_hash, tm->name))
- continue;
- str_hash_insert (op_hash, tm->name, (char *) tm);
- }
+ str_hash_insert (op_hash, tm->name, tm, 0);
+
parop_hash = str_htab_create ();
for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
- {
- if (str_hash_find (parop_hash, tm->name))
- continue;
- str_hash_insert (parop_hash, tm->name, (char *) tm);
- }
+ str_hash_insert (parop_hash, tm->name, tm, 0);
+
reg_hash = str_htab_create ();
for (sym = (tic54x_symbol *) regs; sym->name; sym++)
{
@@ -3011,51 +3005,48 @@ md_begin (void)
&zero_address_frag, sym->value);
SF_SET_LOCAL (symbolP);
symbol_table_insert (symbolP);
- str_hash_insert (reg_hash, sym->name, (char *) sym);
+ str_hash_insert (reg_hash, sym->name, sym, 0);
}
for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
- str_hash_insert (reg_hash, sym->name, (char *) sym);
+ str_hash_insert (reg_hash, sym->name, sym, 0);
mmreg_hash = str_htab_create ();
for (sym = (tic54x_symbol *) mmregs; sym->name; sym++)
- str_hash_insert (mmreg_hash, sym->name, (char *) sym);
+ str_hash_insert (mmreg_hash, sym->name, sym, 0);
cc_hash = str_htab_create ();
for (sym = (tic54x_symbol *) condition_codes; sym->name; sym++)
- str_hash_insert (cc_hash, sym->name, (char *) sym);
+ str_hash_insert (cc_hash, sym->name, sym, 0);
cc2_hash = str_htab_create ();
for (sym = (tic54x_symbol *) cc2_codes; sym->name; sym++)
- str_hash_insert (cc2_hash, sym->name, (char *) sym);
+ str_hash_insert (cc2_hash, sym->name, sym, 0);
cc3_hash = str_htab_create ();
for (sym = (tic54x_symbol *) cc3_codes; sym->name; sym++)
- str_hash_insert (cc3_hash, sym->name, (char *) sym);
+ str_hash_insert (cc3_hash, sym->name, sym, 0);
sbit_hash = str_htab_create ();
for (sym = (tic54x_symbol *) status_bits; sym->name; sym++)
- str_hash_insert (sbit_hash, sym->name, (char *) sym);
+ str_hash_insert (sbit_hash, sym->name, sym, 0);
misc_symbol_hash = str_htab_create ();
for (symname = (char **) misc_symbols; *symname; symname++)
- str_hash_insert (misc_symbol_hash, *symname, *symname);
+ str_hash_insert (misc_symbol_hash, *symname, *symname, 0);
/* Only the base substitution table and local label table are initialized;
the others (for local macro substitution) get instantiated as needed. */
local_label_hash[0] = str_htab_create ();
subsym_hash[0] = str_htab_create ();
for (subsym_proc = subsym_procs; subsym_proc->name; subsym_proc++)
- str_hash_insert (subsym_hash[0], subsym_proc->name,
- (char *) subsym_proc);
+ str_hash_insert (subsym_hash[0], subsym_proc->name, subsym_proc, 0);
math_hash = str_htab_create ();
for (math_proc = math_procs; math_proc->name; math_proc++)
{
/* Insert into the main subsym hash for recognition; insert into
the math hash to actually store information. */
- str_hash_insert (subsym_hash[0], math_proc->name,
- (char *) math_proc);
- str_hash_insert (math_hash, math_proc->name,
- (char *) math_proc);
+ str_hash_insert (subsym_hash[0], math_proc->name, math_proc, 0);
+ str_hash_insert (math_hash, math_proc->name, math_proc, 0);
}
subsym_recurse_hash = str_htab_create ();
stag_hash = str_htab_create ();
@@ -4170,7 +4161,7 @@ tic54x_parse_insn (tic54x_insn *insn, char *line)
if (optimize_insn (insn))
{
insn->tm = (insn_template *) str_hash_find (op_hash,
- insn->mnemonic);
+ insn->mnemonic);
continue;
}
@@ -4335,8 +4326,12 @@ subsym_create_or_replace (char *name, char *value)
int i;
for (i = macro_level; i > 0; i--)
- str_hash_insert (subsym_hash[i], name, value);
- str_hash_insert (subsym_hash[0], name, value);
+ if (str_hash_find (subsym_hash[i], name))
+ {
+ str_hash_insert (subsym_hash[i], name, value, 1);
+ return;
+ }
+ str_hash_insert (subsym_hash[0], name, value, 1);
}
/* Look up the substitution string replacement for the given symbol.
@@ -4495,7 +4490,8 @@ subsym_substitute (char *line, int forced)
value[strlen (value) - 1] = '\0';
sprintf (digit, ".%d", local_label_id++);
strcat (value, digit);
- str_hash_insert (local_label_hash[macro_level], namecopy, value);
+ str_hash_insert (local_label_hash[macro_level],
+ namecopy, value, 0);
}
/* Indicate where to continue looking for substitutions. */
ptr = tail;
@@ -4616,7 +4612,7 @@ subsym_substitute (char *line, int forced)
try to replace a symbol once. */
if (recurse)
{
- str_hash_insert (subsym_recurse_hash, name, name);
+ str_hash_insert (subsym_recurse_hash, name, name, 0);
value = subsym_substitute (value, macro_level > 0);
str_hash_delete (subsym_recurse_hash, name);
}
@@ -5007,18 +5003,20 @@ tic54x_undefined_symbol (char *name)
tic54x_symbol *sym;
/* Not sure how to handle predefined symbols. */
- if ((sym = (tic54x_symbol *) str_hash_find (cc_hash, name)) != NULL ||
- (sym = (tic54x_symbol *) str_hash_find (cc2_hash, name)) != NULL ||
- (sym = (tic54x_symbol *) str_hash_find (cc3_hash, name)) != NULL ||
- (sym = (tic54x_symbol *) str_hash_find (misc_symbol_hash, name)) != NULL ||
- (sym = (tic54x_symbol *) str_hash_find (sbit_hash, name)) != NULL)
+ if ((sym = (tic54x_symbol *) str_hash_find (cc_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (cc2_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (cc3_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (misc_symbol_hash,
+ name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (sbit_hash, name)) != NULL)
{
return symbol_new (name, reg_section, &zero_address_frag, sym->value);
}
- if ((sym = (tic54x_symbol *) str_hash_find (reg_hash, name)) != NULL ||
- (sym = (tic54x_symbol *) str_hash_find (mmreg_hash, name)) != NULL ||
- !strcasecmp (name, "a") || !strcasecmp (name, "b"))
+ if ((sym = (tic54x_symbol *) str_hash_find (reg_hash, name)) != NULL
+ || (sym = (tic54x_symbol *) str_hash_find (mmreg_hash, name)) != NULL
+ || !strcasecmp (name, "a")
+ || !strcasecmp (name, "b"))
{
return symbol_new (name, reg_section, &zero_address_frag,
sym ? sym->value : 0);