X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Fcvt_data.c;h=044857bdbef22d761ee8247291915dbbb2ae4417;hb=f0be238a6a7a2801edfb842a637b19bf91b245bd;hp=bddd6ef2306ee7537cb1c15ba85362d0f797373d;hpb=b74c31e30301a2e5c03e2947a5017af28bf94e65;p=ia32rtools.git diff --git a/tools/cvt_data.c b/tools/cvt_data.c index bddd6ef..044857b 100644 --- a/tools/cvt_data.c +++ b/tools/cvt_data.c @@ -18,6 +18,8 @@ static int asmln; static const struct parsed_proto *g_func_sym_pp; static char g_comment[256]; static int g_warn_cnt; +static int g_cconv_novalidate; +static int g_arm_mode; // note: must be in ascending order enum dx_type { @@ -259,9 +261,10 @@ static const struct parsed_proto *check_var(FILE *fhdr, { goto check_sym; } - if (pp->argc_reg != 2 - || !IS(pp->arg[0].reg, "ecx") - || !IS(pp->arg[1].reg, "edx")) + if (!g_cconv_novalidate + && (pp->argc_reg != 2 + || !IS(pp->arg[0].reg, "ecx") + || !IS(pp->arg[1].reg, "edx"))) { awarn("unhandled reg call: %s\n", fp_var); } @@ -311,18 +314,76 @@ check_sym: return pp; } +static void output_decorated_pp(FILE *fout, + const struct parsed_proto *pp) +{ + if (pp->name[0] != '_') + fprintf(fout, pp->is_fastcall ? "@" : "_"); + fprintf(fout, "%s", pp->name); + if (pp->is_stdcall && pp->argc > 0) + fprintf(fout, "@%d", pp->argc * 4); +} + +static int align_value(int src_val) +{ + if (src_val <= 0) { + awarn("bad align: %d\n", src_val); + src_val = 1; + } + if (!g_arm_mode) + return src_val; + + return __builtin_ffs(src_val) - 1; +} + static int cmpstringp(const void *p1, const void *p2) { return strcmp(*(char * const *)p1, *(char * const *)p2); } +/* XXX: maybe move to external file? */ +static const char *unwanted_syms[] = { + "aRuntimeError", + "aTlossError", + "aSingError", + "aDomainError", + "aR6029ThisAppli", + "aR6028UnableToI", + "aR6027NotEnough", + "aR6026NotEnough", + "aR6025PureVirtu", + "aR6024NotEnough", + "aR6019UnableToO", + "aR6018Unexpecte", + "aR6017Unexpecte", + "aR6016NotEnough", + "aAbnormalProgra", + "aR6009NotEnough", + "aR6008NotEnough", + "aR6002FloatingP", + "aMicrosoftVisua", + "aRuntimeErrorPr", + "aThisApplicatio", + "aMicrosoftFindF", + "aMicrosoftOffic", +}; + +static int is_unwanted_sym(const char *sym) +{ + return bsearch(&sym, unwanted_syms, ARRAY_SIZE(unwanted_syms), + sizeof(unwanted_syms[0]), cmpstringp) != NULL; +} + int main(int argc, char *argv[]) { FILE *fout, *fasm, *fhdr, *frlist; const struct parsed_proto *pp; + int no_decorations = 0; + char comment_char = '#'; char words[20][256]; char word[256]; char line[256]; + char last_sym[32]; unsigned long val; unsigned long cnt; const char *sym; @@ -345,11 +406,25 @@ int main(int argc, char *argv[]) char *p2; if (argc < 4) { - printf("usage:\n%s <.s> <.asm> [rlist]*\n", + // -nd: no symbol decorations + printf("usage:\n%s [-nd] [-i] [-a] <.s> <.asm> [rlist]*\n", argv[0]); return 1; } + for (arg = 1; arg < argc; arg++) { + if (IS(argv[arg], "-nd")) + no_decorations = 1; + else if (IS(argv[arg], "-i")) + g_cconv_novalidate = 1; + else if (IS(argv[arg], "-a")) { + comment_char = '@'; + g_arm_mode = 1; + } + else + break; + } + arg_out = arg++; asmfn = argv[arg++]; @@ -399,6 +474,11 @@ int main(int argc, char *argv[]) if (rlist_cnt > 0) qsort(rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp); + qsort(unwanted_syms, ARRAY_SIZE(unwanted_syms), + sizeof(unwanted_syms[0]), cmpstringp); + + last_sym[0] = 0; + while (1) { next_section(fasm, line); if (feof(fasm)) @@ -413,7 +493,7 @@ int main(int argc, char *argv[]) else aerr("unhandled section: '%s'\n", line); - fprintf(fout, ".align 4\n"); + fprintf(fout, ".align %d\n", align_value(4)); while (fgets(line, sizeof(line), fasm)) { @@ -454,7 +534,7 @@ int main(int argc, char *argv[]) if (IS(words[0], "align")) { val = parse_number(words[1]); - fprintf(fout, "\t\t .align %ld", val); + fprintf(fout, "\t\t .align %d", align_value(val)); goto fin; } @@ -469,20 +549,23 @@ int main(int argc, char *argv[]) aerr("unhandled decl: '%s %s'\n", words[0], words[1]); if (sym != NULL) { - // public/global name - if (pub_sym_cnt >= pub_sym_alloc) { - pub_sym_alloc *= 2; - pub_syms = realloc(pub_syms, pub_sym_alloc * sizeof(pub_syms[0])); - my_assert_not(pub_syms, NULL); - } - pub_syms[pub_sym_cnt++] = strdup(sym); + snprintf(last_sym, sizeof(last_sym), "%s", sym); pp = proto_parse(fhdr, sym, 1); - if (pp != NULL) + if (pp != NULL) { g_func_sym_pp = NULL; + // public/global name + if (pub_sym_cnt >= pub_sym_alloc) { + pub_sym_alloc *= 2; + pub_syms = realloc(pub_syms, pub_sym_alloc * sizeof(pub_syms[0])); + my_assert_not(pub_syms, NULL); + } + pub_syms[pub_sym_cnt++] = strdup(sym); + } + len = strlen(sym); - fprintf(fout, "_%s:", sym); + fprintf(fout, "%s%s:", no_decorations ? "" : "_", sym); len += 2; if (len < 8) @@ -498,7 +581,29 @@ int main(int argc, char *argv[]) fprintf(fout, "\t\t "); } - if (type == DXT_BYTE && words[w][0] == '\'') { + // fill out some unwanted strings with zeroes.. + if (type == DXT_BYTE && words[w][0] == '\'' + && is_unwanted_sym(last_sym)) + { + len = 0; + for (; w < wordc; w++) { + if (words[w][0] == '\'') { + p = words[w] + 1; + for (; *p && *p != '\''; p++) + len++; + } + else { + // assume encoded byte + len++; + } + } + fprintf(fout, ".skip %d", len); + goto fin; + } + else if (type == DXT_BYTE + && (words[w][0] == '\'' + || (w + 1 < wordc && words[w + 1][0] == '\''))) + { // string; use asciz for most common case if (w == wordc - 2 && IS(words[w + 1], "0")) { fprintf(fout, ".asciz \""); @@ -566,7 +671,13 @@ int main(int argc, char *argv[]) if (w != wordc - 1) aerr("TODO\n"); - fprintf(fout, "%s %s", type_name_float(type), words[w]); + if (g_arm_mode && type == DXT_TEN) { + fprintf(fout, ".fill 10"); + snprintf(g_comment, sizeof(g_comment), "%s %s", + type_name_float(type), words[w]); + } + else + fprintf(fout, "%s %s", type_name_float(type), words[w]); goto fin; } @@ -607,11 +718,16 @@ int main(int argc, char *argv[]) } else { pp = check_var(fhdr, sym, p); - if (p[0] != '_') - fprintf(fout, (pp && pp->is_fastcall) ? "@" : "_"); - fprintf(fout, "%s", p); - if (pp && pp->is_stdcall && pp->argc > 0) - fprintf(fout, "@%d", pp->argc * 4); + if (pp == NULL) { + fprintf(fout, "%s%s", + (no_decorations || p[0] == '_') ? "" : "_", p); + } + else { + if (no_decorations) + fprintf(fout, "%s", pp->name); + else + output_decorated_pp(fout, pp); + } } } else { @@ -627,7 +743,7 @@ int main(int argc, char *argv[]) fin: if (g_comment[0] != 0) { - fprintf(fout, "\t\t# %s", g_comment); + fprintf(fout, "\t\t%c %s", comment_char, g_comment); g_comment[0] = 0; } fprintf(fout, "\n"); @@ -638,7 +754,8 @@ fin: // dump public syms for (i = 0; i < pub_sym_cnt; i++) - fprintf(fout, ".global _%s\n", pub_syms[i]); + fprintf(fout, ".global %s%s\n", + no_decorations ? "" : "_", pub_syms[i]); fclose(fout); fclose(fasm);