From 555c5e8b851becc08ba661a9cb19f617d5a00c12 Mon Sep 17 00:00:00 2001 From: j8takagi Date: Mon, 13 Dec 2010 00:34:48 +0900 Subject: [PATCH] =?utf8?q?=E3=83=A1=E3=83=A2=E3=83=AA=E7=AE=A1=E7=90=86?= =?utf8?q?=E3=81=AE=E6=94=B9=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit メモリ管理用に、cmem.hとcmem.hを独立/追加 不要になった領域をfree()で解放 malloc_chk時に、memsetで領域を0で埋める --- include/casl2.h | 1 + include/cerr.h | 13 +------------ include/cmem.h | 28 ++++++++++++++++++++++++++++ include/word.h | 1 + src/Makefile | 28 ++++++++++++++++------------ src/assemble.c | 2 ++ src/casl2.c | 7 +++++-- src/cerr.c | 46 ++++++---------------------------------------- src/cmd.c | 18 ++++++++++++------ src/cmem.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/exec.c | 2 ++ src/label.c | 4 ++-- src/struct.c | 8 ++++---- src/token.c | 39 ++++++++++++++++++++------------------- src/word.c | 11 ++++++----- test/unit/TEST.mk | 2 +- 16 files changed, 154 insertions(+), 103 deletions(-) create mode 100644 include/cmem.h create mode 100644 src/cmem.c diff --git a/include/casl2.h b/include/casl2.h index fa8ec3b..aee7f1e 100644 --- a/include/casl2.h +++ b/include/casl2.h @@ -11,6 +11,7 @@ #include "word.h" #include "hash.h" +#include "cmem.h" #include "cerr.h" #ifndef ARRAYSIZE diff --git a/include/cerr.h b/include/cerr.h index ee44ee4..662cff2 100644 --- a/include/cerr.h +++ b/include/cerr.h @@ -6,23 +6,12 @@ #include #include #include +#include "cmem.h" #ifndef ARRAYSIZE #define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0])) #endif -/* mallocを実行し、メモリを確保できない場合は */ -/* エラーを出力して終了 */ -void *malloc_chk(size_t size, char *tag); - -/* callocを実行し、メモリを確保できない場合は */ -/* エラーを出力して終了 */ -void *calloc_chk(size_t nmemb, size_t size, char *tag); - -/* malloc_chkを実行してメモリを確保してから、 */ -/* コピーした文字列を返す */ -char *strdup_chk(const char *s, char *tag); - /* エラーの構造体 */ typedef struct { int num; /* エラー番号 */ diff --git a/include/cmem.h b/include/cmem.h new file mode 100644 index 0000000..2e7cd3c --- /dev/null +++ b/include/cmem.h @@ -0,0 +1,28 @@ +#ifndef YACASL2_CMEM_H_INCLUDED +#define YACASL2_CMEM_H_INCLUDED + +#include +#include +#include +#include +#include + +#ifndef ARRAYSIZE +#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0])) +#endif + +/* mallocを実行し、メモリを確保できない場合は */ +/* エラーを出力して終了 */ +void *malloc_chk(size_t size, char *tag); + +/* callocを実行し、メモリを確保できない場合は */ +/* エラーを出力して終了 */ +void *calloc_chk(size_t nmemb, size_t size, char *tag); + +/* malloc_chkを実行してメモリを確保してから、 */ +/* コピーした文字列を返す */ +char *strdup_chk(const char *s, char *tag); + +/* メモリがNULLの場合は解放 */ +void free_chk(void *ptr, char *tag); +#endif diff --git a/include/word.h b/include/word.h index c1efb67..7f11c5e 100644 --- a/include/word.h +++ b/include/word.h @@ -8,6 +8,7 @@ #include #include +#include "cmem.h" #include "cerr.h" /* wordのエラー定義 */ diff --git a/src/Makefile b/src/Makefile index 48254ab..ca967d9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,34 +1,38 @@ INCLUDE = ../include CC = gcc CFLAGS = -g -Wall -I $(INCLUDE) -HASHSRC = hash.o -CERRSRC = cerr.o -WORDSRC = word.o -COMMONSRC = $(WORDSRC) $(HASHSRC) $(CERRSRC) struct.o cmd.o -ASSRC = assemble.o token.o label.o macro.o -EXECSRC = exec.o dump.o +WORDOBJ = word.o +HASHOBJ = hash.o +CMEMOBJ = cmem.o +CERROBJ = cerr.o +COMMONOBJ = $(WORDOBJ) $(HASHOBJ) $(CMEMOBJ) $(CERROBJ) struct.o cmd.o +ASOBJ = assemble.o token.o label.o macro.o +EXECOBJ = exec.o dump.o +COMMONHEAD = $(INCLUDE)/casl2.h $(INCLUDE)/word.h $(INCLUDE)/hash.h $(INCLUDE)/cmem.h $(INCLUDE)/cerr.h +ASHEAD = $(INCLUDE)/assemble.h +EXECHEAD = $(INCLUDE)/exec.h .PHONY: all clean all: ../casl2 ../comet2 ../dumpword -../casl2: casl2.o $(COMMONSRC) $(ASSRC) $(EXECSRC) +../casl2: casl2.o $(COMMONOBJ) $(ASOBJ) $(EXECOBJ) $(CC) $(CFLAGS) -o $@ $^ -../comet2: comet2.o $(COMMONSRC) $(EXECSRC) +../comet2: comet2.o $(COMMONOBJ) $(EXECOBJ) $(CC) $(CFLAGS) -o $@ $^ -../dumpword: dumpword.o $(WORDSRC) $(CERRSRC) +../dumpword: dumpword.o $(WORDOBJ) $(CMEMOBJ) $(CERROBJ) $(CC) $(CFLAGS) -o $@ $^ %.o: %.c $(CC) -c $(CFLAGS) $< -casl2.o comet2.o $(COMMONSRC) $(ASSRC) $(EXECSRC): $(INCLUDE)/casl2.h $(INCLUDE)/word.h $(INCLUDE)/hash.h $(INCLUDE)/cerr.h +casl2.o comet2.o $(COMMONOBJ) $(ASOBJ) $(EXECOBJ): $(COMMONHEAD) -casl2.o $(ASSRC): $(INCLUDE)/assemble.h +casl2.o $(ASOBJ): $(ASHEAD) -comet2.o $(EXECSRC): $(INCLUDE)/exec.h +comet2.o $(EXECOBJ): $(EXECHEAD) TAGS: $(INCLUDE)/*.h *.c @if test `which etags`; then etags $^; fi diff --git a/src/assemble.c b/src/assemble.c index 42ef345..6d67955 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -470,6 +470,8 @@ bool assemble(const char *file, PASS pass) if(cerr->num > 0) { break; } + free_chk(line, "line"); + free_chk(cmdl, "cmdl"); } if(cerr->num > 0) { fprintf(stderr, "Assemble error - %d: %s\n", cerr->num, cerr->msg); diff --git a/src/casl2.c b/src/casl2.c index 40001ea..7569f92 100644 --- a/src/casl2.c +++ b/src/casl2.c @@ -128,7 +128,7 @@ int main(int argc, char *argv[]) for(pass = FIRST; pass <= SECOND; pass++) { if(pass == FIRST) { create_cmdtype_code(); /* 命令と命令タイプがキーのハッシュ表を作成 */ - asprop = malloc_chk(sizeof(ASPROP), "asprop"); + asprop = malloc_chk(sizeof(ASPROP), "asprop"); /* アセンブル時のプロパティ用の領域確保 */ } for(i = optind; i < argc; i++) { /* データの格納開始位置 */ @@ -155,8 +155,10 @@ int main(int argc, char *argv[]) } } if(pass == SECOND) { - free_cmdtype_code(); /* 命令と命令タイプがキーのハッシュ表を解放 */ freelabel(); /* ラベルハッシュ表を解放 */ + free_chk(asprop->prog, "asprop.prog"); /* プログラム名を解放 */ + free_chk(asprop, "asprop"); /* アセンブル時のプロパティを解放 */ + free_cmdtype_code(); /* 命令と命令タイプがキーのハッシュ表を解放 */ } } if(res == true) { @@ -174,6 +176,7 @@ int main(int argc, char *argv[]) if(cerr->num > 0) { status = -1; } + free_chk(objfile, "objfile"); /* エラーの解放 */ freecerr(); return status; diff --git a/src/cerr.c b/src/cerr.c index 9906739..02b6a3b 100644 --- a/src/cerr.c +++ b/src/cerr.c @@ -1,31 +1,5 @@ #include "cerr.h" -/* mallocを実行し、メモリを確保できない場合は */ -/* エラーを出力して終了 */ -void *malloc_chk(size_t size, char *tag) -{ - void *p; - - if((p = malloc(size)) == NULL) { - fprintf(stderr, "%s: cannot allocate memory\n", tag); - exit(-1); - } - return p; -} - -/* callocを実行し、メモリを確保できない場合は */ -/* エラーを出力して終了 */ -void *calloc_chk(size_t nmemb, size_t size, char *tag) -{ - void *p; - - if((p = calloc(nmemb, size)) == NULL) { - fprintf(stderr, "%s: cannot allocate memory\n", tag); - exit(-1); - } - return p; -} - /* エラーの初期化 */ void cerr_init() { @@ -33,18 +7,6 @@ void cerr_init() cerr->num = 0; } -/* malloc_chkを実行してメモリを確保してから、 */ -/* コピーした文字列を返す */ -char *strdup_chk(const char *s, char *tag) -{ - assert(s != NULL); - char *t; - - t = malloc_chk(strlen(s) + 1, tag); - strcpy(t, s); - return t; -} - /* 現在のエラー */ CERR *cerr; @@ -79,7 +41,9 @@ bool addcerrlist(int newerrc, CERR newerrv[]) /* 現在のエラーを設定する */ void setcerr(int num, const char *str) { + /* 現在のエラー番号を設定 */ cerr->num = num; + /* 現在のエラーメッセージを設定 */ cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg"); if(str != NULL && strlen(str) <= CERRSTRSIZE) { sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num)); @@ -109,9 +73,11 @@ void freecerr() /* エラーリストを解放 */ while(p != NULL) { q = p->next; - free(p); + free_chk(p, "freecerr.p"); p = q; } + /* 現在のエラーメッセージを解放 */ + free_chk(cerr->msg, "cerr.msg"); /* 現在のエラーを解放 */ - free(cerr); + free_chk(cerr, "cerr"); } diff --git a/src/cmd.c b/src/cmd.c index eff58de..add169a 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -48,17 +48,23 @@ CMDTAB **cmdtype_code, **code_type; /* 命令と命令タイプからハッシュ値を生成する */ unsigned hash_cmdtype(const char *cmd, CMDTYPE type) { HKEY *keys[2]; + unsigned hashval; /* 命令をセット */ - keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key"); + keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[0]"); keys[0]->type = CHARS; - keys[0]->val.s = strdup_chk(cmd, "keys[0].val"); + keys[0]->val.s = strdup_chk(cmd, "keys[0].val.s"); /* 命令タイプをセット */ - keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key"); + keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.keys[1]"); keys[1]->type = INT; keys[1]->val.i = (int)(type & 070); + /* ハッシュ値の計算 */ + hashval = hash(2, keys, cmdtabsize); + free_chk(keys[0]->val.s, "keys[0].val.s"); + free_chk(keys[0], "keys[0]"); + free_chk(keys[1], "keys[1]"); /* ハッシュ値を返す */ - return hash(2, keys, cmdtabsize); + return hashval; } /* 命令と命令タイプがキーのハッシュ表を作成する */ @@ -112,11 +118,11 @@ void free_cmdtype_code() np = cmdtype_code[i]; while(np != NULL) { nq = np->next; - free(np); + free_chk(np, "free_cmdtype_code.np"); np = nq; } } - free(cmdtype_code); + free_chk(cmdtype_code, "cmdtype_code"); } /* 命令コードからハッシュ値を生成する */ diff --git a/src/cmem.c b/src/cmem.c new file mode 100644 index 0000000..b83c79c --- /dev/null +++ b/src/cmem.c @@ -0,0 +1,47 @@ +#include "cmem.h" + +/* mallocを実行し、0で初期化 */ +/* メモリを確保できない場合はエラーを出力して終了 */ +void *malloc_chk(size_t size, char *tag) +{ + void *p; + + if((p = malloc(size)) == NULL) { + fprintf(stderr, "%s: cannot allocate memory\n", tag); + exit(-1); + } + return memset(p, 0, size); +} + +/* callocを実行 */ +/* メモリを確保できない場合はエラーを出力して終了 */ +void *calloc_chk(size_t nmemb, size_t size, char *tag) +{ + void *p; + + if((p = calloc(nmemb, size)) == NULL) { + fprintf(stderr, "%s: cannot allocate memory\n", tag); + exit(-1); + } + return p; +} + +/* malloc_chkを実行してメモリを確保してから、 */ +/* コピーした文字列を返す */ +char *strdup_chk(const char *s, char *tag) +{ + assert(s != NULL); + char *t; + + t = malloc_chk(strlen(s) + 1, tag); + strcpy(t, s); + return t; +} + +/* メモリがNULLの場合は解放 */ +void free_chk(void *ptr, char *tag) +{ + if(ptr != NULL) { + free(ptr); + } +} diff --git a/src/exec.c b/src/exec.c index da6fbad..35aec47 100644 --- a/src/exec.c +++ b/src/exec.c @@ -41,6 +41,7 @@ void svcin() sys->memory[sys->cpu->gr[1]+i] = *(buffer + i); } sys->memory[sys->cpu->gr[2]] = i + 1; + free_chk(buffer, "buffer"); } /* 標準出力へ文字データを書出(SVC 2) */ @@ -347,6 +348,7 @@ bool exec() val = sys->memory[val]; } } + free_chk(errpr, "errpr"); /* 主オペランドが1〜4の場合、第2ビットを無視 */ if(op >= 0x1000 && op <= 0x4FFF) { op &= 0xFB00; diff --git a/src/label.c b/src/label.c index c76c3a7..1b9b806 100644 --- a/src/label.c +++ b/src/label.c @@ -117,8 +117,8 @@ void freelabel() if(np->prog != NULL) { free(np->prog); } - free(np->label); - free(np); + free_chk(np->label, "np.label"); + free_chk(np, "np"); } } } diff --git a/src/struct.c b/src/struct.c index 8e60601..9e3d256 100644 --- a/src/struct.c +++ b/src/struct.c @@ -31,8 +31,8 @@ void reset(int memsize, int clocks) /* COMET II仮想マシンのシャットダウン */ void shutdown() { - free(prog); - free(sys->memory); - free(sys->cpu); - free(sys); + free_chk(prog, "prog"); + free_chk(sys->memory, "sys.memory"); + free_chk(sys->cpu, "sys.cpu"); + free_chk(sys, "sys"); } diff --git a/src/token.c b/src/token.c index b9ff352..02e304d 100644 --- a/src/token.c +++ b/src/token.c @@ -5,60 +5,61 @@ OPD *opdtok(const char *str) { OPD *opd = malloc_chk(sizeof(OPD), "opd"); - char *p, *q, *sepp; - int sepc = ',', qcnt = 0; + char *p, *q, *r, *sepp; /* pは文字列全体の先頭位置、qはトークンの先頭位置、rは文字の位置 */ + int sepc = ',', rcnt = 0; bool quoting = false; opd->opdc = 0; if(str == NULL) { return opd; } - p = q = strdup_chk(str, "opdtopk.p"); + p = q = r = strdup_chk(str, "opdtopk.p"); do { /* オペランド数が多すぎる場合はエラー */ if(opd->opdc >= OPDSIZE) { setcerr(117, NULL); /* operand is too many */ break; } - /* 先頭が「=」の場合の処理 */ - if(*q == '=') { - q++; + /* 先頭が「=」の場合 */ + if(*r == '=') { + r++; } /* 「'」の場合 */ - if(*q == '\'') { + if(*r == '\'') { /* 「''」以外の場合はquote値を反転 */ - if(*(q+1) != '\'' && !(p < q && *(q-1) == '\'')) { + if(*(r+1) != '\'' && !(q < r && *(r-1) == '\'')) { quoting = !quoting; } - /* 「'」の分、文字列の長さを小さくする */ - if(*(q+1) != '\'') { - qcnt++; + /* 文字列の長さを数える。「'」の場合は数えない */ + if(*(r+1) != '\'') { + rcnt++; } } if(quoting == true) { /* 閉じ「'」がないまま文字列が終了した場合 */ - if(*q == '\0') { + if(*r == '\0') { setcerr(123, str); /* unclosed quote */ break; } - q++; + r++; } else { - sepp = q + strcspn(q, ", "); + sepp = r + strcspn(r, ", "); sepc = *sepp; *sepp = '\0'; - if(*p == '\0') { + if(*q == '\0') { setcerr(121, NULL); /* cannot get operand token */ break; } - if(strlen(p) - qcnt > OPDSIZE) { + if(strlen(q) - rcnt > OPDSIZE) { setcerr(118, NULL); /* operand length is too long */ break; } - opd->opdv[(++opd->opdc)-1] = strdup_chk(p, "opd.opdv[]"); - p = q = sepp + 1; - qcnt = 0; + opd->opdv[(++opd->opdc)-1] = strdup_chk(q, "opd.opdv[]"); + q = r = sepp + 1; + rcnt = 0; } } while(sepc == ','); + free_chk(p, "opdtok.p"); return opd; } diff --git a/src/word.c b/src/word.c index cf841ce..5f49cc4 100644 --- a/src/word.c +++ b/src/word.c @@ -76,17 +76,18 @@ char *word2n(WORD word) enum { MAXLEN = 6, /* WORD値を10進数で表したときの最大桁数 */ }; - char *p = malloc_chk(MAXLEN, "word2n.p"), *q = malloc_chk(MAXLEN, "word2n.q"); + char *p = malloc_chk(MAXLEN, "word2n.p"), *digit = malloc_chk(MAXLEN, "word2n.digit"); int i = 0, j; do{ *(p + i++) = word % 10 + '0'; } while((word /= 10) > 0); for(j = 0; j < i; j++) { - *(q + j) = *(p + (i - 1) - j); + *(digit + j) = *(p + (i - 1) - j); } - *(q + j + 1) = '\0'; - return q; + *(digit + j + 1) = '\0'; + free_chk(p, "word2n.p"); + return digit; } /* WORD値を2進数の文字列に変換 */ @@ -98,7 +99,7 @@ char *word2bit(const WORD word) WORD mask = 0x8000; char *bit, *p; - p = bit = malloc_chk(MAXLEN + 1, "word2bit.bit"); + bit = p = malloc_chk(MAXLEN + 1, "word2bit.bit"); do { *p++ = (word & mask) ? '1' : '0'; } while((mask >>= 1) > 0); diff --git a/test/unit/TEST.mk b/test/unit/TEST.mk index 2a26dde..fbda62a 100644 --- a/test/unit/TEST.mk +++ b/test/unit/TEST.mk @@ -11,7 +11,7 @@ SRCDIR = ../../../src INCLUDE = ../../../include CC = gcc CFLAGS = -g -Wall -I $(INCLUDE) -COMMONSRC = $(SRCDIR)/word.o $(SRCDIR)/struct.o $(SRCDIR)/hash.o $(SRCDIR)/cmd.o $(SRCDIR)/cerr.o +COMMONSRC = $(SRCDIR)/word.o $(SRCDIR)/struct.o $(SRCDIR)/hash.o $(SRCDIR)/cmd.o $(SRCDIR)/cmem.o $(SRCDIR)/cerr.o ASSRC = $(SRCDIR)/assemble.o $(SRCDIR)/token.o $(SRCDIR)/label.o $(SRCDIR)/macro.o EXECSRC = $(SRCDIR)/exec.o $(SRCDIR)/dump.o -- 2.18.0