X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=tools%2Fprotoparse.h;h=26b0e0048cd5728b442df0ae3c64b9e8ab6302bb;hb=c7ed83dd918585832e3c9001dabdb7375518d635;hp=0900243a508a8f77c90b703f95b04ef7eaf585d5;hpb=ef6b315df434af2d9f1336be3247a08b816306a4;p=ia32rtools.git diff --git a/tools/protoparse.h b/tools/protoparse.h index 0900243..26b0e00 100644 --- a/tools/protoparse.h +++ b/tools/protoparse.h @@ -6,6 +6,7 @@ struct parsed_type { unsigned int is_array:1; unsigned int is_ptr:1; unsigned int is_struct:1; // split for args + unsigned int is_retreg:1; // register to return }; struct parsed_proto_arg { @@ -28,11 +29,14 @@ struct parsed_proto { unsigned int is_func:1; unsigned int is_stdcall:1; unsigned int is_fastcall:1; - unsigned int is_vararg:1; + unsigned int is_vararg:1; // vararg func unsigned int is_fptr:1; unsigned int is_noreturn:1; unsigned int is_unresolved:1; + unsigned int is_userstack:1; + unsigned int is_arg:1; // decl in func arg unsigned int has_structarg:1; + unsigned int has_retreg:1; }; static const char *hdrfn; @@ -112,14 +116,22 @@ static int do_protostrs(FILE *fhdr, const char *fname) return -1; } -static int get_regparm(char *dst, size_t dlen, char *p) +static int get_regparm(char *dst, size_t dlen, char *p, int *retreg) { - int i, o; + int i = 0, o; + + *retreg = 0; if (*p != '<') return 0; - for (o = 0, i = 1; o < dlen; i++) { + i++; + if (p[i] == '*') { + *retreg = 1; + i++; + } + + for (o = 0; o < dlen; i++) { if (p[i] == 0) return 0; if (p[i] == '>') @@ -154,13 +166,14 @@ static const char *known_ptr_types[] = { "HGLOBAL", "HICON", "HINSTANCE", - //"HIMC", // DWORD + "HIMC", // DWORD in mingw, ptr in wine.. "HMODULE", "HPALETTE", "HRGN", "HRSRC", "HKEY", "HMENU", + "HWAVEOUT", "HWND", "PBYTE", "PCRITICAL_SECTION", @@ -300,6 +313,7 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) char regparm[16]; char buf[256]; char cconv[32]; + int is_retreg; int xarg = 0; char *p, *p1; int i, l; @@ -388,6 +402,10 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) pp->is_stdcall = 1; // IDA else if (IS(cconv, "__usercall")) pp->is_stdcall = 0; // IDA + else if (IS(cconv, "__userstack")) { + pp->is_stdcall = 0; // custom + pp->is_userstack = 1; + } else if (IS(cconv, "WINAPI")) pp->is_stdcall = 1; else { @@ -418,7 +436,7 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) } strcpy(pp->name, buf); - ret = get_regparm(regparm, sizeof(regparm), p); + ret = get_regparm(regparm, sizeof(regparm), p, &is_retreg); if (ret > 0) { if (!IS(regparm, "eax") && !IS(regparm, "ax") && !IS(regparm, "al") && !IS(regparm, "edx:eax")) @@ -512,6 +530,10 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) hdrfn, hdrfline, p1 - protostr); return -1; } + arg->fptr->is_arg = 1; + // we don't use actual names right now.. + snprintf(arg->fptr->name, + sizeof(arg->fptr->name), "a%d", xarg); // we'll treat it as void * for non-calls arg->type.name = strdup("void *"); arg->type.is_ptr = 1; @@ -530,12 +552,14 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) #endif arg->reg = NULL; - ret = get_regparm(regparm, sizeof(regparm), p); + ret = get_regparm(regparm, sizeof(regparm), p, &is_retreg); if (ret > 0) { p += ret; p = sskip(p); arg->reg = strdup(map_reg(regparm)); + arg->type.is_retreg = is_retreg; + pp->has_retreg |= is_retreg; } if (strstr(arg->type.name, "int64") @@ -659,6 +683,7 @@ static const struct parsed_proto *proto_parse(FILE *fhdr, const char *sym, { const struct parsed_proto *pp_ret; struct parsed_proto pp_search; + char *p; if (pp_cache == NULL) build_pp_cache(fhdr); @@ -667,6 +692,10 @@ static const struct parsed_proto *proto_parse(FILE *fhdr, const char *sym, sym++; strcpy(pp_search.name, sym); + p = strchr(pp_search.name, '@'); + if (p != NULL) + *p = 0; + pp_ret = bsearch(&pp_search, pp_cache, pp_cache_size, sizeof(pp_cache[0]), pp_name_cmp); if (pp_ret == NULL && !quiet)