From: Peter Johnson Date: Mon, 29 Oct 2001 04:52:44 +0000 (-0000) Subject: Plug memory leaks, and enhance finding later ones with *_delete functions. X-Git-Tag: v0.1.0~229 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d95de5161399e432a423a5f5c38345ceb24431f;p=yasm Plug memory leaks, and enhance finding later ones with *_delete functions. Fix a *major* bug in expr_level_op(). svn path=/trunk/yasm/; revision=301 --- diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index b42d331b..45e76049 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -132,8 +132,13 @@ main(int argc, char *argv[]) sections = nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in); - if (OutputAllErrorWarning() > 0) + if (OutputAllErrorWarning() > 0) { + sections_delete(sections); + symrec_delete_all(); + filename_delete_all(); + BitVector_Shutdown(); return EXIT_FAILURE; + } sections_print(sections); printf("\n***Symbol Table***\n"); @@ -145,7 +150,10 @@ main(int argc, char *argv[]) printf("Post-parser-finalization:\n"); sections_print(sections); + sections_delete(sections); + symrec_delete_all(); filename_delete_all(); + BitVector_Shutdown(); return EXIT_SUCCESS; } diff --git a/libyasm/bitvect.c b/libyasm/bitvect.c index ef239184..cedec924 100644 --- a/libyasm/bitvect.c +++ b/libyasm/bitvect.c @@ -304,6 +304,11 @@ ErrCode BitVector_Boot(void) return(ErrCode_Ok); } +void BitVector_Shutdown(void) +{ + if (BITMASKTAB) xfree(BITMASKTAB); +} + N_word BitVector_Size(N_int bits) /* bit vector size (# of words) */ { N_word size; diff --git a/libyasm/bitvect.h b/libyasm/bitvect.h index 1cd3195d..4712e439 100644 --- a/libyasm/bitvect.h +++ b/libyasm/bitvect.h @@ -108,6 +108,7 @@ typedef enum /* ===> MISCELLANEOUS: <=== */ ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */ +void BitVector_Shutdown (void); /* undo Boot */ N_word BitVector_Size (N_int bits); /* bit vector size (# of words) */ N_word BitVector_Mask (N_int bits); /* bit vector mask (unused bits) */ diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index 498236ba..0a5352c5 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -543,6 +543,40 @@ bytecode_new_reserve(expr *numitems, unsigned long itemsize) return bc; } +void +bytecode_delete(bytecode *bc) +{ + if (!bc) + return; + + switch (bc->type) { + case BC_EMPTY: + break; + case BC_INSN: + if (bc->data.insn.ea) { + expr_delete(bc->data.insn.ea->disp); + xfree(bc->data.insn.ea); + } + if (bc->data.insn.imm) { + expr_delete(bc->data.insn.imm->val); + xfree(bc->data.insn.imm); + } + break; + case BC_JMPREL: + expr_delete(bc->data.jmprel.target); + break; + case BC_DATA: + datavals_delete(&bc->data.data.datahead); + break; + case BC_RESERVE: + expr_delete(bc->data.reserve.numitems); + break; + } + + expr_delete(bc->multiple); + xfree(bc); +} + int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val) { @@ -658,7 +692,7 @@ bytecode_print(const bytecode *bc) printf("Final Element Size=%u\n", (unsigned int)bc->data.data.size); printf("Elements:\n"); - dataval_print(&bc->data.data.datahead); + datavals_print(&bc->data.data.datahead); break; case BC_RESERVE: printf("_Reserve_\n"); @@ -723,6 +757,20 @@ bytecode_parser_finalize(bytecode *bc) } } +void +bytecodes_delete(bytecodehead *headp) +{ + bytecode *cur, *next; + + cur = STAILQ_FIRST(headp); + while (cur) { + next = STAILQ_NEXT(cur, link); + bytecode_delete(cur); + cur = next; + } + STAILQ_INIT(headp); +} + bytecode * bytecodes_append(bytecodehead *headp, bytecode *bc) { @@ -779,6 +827,22 @@ dataval_new_string(char *str_val) return retval; } +void +datavals_delete(datavalhead *headp) +{ + dataval *cur, *next; + + cur = STAILQ_FIRST(headp); + while (cur) { + next = STAILQ_NEXT(cur, link); + if (cur->type == DV_EXPR) + expr_delete(cur->data.expn); + xfree(cur); + cur = next; + } + STAILQ_INIT(headp); +} + dataval * datavals_append(datavalhead *headp, dataval *dv) { @@ -790,7 +854,7 @@ datavals_append(datavalhead *headp, dataval *dv) } void -dataval_print(const datavalhead *head) +datavals_print(const datavalhead *head) { dataval *cur; diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index fc164653..d2cd383c 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -114,6 +114,8 @@ bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size); bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize); +void bytecode_delete(bytecode *bc); + /* Gets the offset of the bytecode specified by bc if possible. * Return value is IF POSSIBLE, not the value. */ @@ -126,6 +128,8 @@ void bytecode_parser_finalize(bytecode *bc); /* void bytecodes_initialize(bytecodehead *headp); */ #define bytecodes_initialize(headp) STAILQ_INIT(headp) +void bytecodes_delete(bytecodehead *headp); + /* Adds bc to the list of bytecodes headp. * NOTE: Does not make a copy of bc; so don't pass this function * static or local variables, and discard the bc pointer after calling @@ -145,6 +149,8 @@ dataval *dataval_new_string(char *str_val); /* void datavals_initialize(datavalhead *headp); */ #define datavals_initialize(headp) STAILQ_INIT(headp) +void datavals_delete(datavalhead *headp); + /* Adds dv to the list of datavals headp. * NOTE: Does not make a copy of dv; so don't pass this function * static or local variables, and discard the dv pointer after calling @@ -153,6 +159,6 @@ dataval *dataval_new_string(char *str_val); */ dataval *datavals_append(datavalhead *headp, dataval *dv); -void dataval_print(const datavalhead *head); +void datavals_print(const datavalhead *head); #endif diff --git a/libyasm/expr.c b/libyasm/expr.c index 33180b3c..63604b90 100644 --- a/libyasm/expr.c +++ b/libyasm/expr.c @@ -550,6 +550,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) intnum_delete(sube->terms[j].data.intn); } } else { + if (o == first_int_term) + o--; e->terms[o--] = sube->terms[j]; /* structure copy */ } } @@ -560,6 +562,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) xfree(sube); } else if (o != i) { /* copy operand if it changed places */ + if (o == first_int_term) + o--; e->terms[o--] = e->terms[i]; } } diff --git a/libyasm/linemgr.c b/libyasm/linemgr.c index 8f516a8e..03ef07e0 100644 --- a/libyasm/linemgr.c +++ b/libyasm/linemgr.c @@ -51,10 +51,16 @@ switch_filename(const char *filename) xfree(copy); } +static void +filename_delete_one(void *d) +{ + xfree(d); +} + void filename_delete_all(void) { in_filename = NULL; - ternary_cleanup(filename_table); + ternary_cleanup(filename_table, filename_delete_one); filename_table = NULL; } diff --git a/libyasm/section.c b/libyasm/section.c index 52d62a2d..90608419 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -127,6 +127,20 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name) return s; } +void +sections_delete(sectionhead *headp) +{ + section *cur, *next; + + cur = STAILQ_FIRST(headp); + while (cur) { + next = STAILQ_NEXT(cur, link); + section_delete(cur); + cur = next; + } + STAILQ_INIT(headp); +} + void sections_print(const sectionhead *headp) { @@ -157,6 +171,17 @@ section_get_name(const section *sect) return sect->name; } +void +section_delete(section *sect) +{ + if (!sect) + return; + + xfree(sect->name); + bytecodes_delete(§->bc); + xfree(sect); +} + void section_print(const section *sect) { diff --git a/libyasm/section.h b/libyasm/section.h index 19438df3..ff99fb9d 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -36,6 +36,8 @@ section *sections_initialize(sectionhead *headp, struct objfmt_s *of); section *sections_switch(sectionhead *headp, struct objfmt_s *of, const char *name); +void sections_delete(sectionhead *headp); + void sections_print(const sectionhead *headp); void sections_parser_finalize(sectionhead *headp); @@ -44,5 +46,7 @@ bytecodehead *section_get_bytecodes(section *sect); const char *section_get_name(const section *sect); +void section_delete(section *sect); + void section_print(const section *sect); #endif diff --git a/libyasm/symrec.c b/libyasm/symrec.c index 1426fc09..698e9869 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -266,6 +266,23 @@ symrec_parser_finalize(void) symrec_foreach(symrec_parser_finalize_checksym); } +static void +symrec_delete_one(void *d) +{ + symrec *sym = d; + xfree(sym->name); + if (sym->type == SYM_EQU) + expr_delete(sym->value.expn); + free(sym); +} + +void +symrec_delete_all(void) +{ + ternary_cleanup(sym_table, symrec_delete_one); + sym_table = NULL; +} + void symrec_print(const symrec *sym) { diff --git a/libyasm/symrec.h b/libyasm/symrec.h index 60ed516e..c4a94f14 100644 --- a/libyasm/symrec.h +++ b/libyasm/symrec.h @@ -74,5 +74,7 @@ int symrec_foreach(int (*func) (symrec *sym)); void symrec_parser_finalize(void); +void symrec_delete_all(void); + void symrec_print(const symrec *sym); #endif diff --git a/modules/arch/x86/expr.c b/modules/arch/x86/expr.c index 33180b3c..63604b90 100644 --- a/modules/arch/x86/expr.c +++ b/modules/arch/x86/expr.c @@ -550,6 +550,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) intnum_delete(sube->terms[j].data.intn); } } else { + if (o == first_int_term) + o--; e->terms[o--] = sube->terms[j]; /* structure copy */ } } @@ -560,6 +562,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) xfree(sube); } else if (o != i) { /* copy operand if it changed places */ + if (o == first_int_term) + o--; e->terms[o--] = e->terms[i]; } } diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index 33180b3c..63604b90 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -550,6 +550,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) intnum_delete(sube->terms[j].data.intn); } } else { + if (o == first_int_term) + o--; e->terms[o--] = sube->terms[j]; /* structure copy */ } } @@ -560,6 +562,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) xfree(sube); } else if (o != i) { /* copy operand if it changed places */ + if (o == first_int_term) + o--; e->terms[o--] = e->terms[i]; } } diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index 234e6784..9846e2cf 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -164,6 +164,7 @@ lineexp: exp | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); + xfree($1); $$ = (bytecode *)NULL; } ; @@ -194,15 +195,19 @@ dataval: expr_no_string { $$ = dataval_new_expr($1); } label: label_id { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } | label_id ':' { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } ; label_id: ID { $$ = $1; + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); nasm_parser_locallabel_base = xstrdup($1); } | SPECIAL_ID @@ -315,6 +320,7 @@ memexpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | '(' memexpr ')' { $$ = $2; } | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } | error { Error(_("invalid effective address")); } ; @@ -478,12 +484,13 @@ expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } expr: expr_no_string | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } ; -explabel: ID { $$ = symrec_use($1); } - | SPECIAL_ID { $$ = symrec_use($1); } - | LOCAL_ID { $$ = symrec_use($1); } +explabel: ID { $$ = symrec_use($1); xfree($1); } + | SPECIAL_ID { $$ = symrec_use($1); xfree($1); } + | LOCAL_ID { $$ = symrec_use($1); xfree($1); } | '$' { $$ = symrec_define_label("$", nasm_parser_cur_section, nasm_parser_prev_bc, 0); diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index 234e6784..9846e2cf 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -164,6 +164,7 @@ lineexp: exp | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); + xfree($1); $$ = (bytecode *)NULL; } ; @@ -194,15 +195,19 @@ dataval: expr_no_string { $$ = dataval_new_expr($1); } label: label_id { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } | label_id ':' { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } ; label_id: ID { $$ = $1; + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); nasm_parser_locallabel_base = xstrdup($1); } | SPECIAL_ID @@ -315,6 +320,7 @@ memexpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | '(' memexpr ')' { $$ = $2; } | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } | error { Error(_("invalid effective address")); } ; @@ -478,12 +484,13 @@ expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } expr: expr_no_string | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } ; -explabel: ID { $$ = symrec_use($1); } - | SPECIAL_ID { $$ = symrec_use($1); } - | LOCAL_ID { $$ = symrec_use($1); } +explabel: ID { $$ = symrec_use($1); xfree($1); } + | SPECIAL_ID { $$ = symrec_use($1); xfree($1); } + | LOCAL_ID { $$ = symrec_use($1); xfree($1); } | '$' { $$ = symrec_define_label("$", nasm_parser_cur_section, nasm_parser_prev_bc, 0); diff --git a/modules/parsers/nasm/nasm-parser.c b/modules/parsers/nasm/nasm-parser.c index a4d9a519..fffa8bdb 100644 --- a/modules/parsers/nasm/nasm-parser.c +++ b/modules/parsers/nasm/nasm-parser.c @@ -35,6 +35,10 @@ #include "preproc.h" #include "parser.h" +#ifdef DMALLOC +# include +#endif + RCSID("$IdPath$"); extern FILE *nasm_parser_in; @@ -48,6 +52,8 @@ objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; +extern char *nasm_parser_locallabel_base; + static sectionhead * nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { @@ -65,6 +71,10 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) nasm_parser_parse(); + /* Free locallabel base if necessary */ + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); + return &nasm_parser_sections; } diff --git a/modules/parsers/nasm/parser.c b/modules/parsers/nasm/parser.c index a4d9a519..fffa8bdb 100644 --- a/modules/parsers/nasm/parser.c +++ b/modules/parsers/nasm/parser.c @@ -35,6 +35,10 @@ #include "preproc.h" #include "parser.h" +#ifdef DMALLOC +# include +#endif + RCSID("$IdPath$"); extern FILE *nasm_parser_in; @@ -48,6 +52,8 @@ objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; +extern char *nasm_parser_locallabel_base; + static sectionhead * nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { @@ -65,6 +71,10 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) nasm_parser_parse(); + /* Free locallabel base if necessary */ + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); + return &nasm_parser_sections; } diff --git a/modules/parsers/nasm/token.l.in b/modules/parsers/nasm/token.l.in index 6973afbe..b868b678 100644 --- a/modules/parsers/nasm/token.l.in +++ b/modules/parsers/nasm/token.l.in @@ -177,12 +177,12 @@ WS [ \t\r] [a-z]+ { BEGIN DIRECTIVE2; - yylval.str_val = xstrdup(yytext); + yylval.str_val = yytext; return DIRECTIVE_NAME; } /* everything printable except for ' ', '[' and ']'. */ [!-@a-z\\^-`{|}~]+ { - yylval.str_val = xstrdup(yytext); + yylval.str_val = yytext; return DIRECTIVE_VAL; } . { diff --git a/src/arch/x86/expr.c b/src/arch/x86/expr.c index 33180b3c..63604b90 100644 --- a/src/arch/x86/expr.c +++ b/src/arch/x86/expr.c @@ -550,6 +550,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) intnum_delete(sube->terms[j].data.intn); } } else { + if (o == first_int_term) + o--; e->terms[o--] = sube->terms[j]; /* structure copy */ } } @@ -560,6 +562,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) xfree(sube); } else if (o != i) { /* copy operand if it changed places */ + if (o == first_int_term) + o--; e->terms[o--] = e->terms[i]; } } diff --git a/src/arch/x86/x86expr.c b/src/arch/x86/x86expr.c index 33180b3c..63604b90 100644 --- a/src/arch/x86/x86expr.c +++ b/src/arch/x86/x86expr.c @@ -550,6 +550,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) intnum_delete(sube->terms[j].data.intn); } } else { + if (o == first_int_term) + o--; e->terms[o--] = sube->terms[j]; /* structure copy */ } } @@ -560,6 +562,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) xfree(sube); } else if (o != i) { /* copy operand if it changed places */ + if (o == first_int_term) + o--; e->terms[o--] = e->terms[i]; } } diff --git a/src/bitvect.c b/src/bitvect.c index ef239184..cedec924 100644 --- a/src/bitvect.c +++ b/src/bitvect.c @@ -304,6 +304,11 @@ ErrCode BitVector_Boot(void) return(ErrCode_Ok); } +void BitVector_Shutdown(void) +{ + if (BITMASKTAB) xfree(BITMASKTAB); +} + N_word BitVector_Size(N_int bits) /* bit vector size (# of words) */ { N_word size; diff --git a/src/bitvect.h b/src/bitvect.h index 1cd3195d..4712e439 100644 --- a/src/bitvect.h +++ b/src/bitvect.h @@ -108,6 +108,7 @@ typedef enum /* ===> MISCELLANEOUS: <=== */ ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */ +void BitVector_Shutdown (void); /* undo Boot */ N_word BitVector_Size (N_int bits); /* bit vector size (# of words) */ N_word BitVector_Mask (N_int bits); /* bit vector mask (unused bits) */ diff --git a/src/bytecode.c b/src/bytecode.c index 498236ba..0a5352c5 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -543,6 +543,40 @@ bytecode_new_reserve(expr *numitems, unsigned long itemsize) return bc; } +void +bytecode_delete(bytecode *bc) +{ + if (!bc) + return; + + switch (bc->type) { + case BC_EMPTY: + break; + case BC_INSN: + if (bc->data.insn.ea) { + expr_delete(bc->data.insn.ea->disp); + xfree(bc->data.insn.ea); + } + if (bc->data.insn.imm) { + expr_delete(bc->data.insn.imm->val); + xfree(bc->data.insn.imm); + } + break; + case BC_JMPREL: + expr_delete(bc->data.jmprel.target); + break; + case BC_DATA: + datavals_delete(&bc->data.data.datahead); + break; + case BC_RESERVE: + expr_delete(bc->data.reserve.numitems); + break; + } + + expr_delete(bc->multiple); + xfree(bc); +} + int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val) { @@ -658,7 +692,7 @@ bytecode_print(const bytecode *bc) printf("Final Element Size=%u\n", (unsigned int)bc->data.data.size); printf("Elements:\n"); - dataval_print(&bc->data.data.datahead); + datavals_print(&bc->data.data.datahead); break; case BC_RESERVE: printf("_Reserve_\n"); @@ -723,6 +757,20 @@ bytecode_parser_finalize(bytecode *bc) } } +void +bytecodes_delete(bytecodehead *headp) +{ + bytecode *cur, *next; + + cur = STAILQ_FIRST(headp); + while (cur) { + next = STAILQ_NEXT(cur, link); + bytecode_delete(cur); + cur = next; + } + STAILQ_INIT(headp); +} + bytecode * bytecodes_append(bytecodehead *headp, bytecode *bc) { @@ -779,6 +827,22 @@ dataval_new_string(char *str_val) return retval; } +void +datavals_delete(datavalhead *headp) +{ + dataval *cur, *next; + + cur = STAILQ_FIRST(headp); + while (cur) { + next = STAILQ_NEXT(cur, link); + if (cur->type == DV_EXPR) + expr_delete(cur->data.expn); + xfree(cur); + cur = next; + } + STAILQ_INIT(headp); +} + dataval * datavals_append(datavalhead *headp, dataval *dv) { @@ -790,7 +854,7 @@ datavals_append(datavalhead *headp, dataval *dv) } void -dataval_print(const datavalhead *head) +datavals_print(const datavalhead *head) { dataval *cur; diff --git a/src/bytecode.h b/src/bytecode.h index fc164653..d2cd383c 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -114,6 +114,8 @@ bytecode *bytecode_new_data(datavalhead *datahead, unsigned long size); bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize); +void bytecode_delete(bytecode *bc); + /* Gets the offset of the bytecode specified by bc if possible. * Return value is IF POSSIBLE, not the value. */ @@ -126,6 +128,8 @@ void bytecode_parser_finalize(bytecode *bc); /* void bytecodes_initialize(bytecodehead *headp); */ #define bytecodes_initialize(headp) STAILQ_INIT(headp) +void bytecodes_delete(bytecodehead *headp); + /* Adds bc to the list of bytecodes headp. * NOTE: Does not make a copy of bc; so don't pass this function * static or local variables, and discard the bc pointer after calling @@ -145,6 +149,8 @@ dataval *dataval_new_string(char *str_val); /* void datavals_initialize(datavalhead *headp); */ #define datavals_initialize(headp) STAILQ_INIT(headp) +void datavals_delete(datavalhead *headp); + /* Adds dv to the list of datavals headp. * NOTE: Does not make a copy of dv; so don't pass this function * static or local variables, and discard the dv pointer after calling @@ -153,6 +159,6 @@ dataval *dataval_new_string(char *str_val); */ dataval *datavals_append(datavalhead *headp, dataval *dv); -void dataval_print(const datavalhead *head); +void datavals_print(const datavalhead *head); #endif diff --git a/src/expr.c b/src/expr.c index 33180b3c..63604b90 100644 --- a/src/expr.c +++ b/src/expr.c @@ -550,6 +550,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) intnum_delete(sube->terms[j].data.intn); } } else { + if (o == first_int_term) + o--; e->terms[o--] = sube->terms[j]; /* structure copy */ } } @@ -560,6 +562,8 @@ expr_level_op(expr *e, int fold_const, int simplify_ident) xfree(sube); } else if (o != i) { /* copy operand if it changed places */ + if (o == first_int_term) + o--; e->terms[o--] = e->terms[i]; } } diff --git a/src/globals.c b/src/globals.c index 8f516a8e..03ef07e0 100644 --- a/src/globals.c +++ b/src/globals.c @@ -51,10 +51,16 @@ switch_filename(const char *filename) xfree(copy); } +static void +filename_delete_one(void *d) +{ + xfree(d); +} + void filename_delete_all(void) { in_filename = NULL; - ternary_cleanup(filename_table); + ternary_cleanup(filename_table, filename_delete_one); filename_table = NULL; } diff --git a/src/linemgr.c b/src/linemgr.c index 8f516a8e..03ef07e0 100644 --- a/src/linemgr.c +++ b/src/linemgr.c @@ -51,10 +51,16 @@ switch_filename(const char *filename) xfree(copy); } +static void +filename_delete_one(void *d) +{ + xfree(d); +} + void filename_delete_all(void) { in_filename = NULL; - ternary_cleanup(filename_table); + ternary_cleanup(filename_table, filename_delete_one); filename_table = NULL; } diff --git a/src/main.c b/src/main.c index b42d331b..45e76049 100644 --- a/src/main.c +++ b/src/main.c @@ -132,8 +132,13 @@ main(int argc, char *argv[]) sections = nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in); - if (OutputAllErrorWarning() > 0) + if (OutputAllErrorWarning() > 0) { + sections_delete(sections); + symrec_delete_all(); + filename_delete_all(); + BitVector_Shutdown(); return EXIT_FAILURE; + } sections_print(sections); printf("\n***Symbol Table***\n"); @@ -145,7 +150,10 @@ main(int argc, char *argv[]) printf("Post-parser-finalization:\n"); sections_print(sections); + sections_delete(sections); + symrec_delete_all(); filename_delete_all(); + BitVector_Shutdown(); return EXIT_SUCCESS; } diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index 234e6784..9846e2cf 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -164,6 +164,7 @@ lineexp: exp | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); + xfree($1); $$ = (bytecode *)NULL; } ; @@ -194,15 +195,19 @@ dataval: expr_no_string { $$ = dataval_new_expr($1); } label: label_id { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } | label_id ':' { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } ; label_id: ID { $$ = $1; + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); nasm_parser_locallabel_base = xstrdup($1); } | SPECIAL_ID @@ -315,6 +320,7 @@ memexpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | '(' memexpr ')' { $$ = $2; } | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } | error { Error(_("invalid effective address")); } ; @@ -478,12 +484,13 @@ expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } expr: expr_no_string | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } ; -explabel: ID { $$ = symrec_use($1); } - | SPECIAL_ID { $$ = symrec_use($1); } - | LOCAL_ID { $$ = symrec_use($1); } +explabel: ID { $$ = symrec_use($1); xfree($1); } + | SPECIAL_ID { $$ = symrec_use($1); xfree($1); } + | LOCAL_ID { $$ = symrec_use($1); xfree($1); } | '$' { $$ = symrec_define_label("$", nasm_parser_cur_section, nasm_parser_prev_bc, 0); diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index 234e6784..9846e2cf 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -164,6 +164,7 @@ lineexp: exp | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); + xfree($1); $$ = (bytecode *)NULL; } ; @@ -194,15 +195,19 @@ dataval: expr_no_string { $$ = dataval_new_expr($1); } label: label_id { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } | label_id ':' { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, 1); + xfree($1); } ; label_id: ID { $$ = $1; + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); nasm_parser_locallabel_base = xstrdup($1); } | SPECIAL_ID @@ -315,6 +320,7 @@ memexpr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | '(' memexpr ')' { $$ = $2; } | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } | error { Error(_("invalid effective address")); } ; @@ -478,12 +484,13 @@ expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } expr: expr_no_string | STRING { $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1))); + xfree($1); } ; -explabel: ID { $$ = symrec_use($1); } - | SPECIAL_ID { $$ = symrec_use($1); } - | LOCAL_ID { $$ = symrec_use($1); } +explabel: ID { $$ = symrec_use($1); xfree($1); } + | SPECIAL_ID { $$ = symrec_use($1); xfree($1); } + | LOCAL_ID { $$ = symrec_use($1); xfree($1); } | '$' { $$ = symrec_define_label("$", nasm_parser_cur_section, nasm_parser_prev_bc, 0); diff --git a/src/parsers/nasm/nasm-parser.c b/src/parsers/nasm/nasm-parser.c index a4d9a519..fffa8bdb 100644 --- a/src/parsers/nasm/nasm-parser.c +++ b/src/parsers/nasm/nasm-parser.c @@ -35,6 +35,10 @@ #include "preproc.h" #include "parser.h" +#ifdef DMALLOC +# include +#endif + RCSID("$IdPath$"); extern FILE *nasm_parser_in; @@ -48,6 +52,8 @@ objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; +extern char *nasm_parser_locallabel_base; + static sectionhead * nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { @@ -65,6 +71,10 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) nasm_parser_parse(); + /* Free locallabel base if necessary */ + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); + return &nasm_parser_sections; } diff --git a/src/parsers/nasm/parser.c b/src/parsers/nasm/parser.c index a4d9a519..fffa8bdb 100644 --- a/src/parsers/nasm/parser.c +++ b/src/parsers/nasm/parser.c @@ -35,6 +35,10 @@ #include "preproc.h" #include "parser.h" +#ifdef DMALLOC +# include +#endif + RCSID("$IdPath$"); extern FILE *nasm_parser_in; @@ -48,6 +52,8 @@ objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; +extern char *nasm_parser_locallabel_base; + static sectionhead * nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { @@ -65,6 +71,10 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) nasm_parser_parse(); + /* Free locallabel base if necessary */ + if (nasm_parser_locallabel_base) + xfree(nasm_parser_locallabel_base); + return &nasm_parser_sections; } diff --git a/src/parsers/nasm/token.l.in b/src/parsers/nasm/token.l.in index 6973afbe..b868b678 100644 --- a/src/parsers/nasm/token.l.in +++ b/src/parsers/nasm/token.l.in @@ -177,12 +177,12 @@ WS [ \t\r] [a-z]+ { BEGIN DIRECTIVE2; - yylval.str_val = xstrdup(yytext); + yylval.str_val = yytext; return DIRECTIVE_NAME; } /* everything printable except for ' ', '[' and ']'. */ [!-@a-z\\^-`{|}~]+ { - yylval.str_val = xstrdup(yytext); + yylval.str_val = yytext; return DIRECTIVE_VAL; } . { diff --git a/src/section.c b/src/section.c index 52d62a2d..90608419 100644 --- a/src/section.c +++ b/src/section.c @@ -127,6 +127,20 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name) return s; } +void +sections_delete(sectionhead *headp) +{ + section *cur, *next; + + cur = STAILQ_FIRST(headp); + while (cur) { + next = STAILQ_NEXT(cur, link); + section_delete(cur); + cur = next; + } + STAILQ_INIT(headp); +} + void sections_print(const sectionhead *headp) { @@ -157,6 +171,17 @@ section_get_name(const section *sect) return sect->name; } +void +section_delete(section *sect) +{ + if (!sect) + return; + + xfree(sect->name); + bytecodes_delete(§->bc); + xfree(sect); +} + void section_print(const section *sect) { diff --git a/src/section.h b/src/section.h index 19438df3..ff99fb9d 100644 --- a/src/section.h +++ b/src/section.h @@ -36,6 +36,8 @@ section *sections_initialize(sectionhead *headp, struct objfmt_s *of); section *sections_switch(sectionhead *headp, struct objfmt_s *of, const char *name); +void sections_delete(sectionhead *headp); + void sections_print(const sectionhead *headp); void sections_parser_finalize(sectionhead *headp); @@ -44,5 +46,7 @@ bytecodehead *section_get_bytecodes(section *sect); const char *section_get_name(const section *sect); +void section_delete(section *sect); + void section_print(const section *sect); #endif diff --git a/src/symrec.c b/src/symrec.c index 1426fc09..698e9869 100644 --- a/src/symrec.c +++ b/src/symrec.c @@ -266,6 +266,23 @@ symrec_parser_finalize(void) symrec_foreach(symrec_parser_finalize_checksym); } +static void +symrec_delete_one(void *d) +{ + symrec *sym = d; + xfree(sym->name); + if (sym->type == SYM_EQU) + expr_delete(sym->value.expn); + free(sym); +} + +void +symrec_delete_all(void) +{ + ternary_cleanup(sym_table, symrec_delete_one); + sym_table = NULL; +} + void symrec_print(const symrec *sym) { diff --git a/src/symrec.h b/src/symrec.h index 60ed516e..c4a94f14 100644 --- a/src/symrec.h +++ b/src/symrec.h @@ -74,5 +74,7 @@ int symrec_foreach(int (*func) (symrec *sym)); void symrec_parser_finalize(void); +void symrec_delete_all(void); + void symrec_print(const symrec *sym); #endif diff --git a/src/ternary.c b/src/ternary.c index 96083c32..9447bab9 100644 --- a/src/ternary.c +++ b/src/ternary.c @@ -102,14 +102,16 @@ ternary_insert (ternary_tree * root, const char *s, void *data, int replace) /* Free the ternary search tree rooted at p. */ void -ternary_cleanup (ternary_tree p) +ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d)) { if (p) { - ternary_cleanup (p->lokid); + ternary_cleanup (p->lokid, data_cleanup); if (p->splitchar) - ternary_cleanup (p->eqkid); - ternary_cleanup (p->hikid); + ternary_cleanup (p->eqkid, data_cleanup); + else + data_cleanup (p->eqkid); + ternary_cleanup (p->hikid, data_cleanup); xfree (p); } } diff --git a/src/ternary.h b/src/ternary.h index e9f78b80..7ae54bf3 100644 --- a/src/ternary.h +++ b/src/ternary.h @@ -42,7 +42,7 @@ void *ternary_insert (ternary_tree *p, const char *s, void *data, int replace); /* Delete the ternary search tree rooted at P. Does NOT delete the data you associated with the strings. */ -void ternary_cleanup (ternary_tree p); +void ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d)); /* Search the ternary tree for string S, returning the data associated with it if found. */