From ede51255344cb1cd5859fb24cae2e87692ca0887 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 19 Nov 2013 00:19:20 +0200 Subject: [PATCH] add .asm function renamer --- tools/Makefile | 6 + tools/asmproc.c | 233 +++++++++++++++++++++++++++ cmpmrg_text.c => tools/cmpmrg_text.c | 22 +-- tools/my_assert.h | 22 +++ 4 files changed, 263 insertions(+), 20 deletions(-) create mode 100644 tools/Makefile create mode 100644 tools/asmproc.c rename cmpmrg_text.c => tools/cmpmrg_text.c (96%) create mode 100644 tools/my_assert.h diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..7c03266 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,6 @@ +CFLAGS += -Wall -ggdb + +all: asmproc cmpmrg_text + +clean: + $(RM) asmproc cmpmrg_text diff --git a/tools/asmproc.c b/tools/asmproc.c new file mode 100644 index 0000000..911fe58 --- /dev/null +++ b/tools/asmproc.c @@ -0,0 +1,233 @@ +#include +#include +#include + +#include "my_assert.h" + +static int my_isblank(char c) +{ + return c == '\t' || c == ' ' || c == '\r' || c == '\n'; +} + +static char *sskip(char *s) +{ + while (my_isblank(*s)) + s++; + + return s; +} + +static char *next_word(char *w, size_t wsize, char *s) +{ + size_t i; + + s = sskip(s); + + for (i = 0; i < wsize - 1; i++) { + if (*s == 0 || my_isblank(s[i])) + break; + w[i] = s[i]; + } + w[i] = 0; + + if (*s != 0 && !my_isblank(s[i])) + printf("warning: '%s' truncated\n", w); + + return s + i; +} + +struct sl_item { + char *name; + int is_replace; +}; + +static int cmp_sym(const void *p1_, const void *p2_) +{ + const struct sl_item *p1 = p1_, *p2 = p2_; + const char *s1 = p1->name, *s2 = p2->name; + int i; + + for (i = 0; ; i++) { + if (s1[i] == s2[i]) + continue; + + if (s1[i] == 0) { + if (s2[i] == 0 || s2[i] == '@') + break; + } + + if (s2[i] == 0 || s1[i] == '@') + break; + + return s1[i] - s2[i]; + } + + return 0; +} + +static int cmp_sym_sort(const void *p1_, const void *p2_) +{ + const struct sl_item *p1 = p1_, *p2 = p2_; + const char *s1 = p1->name, *s2 = p2->name; + int ret; + + ret = cmp_sym(p1_, p2_); + if (ret == 0) { + printf("%s: dupe sym: '%s' '%s'\n", __func__, s1, s2); + exit(1); + } + return ret; +} + +void read_list(struct sl_item **sl_in, int *cnt, int *alloc, FILE *f, int is_repl) +{ + struct sl_item *sl = *sl_in; + int c = *cnt; + char line[256]; + char word[256]; + char *r; + + while (fgets(line, sizeof(line), f) != NULL) { + r = next_word(word, sizeof(word), line); + if (r == word) + continue; + + sl[c].name = strdup(word); + sl[c].is_replace = is_repl; + c++; + + if (c >= *alloc) { + *alloc *= 2; + sl = realloc(sl, *alloc * sizeof(sl[0])); + my_assert_not(sl, NULL); + } + } + + *sl_in = sl; + *cnt = c; +} + +int main(int argc, char *argv[]) +{ + struct sl_item *symlist, *sym, ssym; + FILE *fout, *fin, *f; + int symlist_alloc; + int symlist_cnt; + char line[256]; + char word[256]; + char word2[256]; + char word3[256]; + char word4[256]; + char *p; + + if (argc != 5) { + // rmlist - prefix func with 'rm_', callsites with '_' + // renlist - prefix func and callsites with 'rm_' + printf("usage:\n%s \n", + argv[0]); + return 1; + } + + symlist_alloc = 16; + symlist_cnt = 0; + symlist = malloc(symlist_alloc * sizeof(symlist[0])); + my_assert_not(symlist, NULL); + + f = fopen(argv[3], "r"); + my_assert_not(f, NULL); + read_list(&symlist, &symlist_cnt, &symlist_alloc, f, 1); + fclose(f); + + f = fopen(argv[4], "r"); + my_assert_not(f, NULL); + read_list(&symlist, &symlist_cnt, &symlist_alloc, f, 0); + fclose(f); + + qsort(symlist, symlist_cnt, sizeof(symlist[0]), cmp_sym_sort); + +printf("symlist:\n"); +int i; +for (i = 0; i < symlist_cnt; i++) + printf("%d '%s'\n", symlist[i].is_replace, symlist[i].name); + + fin = fopen(argv[2], "r"); + my_assert_not(fin, NULL); + + fout = fopen(argv[1], "w"); + my_assert_not(fout, NULL); + + while (fgets(line, sizeof(line), fin)) + { + p = sskip(line); + if (*p == 0 || *p == ';') + goto pass; + + p = sskip(next_word(word, sizeof(word), p)); + if (*p == 0 || *p == ';') + goto pass; // need at least 2 words + + p = next_word(word2, sizeof(word2), p); + + if (!strcasecmp(word2, "proc") || !strcasecmp(word2, "endp")) { + ssym.name = word; + sym = bsearch(&ssym, symlist, symlist_cnt, + sizeof(symlist[0]), cmp_sym); + if (sym != NULL) { + fprintf(fout, "rm_%s\t%s%s", word, word2, p); + continue; + } + } + + if (!strcasecmp(word, "call") || !strcasecmp(word, "jmp")) { + ssym.name = word2; + sym = bsearch(&ssym, symlist, symlist_cnt, + sizeof(symlist[0]), cmp_sym); + if (sym != NULL) { + fprintf(fout, "\t\t%s\t%s%s%s", word, + sym->is_replace ? "_" : "rm_", word2, p); + continue; + } + } + + p = sskip(p); + if (*p == 0 || *p == ';') + goto pass; // need at least 3 words + + p = next_word(word3, sizeof(word3), p); + + if (!strcasecmp(word, "dd") && !strcasecmp(word2, "offset")) { + ssym.name = word3; + sym = bsearch(&ssym, symlist, symlist_cnt, + sizeof(symlist[0]), cmp_sym); + if (sym != NULL) { + fprintf(fout, "\t\tdd offset %s%s", word3, p); + continue; + } + } + + p = sskip(p); + if (*p == 0 || *p == ';') + goto pass; // need at least 4 words + + p = next_word(word4, sizeof(word4), p); + + if (!strcasecmp(word2, "dd") && !strcasecmp(word3, "offset")) { + ssym.name = word4; + sym = bsearch(&ssym, symlist, symlist_cnt, + sizeof(symlist[0]), cmp_sym); + if (sym != NULL) { + fprintf(fout, "%s\tdd offset %s%s%s", word, + sym->is_replace ? "_" : "rm_", word4, p); + continue; + } + } + +pass: + fwrite(line, 1, strlen(line), fout); + } + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/cmpmrg_text.c b/tools/cmpmrg_text.c similarity index 96% rename from cmpmrg_text.c rename to tools/cmpmrg_text.c index a7191b3..0bd858a 100644 --- a/cmpmrg_text.c +++ b/tools/cmpmrg_text.c @@ -5,6 +5,8 @@ #include #include +#include "my_assert.h" + /* http://www.delorie.com/djgpp/doc/coff/ */ typedef struct { @@ -70,26 +72,6 @@ struct my_symtab { char *name; }; -static void my_assert_(int line, const char *name, long v, long expect, int is_eq) -{ - int ok; - if (is_eq) - ok = (v == expect); - else - ok = (v != expect); - - if (!ok) - { - printf("%d: '%s' is %lx, need %s%lx\n", line, name, - v, is_eq ? "" : "!", expect); - exit(1); - } -} -#define my_assert(v, exp) \ - my_assert_(__LINE__, #v, (long)(v), (long)(exp), 1) -#define my_assert_not(v, exp) \ - my_assert_(__LINE__, #v, (long)(v), (long)(exp), 0) - static int symt_cmp(const void *p1_, const void *p2_) { const struct my_symtab *p1 = p1_, *p2 = p2_; diff --git a/tools/my_assert.h b/tools/my_assert.h new file mode 100644 index 0000000..b8b0252 --- /dev/null +++ b/tools/my_assert.h @@ -0,0 +1,22 @@ + +static inline void my_assert_(int line, const char *name, long v, long expect, int is_eq) +{ + int ok; + if (is_eq) + ok = (v == expect); + else + ok = (v != expect); + + if (!ok) + { + printf("%d: '%s' is %lx, need %s%lx\n", line, name, + v, is_eq ? "" : "!", expect); + exit(1); + } +} +#define my_assert(v, exp) \ + my_assert_(__LINE__, #v, (long)(v), (long)(exp), 1) +#define my_assert_not(v, exp) \ + my_assert_(__LINE__, #v, (long)(v), (long)(exp), 0) + + -- 2.39.5