]> granicus.if.org Git - yasm/commitdiff
Plug memory leaks, and enhance finding later ones with *_delete functions.
authorPeter Johnson <peter@tortall.net>
Mon, 29 Oct 2001 04:52:44 +0000 (04:52 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 29 Oct 2001 04:52:44 +0000 (04:52 -0000)
Fix a *major* bug in expr_level_op().

svn path=/trunk/yasm/; revision=301

39 files changed:
frontends/yasm/yasm.c
libyasm/bitvect.c
libyasm/bitvect.h
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/expr.c
libyasm/linemgr.c
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
modules/arch/x86/expr.c
modules/arch/x86/x86expr.c
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/nasm-parser.c
modules/parsers/nasm/parser.c
modules/parsers/nasm/token.l.in
src/arch/x86/expr.c
src/arch/x86/x86expr.c
src/bitvect.c
src/bitvect.h
src/bytecode.c
src/bytecode.h
src/expr.c
src/globals.c
src/linemgr.c
src/main.c
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/nasm-parser.c
src/parsers/nasm/parser.c
src/parsers/nasm/token.l.in
src/section.c
src/section.h
src/symrec.c
src/symrec.h
src/ternary.c
src/ternary.h

index b42d331b18cc335ad381c1cddd22e0e9afa0fc9a..45e76049ca6e8d9c77f64261562876e0ed093e54 100644 (file)
@@ -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;
 }
 
index ef2391843c9c1ec65747a9046e2a27e9bcf9d2fb..cedec92428093487c20f1bc714ace139d4227f2f 100644 (file)
@@ -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;
index 1cd3195dc3941e735338bdb1961b887e4e48f43e..4712e439d013c1298fe5fe4840c98ce233e9da85 100644 (file)
@@ -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) */
index 498236ba4eb2bfb316b38f12aaedec8830566801..0a5352c50c0905377de788708c18254fee1bd8ea 100644 (file)
@@ -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;
 
index fc1646531317971fc76d336e145d1e7e46b42c57..d2cd383cc43b239777db633c9c61b3f89d5c7a41 100644 (file)
@@ -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
index 33180b3ce1dabff17646da1c1821c70060f67e1d..63604b906396bdc8b232c7b49b5fb5d20abb500b 100644 (file)
@@ -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];
        }
     }
index 8f516a8e61b3d339e63cd429518762fa70fe3d98..03ef07e0589a39a9110c9eedf9d1e52472286dff 100644 (file)
@@ -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;
 }
index 52d62a2df3ceef55bec4e80f2723c8946d28ca42..90608419febaffa5fad003ed80892523e0d76bdc 100644 (file)
@@ -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(&sect->bc);
+    xfree(sect);
+}
+
 void
 section_print(const section *sect)
 {
index 19438df32d857c04ae223c564516b4b8d857b896..ff99fb9d49a6f0e2d40357632767ebcec88c58ea 100644 (file)
@@ -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
index 1426fc096dcb3d883f07e66ccbecd38601ef959b..698e9869ca0e6b4cbb4579d38343f525a21df6b8 100644 (file)
@@ -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)
 {
index 60ed516e79eeee85db812266f2e8ed95e6a907e9..c4a94f14ca7144816018b667fc4836d09ad81cd6 100644 (file)
@@ -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
index 33180b3ce1dabff17646da1c1821c70060f67e1d..63604b906396bdc8b232c7b49b5fb5d20abb500b 100644 (file)
@@ -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];
        }
     }
index 33180b3ce1dabff17646da1c1821c70060f67e1d..63604b906396bdc8b232c7b49b5fb5d20abb500b 100644 (file)
@@ -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];
        }
     }
index 234e6784c51fd3bf3de8f09c8ceb865ac51eb82f..9846e2cfedfc94a1aa69feced9e8a87622423408 100644 (file)
@@ -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);
index 234e6784c51fd3bf3de8f09c8ceb865ac51eb82f..9846e2cfedfc94a1aa69feced9e8a87622423408 100644 (file)
@@ -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);
index a4d9a519baa7d4a8912d508575abca58fdab8ee9..fffa8bdbe4478ef40e50727270ed39edf875a6ea 100644 (file)
 #include "preproc.h"
 #include "parser.h"
 
+#ifdef DMALLOC
+# include <dmalloc.h>
+#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;
 }
 
index a4d9a519baa7d4a8912d508575abca58fdab8ee9..fffa8bdbe4478ef40e50727270ed39edf875a6ea 100644 (file)
 #include "preproc.h"
 #include "parser.h"
 
+#ifdef DMALLOC
+# include <dmalloc.h>
+#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;
 }
 
index 6973afbe3e2cd0bf1e81c9d4350fc5a0954c1915..b868b67851e6566f073f420940cf0bfe1b5da14a 100644 (file)
@@ -177,12 +177,12 @@ WS       [ \t\r]
 
 <DIRECTIVE>[a-z]+   {
     BEGIN DIRECTIVE2;
-    yylval.str_val = xstrdup(yytext);
+    yylval.str_val = yytext;
     return DIRECTIVE_NAME;
 }
     /* everything printable except for ' ', '[' and ']'. */
 <DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
