diff options
author | Alan Modra <amodra@gmail.com> | 2020-08-22 17:59:57 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-08-23 21:38:05 +0930 |
commit | fe0e921f00237abd926cd9efaeedf758b17170de (patch) | |
tree | eb20c7e2834f06e114323d816077d4c99884a3ab /gas/macro.c | |
parent | b8fff44e0e2e43e1823413eec7c5f6fa9d219ce7 (diff) | |
download | gdb-fe0e921f00237abd926cd9efaeedf758b17170de.zip gdb-fe0e921f00237abd926cd9efaeedf758b17170de.tar.gz 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/macro.c')
-rw-r--r-- | gas/macro.c | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/gas/macro.c b/gas/macro.c index d99430e..3123ddf 100644 --- a/gas/macro.c +++ b/gas/macro.c @@ -505,6 +505,7 @@ do_formals (macro_entry *macro, size_t idx, sb *in) { formal_entry *formal = new_formal (); size_t cidx; + formal_hash_entry_t *elt; idx = get_token (idx, in, &formal->name); if (formal->name.len == 0) @@ -567,14 +568,15 @@ do_formals (macro_entry *macro, size_t idx, sb *in) } /* Add to macro's hash table. */ - if (formal_entry_find (macro->formal_hash, name) == NULL) - htab_insert (macro->formal_hash, formal_entry_alloc (name, formal)); - else - as_bad_where (macro->file, - macro->line, - _("A parameter named `%s' already exists for macro `%s'"), - name, - macro->name); + elt = formal_entry_alloc (name, formal); + if (htab_insert (macro->formal_hash, elt, 0) != NULL) + { + free (elt); + as_bad_where (macro->file, macro->line, + _("A parameter named `%s' " + "already exists for macro `%s'"), + name, macro->name); + } formal->index = macro->formal_count++; *p = formal; @@ -593,6 +595,7 @@ do_formals (macro_entry *macro, size_t idx, sb *in) if (macro_mri) { formal_entry *formal = new_formal (); + formal_hash_entry_t *elt; /* Add a special NARG formal, which macro_expand will set to the number of arguments. */ @@ -606,13 +609,14 @@ do_formals (macro_entry *macro, size_t idx, sb *in) sb_add_string (&formal->name, name); /* Add to macro's hash table. */ - if (formal_entry_find (macro->formal_hash, name)) - as_bad_where (macro->file, - macro->line, - _("Reserved word `%s' used as parameter in macro `%s'"), - name, - macro->name); - htab_insert (macro->formal_hash, formal_entry_alloc (name, formal)); + elt = formal_entry_alloc (name, formal); + if (htab_insert (macro->formal_hash, elt, 0) != NULL) + { + free (elt); + as_bad_where (macro->file, macro->line, + _("Reserved word `%s' used as parameter in macro `%s'"), + name, macro->name); + } formal->index = NARG_INDEX; *p = formal; @@ -709,10 +713,15 @@ define_macro (size_t idx, sb *in, sb *label, /* And stick it in the macro hash table. */ for (idx = 0; idx < name.len; idx++) name.ptr[idx] = TOLOWER (name.ptr[idx]); - if (macro_entry_find (macro_hash, macro->name)) - error = _("Macro `%s' was already defined"); if (!error) - htab_insert (macro_hash, macro_entry_alloc (macro->name, macro)); + { + macro_hash_entry_t *elt = macro_entry_alloc (macro->name, macro); + if (htab_insert (macro_hash, elt, 0) != NULL) + { + free (elt); + error = _("Macro `%s' was already defined"); + } + } if (namep != NULL) *namep = macro->name; @@ -911,10 +920,20 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, { const char *name; formal_entry *f = new_formal (); + formal_hash_entry_t *elt; src = get_token (src, in, &f->name); name = sb_terminate (&f->name); - if (formal_entry_find (formal_hash, name) == NULL) + elt = formal_entry_alloc (name, f); + if (htab_insert (formal_hash, elt, 0) != NULL) + { + free (elt); + as_bad_where (macro->file, macro->line + macro_line, + _("`%s' was already used as parameter " + "(or another local) name"), name); + del_formal (f); + } + else { static int loccnt; char buf[20]; @@ -925,16 +944,6 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt); sb_add_string (&f->actual, buf); - - htab_insert (formal_hash, formal_entry_alloc (name, f)); - } - else - { - as_bad_where (macro->file, - macro->line + macro_line, - _("`%s' was already used as parameter (or another local) name"), - name); - del_formal (f); } src = sb_skip_comma (src, in); @@ -1284,7 +1293,8 @@ delete_macro (const char *name) { char *copy; size_t i, len; - macro_entry *macro; + void **slot; + macro_hash_entry_t needle; len = strlen (name); copy = XNEWVEC (char, len + 1); @@ -1292,17 +1302,17 @@ delete_macro (const char *name) copy[i] = TOLOWER (name[i]); copy[i] = '\0'; - /* We can only ask hash_delete to free memory if we are deleting - macros in reverse order to their definition. - So just clear out the entry. */ - macro = macro_entry_find (macro_hash, copy); - if (macro) + needle.name = copy; + needle.macro = NULL; + slot = htab_find_slot (macro_hash, &needle, NO_INSERT); + if (slot) { - htab_insert (macro_hash, macro_entry_alloc (copy, NULL)); - free_macro (macro); + free_macro (((macro_hash_entry_t *) *slot)->macro); + htab_clear_slot (macro_hash, slot); } else as_warn (_("Attempt to purge non-existing macro `%s'"), copy); + free (copy); } /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a @@ -1334,7 +1344,7 @@ expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *)) h = htab_create_alloc (16, hash_formal_entry, eq_formal_entry, NULL, xcalloc, free); - htab_insert (h, formal_entry_alloc (sb_terminate (&f.name), &f)); + htab_insert (h, formal_entry_alloc (sb_terminate (&f.name), &f), 0); f.index = 1; f.next = NULL; |