From: notaz <notasas@gmail.com>
Date: Thu, 28 Nov 2013 01:16:41 +0000 (+0200)
Subject: adding disasm code, lots of breakage
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e52f54c9322fed87ea1b4c4d2fcfdf4c267afa6;p=ia32rtools.git

adding disasm code, lots of breakage
---

diff --git a/run_idac_adj.sh b/run_idac_adj.sh
index 3ec98c6..ceabb74 100755
--- a/run_idac_adj.sh
+++ b/run_idac_adj.sh
@@ -3,13 +3,13 @@ set -e
 
 f=/tmp/sedcmd_
 echo -n "sed -i '\
-s:__cdecl: /* __cdecl*/:;\
+s:__cdecl: /*__cdecl*/:;\
 s:__stdcall: /*__stdcall*/:;\
 s:__usercall: /*__usercall*/:;\
-s:__userpurge: /* __userpurge*/:;\
-s:__thiscall: /* __thiscall*/:;\
+s:__userpurge: /*__userpurge*/:;\
+s:__thiscall: /*__thiscall*/:;\
 s:__fastcall: /*__fastcall*/:;\
-s:\(<[^>]*>\):/*\1*/:g;\
+s:\(<[^<> ]*>\):/*\1*/:g;\
 ' $1" > $f
 . $f
 
diff --git a/tools/mkbridge.c b/tools/mkbridge.c
index 4c70246..ae2aec3 100644
--- a/tools/mkbridge.c
+++ b/tools/mkbridge.c
@@ -6,6 +6,7 @@
 #include "my_str.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#define IS(w, y) !strcmp(w, y)
 
 static int find_protostr(char *dst, size_t dlen, FILE *fhdr,
 	const char *sym, int *pline)
@@ -53,11 +54,19 @@ static int get_regparm(char *dst, size_t dlen, char *p)
 
 // hmh..
 static const char *known_types[] = {
-	"char",
+	"const void *",
+	"void *",
+	"char *",
+	"FILE *",
 	"unsigned __int8",
-	"int",
-	"signed int",
+	"unsigned __int16",
 	"unsigned int",
+	"signed int",
+	"char",
+	"__int8",
+	"__int16",
+	"int",
+	"bool",
 	"void",
 	"BYTE",
 	"WORD",
@@ -67,9 +76,6 @@ static const char *known_types[] = {
 	"HWND",
 	"LPCSTR",
 	"size_t",
-	"void *",
-	"const void *",
-	"FILE *",
 };
 
 static int check_type(const char *name)
@@ -85,6 +91,25 @@ static int check_type(const char *name)
 	return 0;
 }
 
+/* args are always expanded to 32bit */
+static const char *map_reg(const char *reg)
+{
+	const char *regs_f[] = { "eax", "ebx", "ecx", "edx", "esi", "edi" };
+	const char *regs_w[] = { "ax",  "bx",  "cx",  "dx",  "si",  "di" };
+	const char *regs_b[] = { "al",  "bl",  "cl",  "dl" };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regs_w); i++)
+		if (IS(reg, regs_w[i]))
+			return regs_f[i];
+
+	for (i = 0; i < ARRAY_SIZE(regs_b); i++)
+		if (IS(reg, regs_b[i]))
+			return regs_f[i];
+
+	return reg;
+}
+
 static const char *hdrfn;
 static int pline = 0;
 
