X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Fprotoparse.h;h=70d02c3507a2c2b436171009d4c6b1ec25615172;hb=17ed469eafaf2698cd31cdf0b2cb0e35fa799cd7;hp=7b449be63d0aefbfee2069aa928097acdce5ff0f;hpb=354f5504799c060e73037aa5de26da9ab75c2289;p=ia32rtools.git diff --git a/tools/protoparse.h b/tools/protoparse.h index 7b449be..70d02c3 100644 --- a/tools/protoparse.h +++ b/tools/protoparse.h @@ -33,7 +33,7 @@ struct parsed_proto { struct parsed_type ret_type; struct parsed_type type; }; - struct parsed_proto_arg arg[16]; + struct parsed_proto_arg arg[32]; int argc; int argc_stack; int argc_reg; @@ -641,6 +641,12 @@ static int parse_protostr(char *protostr, struct parsed_proto *pp) return -1; } + if (xarg >= ARRAY_SIZE(pp->arg)) { + printf("%s:%d:%zd: too many args\n", + hdrfn, hdrfline, (p - protostr) + 1); + return -1; + } + arg = &pp->arg[xarg]; xarg++; @@ -993,22 +999,43 @@ static inline int pp_cmp_func(const struct parsed_proto *pp1, if (pp1->argc != pp2->argc || pp1->argc_reg != pp2->argc_reg) return 1; - else { - for (i = 0; i < pp1->argc; i++) { - if ((pp1->arg[i].reg != NULL) != (pp2->arg[i].reg != NULL)) - return 1; - - if ((pp1->arg[i].reg != NULL) - && !IS(pp1->arg[i].reg, pp2->arg[i].reg)) - { - return 1; - } + if (pp1->is_stdcall != pp2->is_stdcall) + return 1; + + // because of poor void return detection, return is not + // checked for now to avoid heaps of false positives + + for (i = 0; i < pp1->argc; i++) { + if ((pp1->arg[i].reg != NULL) != (pp2->arg[i].reg != NULL)) + return 1; + + if ((pp1->arg[i].reg != NULL) + && !IS(pp1->arg[i].reg, pp2->arg[i].reg)) + { + return 1; } } return 0; } +static inline int pp_compatible_func( + const struct parsed_proto *pp_site, + const struct parsed_proto *pp_callee) +{ + if (pp_cmp_func(pp_site, pp_callee) == 0) + return 1; + + if (pp_site->argc_stack == 0 && pp_site->is_fastcall + && pp_callee->argc_stack == 0 + && (pp_callee->is_fastcall || pp_callee->argc_reg == 0) + && pp_site->argc_reg > pp_callee->argc_reg) + /* fascall compatible callee doesn't use all args -> ok */ + return 1; + + return 0; +} + static inline void pp_print(char *buf, size_t buf_size, const struct parsed_proto *pp) {