mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
gas macro memory leaks
This tidies memory allocated for entries in macro_hash. Freeing the macro name requires a little restructuring of the define_macro interface due to the name being used in the error message, and exposed the fact that the name and other fields were not initialised by the iq2000 backend. There is also a fix for .macro .macro .endm .macro .macro .endm which prior to this patch reported mac.s:1: Warning: attempt to redefine pseudo-op `.macro' ignored mac.s:3: Error: Macro `.macro' was already defined rather than reporting the attempt to redefine twice. * macro.c (macro_del_f): New function. (macro_init): Use it when creating macro_hash. (free_macro): Free macro name too. (define_macro): Return the macro_entry, remove idx, file, line and namep params. Call as_where. Report errors here. Delete macro from macro_hash on attempt to redefined pseudo-op. (delete_macro): Don't call free_macro. * macro.h (define_macro): Update prototype. * read.c (s_macro): Adjust to suit. * config/tc-iq2000.c (iq2000_add_macro): Init all fields of macro_entry.
This commit is contained in:
parent
48afe8b710
commit
c026360c75
@ -229,15 +229,14 @@ iq2000_add_macro (const char * name,
|
||||
const char ** arguments)
|
||||
{
|
||||
macro_entry *macro;
|
||||
sb macro_name;
|
||||
const char *namestr;
|
||||
|
||||
macro = XNEW (macro_entry);
|
||||
macro->name = xstrdup (name);
|
||||
sb_new (& macro->sub);
|
||||
sb_new (& macro_name);
|
||||
|
||||
macro->formal_count = 0;
|
||||
macro->formals = 0;
|
||||
macro->formal_hash = str_htab_create ();
|
||||
macro->file = as_where (¯o->line);
|
||||
|
||||
sb_add_string (& macro->sub, semantics);
|
||||
|
||||
@ -245,9 +244,6 @@ iq2000_add_macro (const char * name,
|
||||
{
|
||||
formal_entry ** p = ¯o->formals;
|
||||
|
||||
macro->formal_count = 0;
|
||||
macro->formal_hash = str_htab_create ();
|
||||
|
||||
while (*arguments != NULL)
|
||||
{
|
||||
formal_entry *formal;
|
||||
@ -261,7 +257,7 @@ iq2000_add_macro (const char * name,
|
||||
/* chlm: Added the following to allow defaulted args. */
|
||||
if (strchr (*arguments,'='))
|
||||
{
|
||||
char * tt_args = strdup (*arguments);
|
||||
char * tt_args = xstrdup (*arguments);
|
||||
char * tt_dflt = strchr (tt_args,'=');
|
||||
|
||||
*tt_dflt = 0;
|
||||
@ -283,9 +279,7 @@ iq2000_add_macro (const char * name,
|
||||
}
|
||||
}
|
||||
|
||||
sb_add_string (¯o_name, name);
|
||||
namestr = sb_terminate (¯o_name);
|
||||
str_hash_insert (macro_hash, namestr, macro, 1);
|
||||
str_hash_insert (macro_hash, macro->name, macro, 1);
|
||||
|
||||
macro_defined = 1;
|
||||
}
|
||||
|
46
gas/macro.c
46
gas/macro.c
@ -70,13 +70,23 @@ static size_t (*macro_expr) (const char *, size_t, sb *, offsetT *);
|
||||
|
||||
static int macro_number;
|
||||
|
||||
static void free_macro (macro_entry *);
|
||||
|
||||
static void
|
||||
macro_del_f (void *ent)
|
||||
{
|
||||
string_tuple_t *tuple = ent;
|
||||
free_macro ((macro_entry *) tuple->value);
|
||||
}
|
||||
|
||||
/* Initialize macro processing. */
|
||||
|
||||
void
|
||||
macro_init (int alternate, int mri, int strip_at,
|
||||
size_t (*exp) (const char *, size_t, sb *, offsetT *))
|
||||
{
|
||||
macro_hash = str_htab_create ();
|
||||
macro_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
|
||||
macro_del_f, notes_calloc, NULL);
|
||||
macro_defined = 0;
|
||||
macro_alternate = alternate;
|
||||
macro_mri = mri;
|
||||
@ -664,34 +674,30 @@ free_macro (macro_entry *macro)
|
||||
}
|
||||
htab_delete (macro->formal_hash);
|
||||
sb_kill (¯o->sub);
|
||||
free ((char *) macro->name);
|
||||
free (macro);
|
||||
}
|
||||
|
||||
/* Define a new macro. Returns NULL on success, otherwise returns an
|
||||
error message. If NAMEP is not NULL, *NAMEP is set to the name of
|
||||
the macro which was defined. */
|
||||
/* Define a new macro. */
|
||||
|
||||
const char *
|
||||
define_macro (size_t idx, sb *in, sb *label,
|
||||
size_t (*get_line) (sb *),
|
||||
const char *file, unsigned int line,
|
||||
const char **namep)
|
||||
macro_entry *
|
||||
define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
|
||||
{
|
||||
macro_entry *macro;
|
||||
sb name;
|
||||
size_t idx;
|
||||
const char *error = NULL;
|
||||
|
||||
macro = XNEW (macro_entry);
|
||||
sb_new (¯o->sub);
|
||||
sb_new (&name);
|
||||
macro->file = file;
|
||||
macro->line = line;
|
||||
macro->file = as_where (¯o->line);
|
||||
|
||||
macro->formal_count = 0;
|
||||
macro->formals = 0;
|
||||
macro->formal_hash = str_htab_create ();
|
||||
|
||||
idx = sb_skip_white (idx, in);
|
||||
idx = sb_skip_white (0, in);
|
||||
if (! buffer_and_nest ("MACRO", "ENDM", ¯o->sub, get_line))
|
||||
error = _("unexpected end of file in macro `%s' definition");
|
||||
if (label != NULL && label->len != 0)
|
||||
@ -740,15 +746,16 @@ define_macro (size_t idx, sb *in, sb *label,
|
||||
error = _("Macro `%s' was already defined");
|
||||
}
|
||||
|
||||
if (namep != NULL)
|
||||
*namep = macro->name;
|
||||
|
||||
if (!error)
|
||||
macro_defined = 1;
|
||||
else
|
||||
free_macro (macro);
|
||||
{
|
||||
as_bad_where (macro->file, macro->line, error, macro->name);
|
||||
free_macro (macro);
|
||||
macro = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
return macro;
|
||||
}
|
||||
|
||||
/* Scan a token, and then skip KIND. */
|
||||
@ -1318,10 +1325,7 @@ delete_macro (const char *name)
|
||||
|
||||
macro = str_hash_find (macro_hash, copy);
|
||||
if (macro != NULL)
|
||||
{
|
||||
free_macro (macro);
|
||||
str_hash_delete (macro_hash, copy);
|
||||
}
|
||||
str_hash_delete (macro_hash, copy);
|
||||
else
|
||||
as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
|
||||
free (copy);
|
||||
|
@ -88,8 +88,7 @@ extern void macro_init (int, int, int,
|
||||
extern void macro_end (void);
|
||||
extern void macro_set_alternate (int);
|
||||
extern void macro_mri_mode (int);
|
||||
extern const char *define_macro (size_t, sb *, sb *, size_t (*) (sb *),
|
||||
const char *, unsigned int, const char **);
|
||||
extern macro_entry *define_macro (sb *, sb *, size_t (*) (sb *));
|
||||
extern int check_macro (const char *, sb *, const char **, macro_entry **);
|
||||
extern void delete_macro (const char *);
|
||||
extern const char *expand_irp (int, size_t, sb *, sb *, size_t (*) (sb *));
|
||||
|
32
gas/read.c
32
gas/read.c
@ -2647,13 +2647,8 @@ void
|
||||
s_macro (int ignore ATTRIBUTE_UNUSED)
|
||||
{
|
||||
char *eol;
|
||||
const char * file;
|
||||
unsigned int line;
|
||||
sb s;
|
||||
const char *err;
|
||||
const char *name;
|
||||
|
||||
file = as_where (&line);
|
||||
macro_entry *macro;
|
||||
|
||||
eol = find_end_of_line (input_line_pointer, 0);
|
||||
sb_build (&s, eol - input_line_pointer);
|
||||
@ -2664,19 +2659,18 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
|
||||
{
|
||||
sb label;
|
||||
size_t len;
|
||||
const char *name;
|
||||
|
||||
name = S_GET_NAME (line_label);
|
||||
len = strlen (name);
|
||||
sb_build (&label, len);
|
||||
sb_add_buffer (&label, name, len);
|
||||
err = define_macro (0, &s, &label, get_macro_line_sb, file, line, &name);
|
||||
macro = define_macro (&s, &label, get_macro_line_sb);
|
||||
sb_kill (&label);
|
||||
}
|
||||
else
|
||||
err = define_macro (0, &s, NULL, get_macro_line_sb, file, line, &name);
|
||||
if (err != NULL)
|
||||
as_bad_where (file, line, err, name);
|
||||
else
|
||||
macro = define_macro (&s, NULL, get_macro_line_sb);
|
||||
if (macro != NULL)
|
||||
{
|
||||
if (line_label != NULL)
|
||||
{
|
||||
@ -2686,14 +2680,16 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
|
||||
}
|
||||
|
||||
if (((NO_PSEUDO_DOT || flag_m68k_mri)
|
||||
&& str_hash_find (po_hash, name) != NULL)
|
||||
&& str_hash_find (po_hash, macro->name) != NULL)
|
||||
|| (!flag_m68k_mri
|
||||
&& *name == '.'
|
||||
&& str_hash_find (po_hash, name + 1) != NULL))
|
||||
as_warn_where (file,
|
||||
line,
|
||||
_("attempt to redefine pseudo-op `%s' ignored"),
|
||||
name);
|
||||
&& macro->name[0] == '.'
|
||||
&& str_hash_find (po_hash, macro->name + 1) != NULL))
|
||||
{
|
||||
as_warn_where (macro->file, macro->line,
|
||||
_("attempt to redefine pseudo-op `%s' ignored"),
|
||||
macro->name);
|
||||
str_hash_delete (macro_hash, macro->name);
|
||||
}
|
||||
}
|
||||
|
||||
sb_kill (&s);
|
||||
|
Loading…
Reference in New Issue
Block a user