From bfa4a6ee2ef942b4eaf30eb20153ad5404bb2951 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 7 Dec 2013 03:26:26 +0200 Subject: [PATCH] func blacklisting, fixes --- tools/Makefile | 3 + tools/translate.c | 161 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 129 insertions(+), 35 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index d2fa856..21ef2ea 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,4 +1,7 @@ CFLAGS += -Wall -ggdb +ifndef DEBUG +CFLAGS += -O2 +endif T = asmproc cmpmrg_text mkbridge translate diff --git a/tools/translate.c b/tools/translate.c index dd7ccb1..22fe560 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -412,7 +412,9 @@ static int parse_operand(struct parsed_opr *opr, aerr("[] parse failure\n"); parse_indmode(opr->name, regmask_indirect, 1); - if (opr->lmod == OPLM_UNSPEC && !strncmp(opr->name, "ebp+", 4)) { + if (opr->lmod == OPLM_UNSPEC && !strncmp(opr->name, "ebp+", 4) + && !('0' <= opr->name[4] && opr->name[4] <= '9')) + { // might be an equ struct parsed_equ *eq = equ_find(NULL, opr->name + 4); if (eq) @@ -565,7 +567,7 @@ static const struct { static void parse_op(struct parsed_op *op, char words[16][256], int wordc) { - enum opr_lenmod lmod; + enum opr_lenmod lmod = OPLM_UNSPEC; int prefix_flags = 0; int regmask_ind; int regmask; @@ -847,7 +849,9 @@ static char *out_src_opr(char *buf, size_t buf_size, break; case OPT_REGMEM: - if (g_bp_frame && !strncmp(popr->name, "ebp+", 4)) { + if (g_bp_frame && !strncmp(popr->name, "ebp+", 4) + && !('0' <= popr->name[4] && popr->name[4] <= '9')) + { bg_frame_access(po, popr->lmod, buf, buf_size, popr->name + 4, 1, is_lea); break; @@ -937,7 +941,9 @@ static char *out_dst_opr(char *buf, size_t buf_size, break; case OPT_REGMEM: - if (g_bp_frame && !strncmp(popr->name, "ebp+", 4)) { + if (g_bp_frame && !strncmp(popr->name, "ebp+", 4) + && !('0' <= popr->name[4] && popr->name[4] <= '9')) + { bg_frame_access(po, popr->lmod, buf, buf_size, popr->name + 4, 0, 0); break; @@ -945,6 +951,10 @@ static char *out_dst_opr(char *buf, size_t buf_size, return out_src_opr(buf, buf_size, po, popr, 0); + case OPT_LABEL: + snprintf(buf, buf_size, "%s", popr->name); + break; + default: ferr(po, "invalid dst type: %d\n", popr->type); } @@ -2122,34 +2132,107 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) proto_release(&g_func_pp); } +// '=' needs special treatment.. +static char *next_word_s(char *w, size_t wsize, char *s) +{ + size_t i; + + s = sskip(s); + + for (i = 0; i < wsize - 1; i++) { + if (s[i] == 0 || my_isblank(s[i]) || (s[i] == '=' && i > 0)) + break; + w[i] = s[i]; + } + w[i] = 0; + + if (s[i] != 0 && !my_isblank(s[i]) && s[i] != '=') + printf("warning: '%s' truncated\n", w); + + return s + i; +} + +static int cmpstringp(const void *p1, const void *p2) +{ + return strcmp(*(char * const *)p1, *(char * const *)p2); +} + int main(int argc, char *argv[]) { - FILE *fout, *fasm, *fhdr; + FILE *fout, *fasm, *fhdr, *frlist; char line[256]; char words[16][256]; int in_func = 0; + int skip_func = 0; int skip_warned = 0; int eq_alloc; + char **rlist = NULL; + int rlist_len = 0; + int rlist_alloc = 0; + int verbose = 0; + int arg_out; + int arg = 1; int pi = 0; int len; char *p; int wordc; - if (argc != 4) { - printf("usage:\n%s <.c> <.asm> \n", + if (argv[1] && IS(argv[1], "-v")) { + verbose = 1; + arg++; + } + + if (argc < arg + 3) { + printf("usage:\n%s [-v] <.c> <.asm> [rlist]*\n", argv[0]); return 1; } - hdrfn = argv[3]; - fhdr = fopen(hdrfn, "r"); - my_assert_not(fhdr, NULL); + arg_out = arg++; - asmfn = argv[2]; + asmfn = argv[arg++]; fasm = fopen(asmfn, "r"); my_assert_not(fasm, NULL); - fout = fopen(argv[1], "w"); + hdrfn = argv[arg++]; + fhdr = fopen(hdrfn, "r"); + my_assert_not(fhdr, NULL); + + rlist_alloc = 64; + rlist = malloc(rlist_alloc * sizeof(rlist[0])); + my_assert_not(rlist, NULL); + // needs special handling.. + rlist[rlist_len++] = "__alloca_probe"; + + for (; arg < argc; arg++) { + frlist = fopen(argv[arg], "r"); + my_assert_not(frlist, NULL); + + while (fgets(line, sizeof(line), frlist)) { + p = sskip(line); + if (*p == 0 || *p == ';' || *p == '#') + continue; + + p = next_word(words[0], sizeof(words[0]), p); + if (words[0][0] == 0) + continue; + + if (rlist_len >= rlist_alloc) { + rlist_alloc = rlist_alloc * 2 + 64; + rlist = realloc(rlist, rlist_alloc * sizeof(rlist[0])); + my_assert_not(rlist, NULL); + } + rlist[rlist_len++] = strdup(words[0]); + } + + fclose(frlist); + frlist = NULL; + } + + if (rlist_len > 0) + qsort(rlist, rlist_len, sizeof(rlist[0]), cmpstringp); + + fout = fopen(argv[arg_out], "w"); my_assert_not(fout, NULL); eq_alloc = 128; @@ -2166,7 +2249,7 @@ int main(int argc, char *argv[]) memset(words, 0, sizeof(words)); for (wordc = 0; wordc < 16; wordc++) { - p = sskip(next_word(words[wordc], sizeof(words[0]), p)); + p = sskip(next_word_s(words[wordc], sizeof(words[0]), p)); if (*p == 0 || *p == ';') { wordc++; break; @@ -2192,6 +2275,9 @@ int main(int argc, char *argv[]) if (in_func) aerr("proc '%s' while in_func '%s'?\n", words[0], g_func); + p = words[0]; + if (bsearch(&p, rlist, rlist_len, sizeof(rlist[0]), cmpstringp)) + skip_func = 1; strcpy(g_func, words[0]); in_func = 1; continue; @@ -2203,9 +2289,13 @@ int main(int argc, char *argv[]) if (!IS(g_func, words[0])) aerr("endp '%s' while in_func '%s'?\n", words[0], g_func); - gen_func(fout, fhdr, g_func, pi); + + if (in_func && !skip_func) + gen_func(fout, fhdr, g_func, pi); + in_func = 0; skip_warned = 0; + skip_func = 0; g_func[0] = 0; if (pi != 0) { memset(&ops, 0, pi * sizeof(ops[0])); @@ -2217,6 +2307,28 @@ int main(int argc, char *argv[]) continue; } + p = strchr(words[0], ':'); + if (p != NULL) { + len = p - words[0]; + if (len > sizeof(g_labels[0]) - 1) + aerr("label too long: %d\n", len); + if (g_labels[pi][0] != 0) + aerr("dupe label?\n"); + memcpy(g_labels[pi], words[0], len); + g_labels[pi][len] = 0; + continue; + } + + if (!in_func || skip_func) { + if (!skip_warned && !skip_func && g_labels[pi][0] != 0) { + if (verbose) + anote("skipping from '%s'\n", g_labels[pi]); + skip_warned = 1; + } + g_labels[pi][0] = 0; + continue; + } + if (IS(words[1], "=")) { if (wordc != 5) aerr("unhandled equ, wc=%d\n", wordc); @@ -2250,27 +2362,6 @@ int main(int argc, char *argv[]) if (pi >= ARRAY_SIZE(ops)) aerr("too many ops\n"); - p = strchr(words[0], ':'); - if (p != NULL) { - len = p - words[0]; - if (len > sizeof(g_labels[0]) - 1) - aerr("label too long: %d\n", len); - if (g_labels[pi][0] != 0) - aerr("dupe label?\n"); - memcpy(g_labels[pi], words[0], len); - g_labels[pi][len] = 0; - continue; - } - - if (!in_func) { - if (!skip_warned && g_labels[pi][0] != 0) { - anote("skipping from '%s'\n", g_labels[pi]); - skip_warned = 1; - } - g_labels[pi][0] = 0; - continue; - } - parse_op(&ops[pi], words, wordc); pi++; } -- 2.39.5