From 1fe8d40ebdb232ab6be27af1a3b94a2869cc3779 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 18 Oct 2015 18:00:58 +0300 Subject: [PATCH] translate: support for data imports --- c_auto.h | 6 ++++++ run_imp.sh | 10 ++++++++-- tools/protoparse.h | 10 ++++++++++ tools/translate.c | 25 +++++++++++++++++++------ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/c_auto.h b/c_auto.h index 9b34f88..b3b1afc 100644 --- a/c_auto.h +++ b/c_auto.h @@ -35,6 +35,12 @@ typedef struct { #define BYTE2(x) (*((u8*)&(x)+2)) #define BYTE3(x) (*((u8*)&(x)+3)) +#ifndef __WINE__ +#define DECL_IMPORT __declspec(dllimport) +#else +#define DECL_IMPORT +#endif + #define memcpy_0 memcpy #define noreturn __attribute__((noreturn)) diff --git a/run_imp.sh b/run_imp.sh index 15381b7..b069eba 100755 --- a/run_imp.sh +++ b/run_imp.sh @@ -37,8 +37,14 @@ cat $implist | while read i; do done sym=`cat $tmpsym` if test -z "$sym"; then - echo "$target_s: no file/sym for $i" - exit 1 + # could be a data import + if test -n "$data_symf" && grep -q "$si" $data_symf; then + continue + else + echo "$target_s: no file/sym for $i" + rm $target_s + exit 1 + fi fi echo ".globl $i" >> $target_s diff --git a/tools/protoparse.h b/tools/protoparse.h index a3eb0e6..7acd63a 100644 --- a/tools/protoparse.h +++ b/tools/protoparse.h @@ -42,8 +42,10 @@ struct parsed_proto { unsigned int is_fastcall:1; unsigned int is_vararg:1; // vararg func unsigned int is_fptr:1; + unsigned int is_import:1; // data import unsigned int is_noreturn:1; unsigned int is_unresolved:1; + unsigned int is_guessed:1; // for extra checking unsigned int is_userstack:1; unsigned int is_include:1; // not from top-level header unsigned int is_osinc:1; // OS/system library func @@ -402,6 +404,9 @@ static int parse_arg(char **p_, struct parsed_proto_arg *arg, int xarg) if (ret < 0) return -1; + if (IS_START(arg->pp->name, "guess")) + arg->pp->is_guessed = 1; + // we don't use actual names right now... snprintf(arg->pp->name, sizeof(arg->pp->name), "a%d", xarg); @@ -462,6 +467,11 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) p = sskip(p + l + 1); } + if (IS_START(p, "DECL_IMPORT ")) { + pp->is_import = 1; + p = sskip(p + 12); + } + ret = check_type(p, &pp->ret_type); if (ret <= 0) { printf("%s:%d:%zd: unhandled return in '%s'\n", diff --git a/tools/translate.c b/tools/translate.c index 50af3bf..e6ab802 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -2142,7 +2142,7 @@ static void check_func_pp(struct parsed_op *po, } static const char *check_label_read_ref(struct parsed_op *po, - const char *name) + const char *name, int *is_import) { const struct parsed_proto *pp; @@ -2153,6 +2153,9 @@ static const char *check_label_read_ref(struct parsed_op *po, if (pp->is_func) check_func_pp(po, pp, "ref"); + if (is_import != NULL) + *is_import = pp->is_import; + return pp->name; } @@ -2171,6 +2174,7 @@ static char *out_src_opr(char *buf, size_t buf_size, char tmp1[256], tmp2[256]; char expr[256]; const char *name; + int is_import = 0; char *p; int ret; @@ -2243,7 +2247,11 @@ static char *out_src_opr(char *buf, size_t buf_size, break; case OPT_LABEL: - name = check_label_read_ref(po, popr->name); + name = check_label_read_ref(po, popr->name, &is_import); + if (is_import) + // for imported data, asm is loading the offset + goto do_offset; + if (cast[0] == 0 && popr->is_ptr) cast = "(u32)"; @@ -2259,7 +2267,8 @@ static char *out_src_opr(char *buf, size_t buf_size, break; case OPT_OFFSET: - name = check_label_read_ref(po, popr->name); + do_offset: + name = check_label_read_ref(po, popr->name, NULL); if (cast[0] == 0) cast = "(u32)"; if (is_lea) @@ -6310,6 +6319,9 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) if (pp->is_fptr && !(pp->name[0] != 0 && pp->is_arg)) { if (pp->name[0] != 0) { + if (IS_START(pp->name, "guess")) + pp->is_guessed = 1; + memmove(pp->name + 2, pp->name, strlen(pp->name) + 1); memcpy(pp->name, "i_", 2); @@ -7347,9 +7359,10 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) fprintf(fout, "%s%s = %s;\n", buf3, pp->name, out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], "(void *)", 0)); - if (pp->is_unresolved || IS_START(pp->name, "i_guess")) - fprintf(fout, "%sunresolved_call(\"%s:%d\", %s);\n", - buf3, asmfn, po->asmln, pp->name); + } + if (pp->is_fptr && (pp->is_unresolved || pp->is_guessed)) { + fprintf(fout, "%sunresolved_call(\"%s:%d\", %s);\n", + buf3, asmfn, po->asmln, pp->name); } fprintf(fout, "%s", buf3); -- 2.39.2