-    yylval.str_val = xstrdup(yytext);
+    yylval.str_val = yytext;
     return DIRECTIVE_VAL;
 }
 <DIRECTIVE>. {
index 33180b3ce1dabff17646da1c1821c70060f67e1d..63604b906396bdc8b232c7b49b5fb5d20abb500b 100644 (file)
@@ -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];
        }
     }
index 33180b3ce1dabff17646da1c1821c70060f67e1d..63604b906396bdc8b232c7b49b5fb5d20abb500b 100644 (file)
@@ -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];
        }
     }
index ef2391843c9c1ec65747a9046e2a27e9bcf9d2fb..cedec92428093487c20f1bc714ace139d4227f2f 100644 (file)
@@ -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;
index 1cd3195dc3941e735338bdb1961b887e4e48f43e..4712e439d013c1298fe5fe4840c98ce233e9da85 100644 (file)
@@ -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) */
index 498236ba4eb2bfb316b38f12aaedec8830566801..0a5352c50c0905377de788708c18254fee1bd8ea 100644 (file)
@@ -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;
 
index fc1646531317971fc76d336e145d1e7e46b42c57..d2cd383cc43b239777db633c9c61b3f89d5c7a41 100644 (file)
@@ -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
index 33180b3ce1dabff17646da1c1821c70060f67e1d..63604b906396bdc8b232c7b49b5fb5d20abb500b 100644 (file)
@@ -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];
        }
     }
index 8f516a8e61b3d339e63cd429518762fa70fe3d98..03ef07e0589a39a9110c9eedf9d1e52472286dff 100644 (file)
@@ -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;
 }
index 8f516a8e61b3d339e63cd429518762fa70fe3d98..03ef07e0589a39a9110c9eedf9d1e52472286dff 100644 (file)
@@ -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;
 }
index b42d331b18cc335ad381c1cddd22e0e9afa0fc9a..45e76049ca6e8d9c77f64261562876e0ed093e54 100644 (file)
@@ -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;
 }
 
index 234e6784c51fd3bf3de8f09c8ceb865ac51eb82f..9846e2cfedfc94a1aa69feced9e8a87622423408 100644 (file)
@@ -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);
index 234e6784c51fd3bf3de8f09c8ceb865ac51eb82f..9846e2cfedfc94a1aa69feced9e8a87622423408 100644 (file)
@@ -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);
index a4d9a519baa7d4a8912d508575abca58fdab8ee9..fffa8bdbe4478ef40e50727270ed39edf875a6ea 100644 (file)
 #include "preproc.h"
 #include "parser.h"
 
+#ifdef DMALLOC
+# include <dmalloc.h>
+#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;
 }
 
index a4d9a519baa7d4a8912d508575abca58fdab8ee9..fffa8bdbe4478ef40e50727270ed39edf875a6ea 100644 (file)
 #include "preproc.h"
 #include "parser.h"
 
+#ifdef DMALLOC
+# include <dmalloc.h>
+#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;
 }
 
index 6973afbe3e2cd0bf1e81c9d4350fc5a0954c1915..b868b67851e6566f073f420940cf0bfe1b5da14a 100644 (file)
@@ -177,12 +177,12 @@ WS       [ \t\r]
 
 <DIRECTIVE>[a-z]+   {
     BEGIN DIRECTIVE2;
-    yylval.str_val = xstrdup(yytext);
+    yylval.str_val = yytext;
     return DIRECTIVE_NAME;
 }
     /* everything printable except for ' ', '[' and ']'. */
 <DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
-    yylval.str_val = xstrdup(yytext);
+    yylval.str_val = yytext;
     return DIRECTIVE_VAL;
 }
 <DIRECTIVE>. {
index 52d62a2df3ceef55bec4e80f2723c8946d28ca42..90608419febaffa5fad003ed80892523e0d76bdc 100644 (file)
@@ -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(&sect->bc);
+    xfree(sect);
+}
+
 void
 section_print(const section *sect)
 {
index 19438df32d857c04ae223c564516b4b8d857b896..ff99fb9d49a6f0e2d40357632767ebcec88c58ea 100644 (file)
@@ -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
index 1426fc096dcb3d883f07e66ccbecd38601ef959b..698e9869ca0e6b4cbb4579d38343f525a21df6b8 100644 (file)
@@ -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)
 {
index 60ed516e79eeee85db812266f2e8ed95e6a907e9..c4a94f14ca7144816018b667fc4836d09ad81cd6 100644 (file)
@@ -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
index 96083c3290601d1dfefe9d4751cfad7a3414c7ab..9447bab9d544a31874e0009376ea979f3347331a 100644 (file)
@@ -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);
     }
 }
index e9f78b80a4c62f736798a7f7c6dbb2b554b16ef9..7ae54bf3556edce3807ee95c891c38b320d26f6e 100644 (file)
@@ -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. */