From 4db74a7d9217b7ccd74afe8f96b094fa6f376770 Mon Sep 17 00:00:00 2001 From: j8takagi Date: Sun, 3 Jun 2018 01:23:00 +0900 Subject: [PATCH] =?utf8?q?disassemble=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?utf8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + Makefile | 2 +- as/sample/hello.o | Bin 0 -> 70 bytes as/sample/hello.o.casl | 30 ++++++ as/sample/sum_10.o | Bin 0 -> 40 bytes as/sample/sum_10.o.casl | 16 +++ include/struct.h | 10 ++ src/.gitignore | 1 + src/Makefile | 4 +- src/disassemble.c | 127 ++++++++++++++++++++++++ src/exec.c | 2 +- src/struct.c | 19 +++- test/system/disassemble/Define.mk | 1 + test/system/disassemble/Makefile | 1 + test/system/disassemble/Test.mk | 1 + test/system/disassemble/sum_10/0.txt | 16 +++ test/system/disassemble/sum_10/Makefile | 2 + test/system/disassemble/sum_10/cmd | 1 + 18 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 as/sample/hello.o create mode 100644 as/sample/hello.o.casl create mode 100644 as/sample/sum_10.o create mode 100644 as/sample/sum_10.o.casl create mode 100644 src/disassemble.c create mode 120000 test/system/disassemble/Define.mk create mode 120000 test/system/disassemble/Makefile create mode 120000 test/system/disassemble/Test.mk create mode 100644 test/system/disassemble/sum_10/0.txt create mode 100644 test/system/disassemble/sum_10/Makefile create mode 100755 test/system/disassemble/sum_10/cmd diff --git a/.gitignore b/.gitignore index 123260b..e2eadfc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ /casl2 /comet2 /dumpword +/disassemble *.o +!as/sample/hello.o +!as/sample/sum_10.o *~ GPATH GRTAGS diff --git a/Makefile b/Makefile index 80f8a82..a16c13c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ clean src-clean gtags-clean \ test-clean doc-clean doc_inner-clean -CMD := casl2 comet2 dumpword +CMD := casl2 comet2 dumpword disassemble CAT := cat CP := cp diff --git a/as/sample/hello.o b/as/sample/hello.o new file mode 100644 index 0000000000000000000000000000000000000000..ada8b013ef286b72a047992112a205ccf6aebd78 GIT binary patch literal 70 zcmZQ9U|?VZVgVsx1_dDn28ItzK(-=~tpsK(6bckFG +#include +#define _GNU_SOURCE +#include +#include + +#include "exec.h" +#include "cmem.h" +#include "cerr.h" +#include "package.h" + +char *grstr(WORD word) +{ + char *str; + str = (char *)malloc(4); + sprintf(str, "GR%d", word); + return str; +} + +bool disassemble(const char *file) +{ + FILE *fp; + bool stat = true; + int i = 0; + WORD w, cmd, r, x, r1, r2, adr; + CMDTYPE type = 0; + char *cmdname; + + assert(file != NULL); + if((fp = fopen(file, "rb")) == NULL) { + perror(file); + return false; + } + + create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ + + fprintf(stdout, "MAIN\tSTART\n"); + for( ; !feof(fp); ) { + fread(&w, sizeof(WORD), 1, fp); + cmd = w & 0xFF00; + cmdname = getcmdname(cmd); + if(cmd == 0xFF00 || (w != 0 && cmd == 0x0000)) { + fprintf(stdout, "\tDC\t%d\t\t; #%04X", w, i++); + } else if((type = getcmdtype(cmd)) == R_ADR_X || type == ADR_X) { + fread(&adr, sizeof(WORD), 1, fp); + fprintf(stdout, "\t%s\t", cmdname); + if(type == R_ADR_X) { + r = (w & 0x00F0) >> 4; + fprintf(stdout, "%s,", grstr(r)); + } + fprintf(stdout, "#%04X", adr); + if((x = w & 0x000F) != 0) { + fprintf(stdout, ",%s", grstr(x)); + } + fprintf(stdout, "\t\t; #%04X", i); + i += 2; + } else { + fprintf(stdout, "\t%s", cmdname); + if(type == R1_R2) { + r1 = (w & 0x00F0) >> 4; + r2 = w & 0x000F; + fprintf(stdout, "\t%s,%s", grstr(r1), grstr(r2)); + } else if(type == R_) { + r = (w & 0x00F0) >> 4; + fprintf(stdout, "\t%s", grstr(r)); + } + fprintf(stdout, "\t\t; #%04X", i++); + } + fprintf(stdout, "\n"); + } + fprintf(stdout, "\tEND\n"); + free_code_cmdtype(); + return stat; +} + +/** + * disassembleコマンドのオプション + */ +static struct option longopts[] = { + {"version", no_argument, NULL, 'v' }, + {"help", no_argument, NULL, 'h'}, + {0, 0, 0, 0}, +}; + +/** + * @brief disassembleコマンドのメイン + * + * @return 正常終了時は0、異常終了時は1 + * + * @param argc コマンドライン引数の数 + * @param *argv[] コマンドライン引数の配列 + */ +int main(int argc, char *argv[]) +{ + int opt, stat = 0; + const char *version = PACKAGE_VERSION, *cmdversion = "disassemble of YACASL2 version %s\n"; + const char *usage = "Usage: %s [-vh] FILE\n"; + + cerr_init(); + addcerrlist_load(); + addcerrlist_exec(); + + /* オプションの処理 */ + while((opt = getopt_long(argc, argv, "vh", longopts, NULL)) != -1) { + switch(opt) { + case 'v': + fprintf(stdout, cmdversion, version); + return 0; + case 'h': + fprintf(stdout, usage, argv[0]); + return 0; + case '?': + fprintf(stderr, usage, argv[0]); + exit(1); + } + } + if(argv[optind] == NULL) { + setcerr(211, ""); /* object file not specified */ + fprintf(stderr, "disassemble error - %d: %s\n", cerr->num, cerr->msg); + exit(1); + } + disassemble(argv[optind]); /* プログラム実行 */ + stat = (cerr->num == 0) ? 0 : 1; + /* エラーの解放 */ + freecerr(); + return stat; +} diff --git a/src/exec.c b/src/exec.c index a6c7edc..a447aa7 100644 --- a/src/exec.c +++ b/src/exec.c @@ -237,7 +237,7 @@ bool loadassemble(const char *file) bool stat = true; assert(file != NULL); - if((fp = fopen(file, "r")) == NULL) { + if((fp = fopen(file, "rb")) == NULL) { perror(file); return false; } diff --git a/src/struct.c b/src/struct.c index 981409a..f0f705b 100644 --- a/src/struct.c +++ b/src/struct.c @@ -209,10 +209,27 @@ const void (*getcmdptr(WORD code)) return ptr; } +/** + * 命令コードから命令のタイプを返す + */ +CMDTYPE getcmdtype(WORD code) +{ + CMDTAB *t; + CMDTYPE type = 0; + + for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) { + if(code == t->cmd->code) { + type = t->cmd->type; + break; + } + } + return type; +} + /** * 命令コードから命令の名前を返す */ -char (*getcmdname(WORD code)) +char *getcmdname(WORD code) { CMDTAB *t; char *cmd = NULL; diff --git a/test/system/disassemble/Define.mk b/test/system/disassemble/Define.mk new file mode 120000 index 0000000..b4a58e1 --- /dev/null +++ b/test/system/disassemble/Define.mk @@ -0,0 +1 @@ +../../template/Define.mk \ No newline at end of file diff --git a/test/system/disassemble/Makefile b/test/system/disassemble/Makefile new file mode 120000 index 0000000..4f4e7b0 --- /dev/null +++ b/test/system/disassemble/Makefile @@ -0,0 +1 @@ +../../template/Group.mk \ No newline at end of file diff --git a/test/system/disassemble/Test.mk b/test/system/disassemble/Test.mk new file mode 120000 index 0000000..ada05aa --- /dev/null +++ b/test/system/disassemble/Test.mk @@ -0,0 +1 @@ +../../template/Test.mk \ No newline at end of file diff --git a/test/system/disassemble/sum_10/0.txt b/test/system/disassemble/sum_10/0.txt new file mode 100644 index 0000000..f1bd9f2 --- /dev/null +++ b/test/system/disassemble/sum_10/0.txt @@ -0,0 +1,16 @@ +MAIN START + PUSH #0000,GR1 ; #0000 + LAD GR0,#0000 ; #0002 + LD GR1,#0011 ; #0004 + ADDL GR0,GR1 ; #0006 + ADDL GR1,#0013 ; #0007 + CPL GR1,#0012 ; #0009 + JPL #000F ; #000B + JUMP #0006 ; #000D + POP GR1 ; #000F + RET ; #0010 + DC 1 ; #0011 + DC 10 ; #0012 + DC 1 ; #0013 + DC 1 ; #0014 + END diff --git a/test/system/disassemble/sum_10/Makefile b/test/system/disassemble/sum_10/Makefile new file mode 100644 index 0000000..b6dac59 --- /dev/null +++ b/test/system/disassemble/sum_10/Makefile @@ -0,0 +1,2 @@ +include ../Define.mk +include ../Test.mk diff --git a/test/system/disassemble/sum_10/cmd b/test/system/disassemble/sum_10/cmd new file mode 100755 index 0000000..879a760 --- /dev/null +++ b/test/system/disassemble/sum_10/cmd @@ -0,0 +1 @@ +../../../../disassemble ../../../../as/sample/sum_10.o -- 2.18.0