@@ -93,6 +118,7 @@ static int parse_protostr(char *protostr, char **reglist, int *cnt_out,
 {
 	char regparm[16];
 	char buf[256];
+	char cconv[32];
 	int xarg = 0;
 	int ret;
 	char *p;
@@ -112,25 +138,28 @@ static int parse_protostr(char *protostr, char **reglist, int *cnt_out,
 	p += ret;
 	p = sskip(p);
 
-	p = next_word(buf, sizeof(buf), p);
+	p = next_word(cconv, sizeof(cconv), p);
 	p = sskip(p);
-	if (buf[0] == 0) {
+	if (cconv[0] == 0) {
 		printf("%s:%d:%ld: cconv missing\n",
 			hdrfn, pline, (p - protostr) + 1);
 		return 1;
 	}
-	if      (strcmp(buf, "__cdecl") == 0)
+	if      (IS(cconv, "__cdecl"))
 		*is_stdcall = 0;
-	else if (strcmp(buf, "__stdcall") == 0)
+	else if (IS(cconv, "__stdcall"))
+		*is_stdcall = 1;
+	else if (IS(cconv, "__fastcall"))
+		*is_stdcall = 1;
+	else if (IS(cconv, "__thiscall"))
 		*is_stdcall = 1;
-	else if (strcmp(buf, "__userpurge") == 0)
+	else if (IS(cconv, "__userpurge"))
 		*is_stdcall = 1; // in all cases seen..
-	else if (strcmp(buf, "__usercall") == 0)
+	else if (IS(cconv, "__usercall"))
 		*is_stdcall = 0; // ..or is it?
 	else {
-		// TODO: __thiscall needs special handling (arg1~ecx)
 		printf("%s:%d:%ld: unhandled cconv: '%s'\n",
-			hdrfn, pline, (p - protostr) + 1, buf);
+			hdrfn, pline, (p - protostr) + 1, cconv);
 		return 1;
 	}
 
@@ -144,8 +173,8 @@ static int parse_protostr(char *protostr, char **reglist, int *cnt_out,
 
 	ret = get_regparm(regparm, sizeof(regparm), p);
 	if (ret > 0) {
-		if (strcmp(regparm, "eax") && strcmp(regparm, "ax")
-		    && strcmp(regparm, "al"))
+		if (!IS(regparm, "eax") && !IS(regparm, "ax")
+		 && !IS(regparm, "al"))
 		{
 			printf("%s:%d:%ld: bad regparm: %s\n",
 				hdrfn, pline, (p - protostr) + 1, regparm);
@@ -196,8 +225,24 @@ static int parse_protostr(char *protostr, char **reglist, int *cnt_out,
 			p += ret;
 			p = sskip(p);
 
-			reglist[xarg - 1] = strdup(regparm);
+			reglist[xarg - 1] = strdup(map_reg(regparm));
+		}
+	}
+
+	if (xarg > 0 && (IS(cconv, "__fastcall") || IS(cconv, "__thiscall"))) {
+		if (reglist[0] != NULL) {
+			printf("%s:%d: %s with arg1 spec %s?\n",
+				hdrfn, pline, cconv, reglist[0]);
 		}
+		reglist[0] = strdup("ecx");
+	}
+
+	if (xarg > 1 && IS(cconv, "__fastcall")) {
+		if (reglist[1] != NULL) {
+			printf("%s:%d: %s with arg2 spec %s?\n",
+				hdrfn, pline, cconv, reglist[1]);
+		}
+		reglist[1] = strdup("edx");
 	}
 
 	*cnt_out = xarg;
@@ -321,7 +366,7 @@ static void out_fromasm_x86(FILE *f, char *sym, char *reg_list[], int reg_cnt,
 	fprintf(f, ".global %s\n", sym);
 	fprintf(f, "%s:\n", sym);
 
-	if (!have_regs) {
+	if (!have_regs && !is_stdcall) {
 		fprintf(f, "\tjmp _%s\n\n", sym);
 		return;
 	}
@@ -358,6 +403,18 @@ static void out_fromasm_x86(FILE *f, char *sym, char *reg_list[], int reg_cnt,
 		fprintf(f, "\tret\n\n");
 }
 
+static void free_reglist(char *reg_list[], int reg_cnt)
+{
+	int i;
+
+	for (i = 0; i < reg_cnt; i++) {
+		if (reg_list[i] == NULL) {
+			free(reg_list[i]);
+			reg_list[i] = NULL;
+		}
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	FILE *fout, *fsyms_to, *fsyms_from, *fhdr;
@@ -410,6 +467,7 @@ int main(int argc, char *argv[])
 			goto out;
 
 		out_toasm_x86(fout, sym, reg_list, reg_cnt, is_stdcall);
+		free_reglist(reg_list, reg_cnt);
 	}
 
 	fprintf(fout, "# from asm\n\n");
@@ -433,6 +491,7 @@ int main(int argc, char *argv[])
 			goto out;
 
 		out_fromasm_x86(fout, sym, reg_list, reg_cnt, is_stdcall);
+		free_reglist(reg_list, reg_cnt);
 	}
 
 	ret = 0;