|
dvander@2320
|
1 |
#include <stdio.h> |
|
dvander@2320
|
2 |
#include <stdlib.h> |
|
dvander@2320
|
3 |
#include <string.h> |
|
dvander@2320
|
4 |
#include <stdarg.h> |
|
dvander@2325
|
5 |
#include <assert.h> |
|
dvander@2320
|
6 |
#include "decompiler.h" |
|
dvander@2320
|
7 |
#include "platform_util.h" |
|
dvander@2320
|
8 |
|
|
dvander@2320
|
9 |
sp_decomp_t *Sp_InitDecomp(const char *file, int *err) |
|
dvander@2320
|
10 |
{ |
|
dvander@2320
|
11 |
sp_decomp_t *dc; |
|
dvander@2320
|
12 |
sp_file_t *plugin; |
|
dvander@2320
|
13 |
|
|
dvander@2320
|
14 |
if ((plugin = Sp_ReadPlugin(file, err)) == NULL) |
|
dvander@2320
|
15 |
{ |
|
dvander@2320
|
16 |
return NULL; |
|
dvander@2320
|
17 |
} |
|
dvander@2320
|
18 |
|
|
dvander@2320
|
19 |
dc = new sp_decomp_t; |
|
dvander@2320
|
20 |
memset(dc, 0, sizeof(sp_decomp_t)); |
|
dvander@2320
|
21 |
dc->plugin = plugin; |
|
dvander@2320
|
22 |
dc->pcode_map = (cell_t *)malloc(dc->plugin->pcode_size); |
|
dvander@2320
|
23 |
memset(dc->pcode_map, 0, dc->plugin->pcode_size); |
|
dvander@2320
|
24 |
|
|
dvander@2320
|
25 |
#define OPDEF(num,enm,str,prms) \ |
|
dvander@2320
|
26 |
dc->opdef[num].name = str; \ |
|
dvander@2320
|
27 |
dc->opdef[num].params = prms; |
|
dvander@2320
|
28 |
#include "opcodes.tbl" |
|
dvander@2320
|
29 |
#undef OPDEF |
|
dvander@2320
|
30 |
|
|
dvander@2325
|
31 |
if (plugin->debug.ntv != NULL) |
|
dvander@2325
|
32 |
{ |
|
dvander@2325
|
33 |
assert(plugin->debug.ntv->num_entries == plugin->num_natives); |
|
dvander@2325
|
34 |
dc->natives = new FunctionInfo[plugin->num_natives]; |
|
dvander@2325
|
35 |
memset(dc->natives, 0, sizeof(FunctionInfo) * plugin->num_natives); |
|
dvander@2325
|
36 |
|
|
dvander@2325
|
37 |
/* Unfurl this mess. */ |
|
dvander@2325
|
38 |
uint8_t *cursor = (uint8_t *)plugin->debug.ntv; |
|
dvander@2325
|
39 |
|
|
dvander@2325
|
40 |
cursor += sizeof(sp_fdbg_ntvtab_t); |
|
dvander@2325
|
41 |
for (uint32_t i = 0; i < plugin->num_natives; i++) |
|
dvander@2325
|
42 |
{ |
|
dvander@2325
|
43 |
sp_fdbg_native_t *native = (sp_fdbg_native_t *)cursor; |
|
dvander@2325
|
44 |
|
|
dvander@2325
|
45 |
uint32_t idx = native->index; |
|
dvander@2325
|
46 |
|
|
dvander@2325
|
47 |
assert(dc->natives[idx].name[0] == '\0'); |
|
dvander@2325
|
48 |
|
|
dvander@2325
|
49 |
Sp_Format(dc->natives[idx].name, |
|
dvander@2325
|
50 |
sizeof(dc->natives[idx].name), |
|
dvander@2325
|
51 |
"%s", |
|
dvander@2325
|
52 |
plugin->debug.stringbase + native->name); |
|
dvander@2325
|
53 |
dc->natives[idx].tag = Sp_FindTag(plugin, native->tagid); |
|
dvander@2325
|
54 |
dc->natives[idx].num_known_args = native->nargs; |
|
dvander@2325
|
55 |
|
|
dvander@2325
|
56 |
cursor += sizeof(sp_fdbg_native_t); |
|
dvander@2325
|
57 |
|
|
dvander@2325
|
58 |
for (uint32_t j = 0; j < dc->natives[idx].num_known_args; j++) |
|
dvander@2325
|
59 |
{ |
|
dvander@2325
|
60 |
sp_fdbg_ntvarg_t *arg = (sp_fdbg_ntvarg_t *)cursor; |
|
dvander@2325
|
61 |
dc->natives[idx].known_args[j].name = |
|
dvander@2325
|
62 |
plugin->debug.stringbase + arg->name; |
|
dvander@2325
|
63 |
dc->natives[idx].known_args[j].tag = |
|
dvander@2325
|
64 |
Sp_FindTag(plugin, arg->tagid); |
|
dvander@2325
|
65 |
dc->natives[idx].known_args[j].dimcount = arg->dimcount; |
|
dvander@2325
|
66 |
|
|
dvander@2325
|
67 |
cursor += sizeof(sp_fdbg_ntvarg_t); |
|
dvander@2325
|
68 |
if (arg->dimcount != 0) |
|
dvander@2325
|
69 |
{ |
|
dvander@2325
|
70 |
dc->natives[idx].known_args[j].dims = (sp_fdbg_arraydim_t *)cursor; |
|
dvander@2325
|
71 |
cursor += sizeof(sp_fdbg_arraydim_t) * arg->dimcount; |
|
dvander@2325
|
72 |
} |
|
dvander@2325
|
73 |
} |
|
dvander@2325
|
74 |
} |
|
dvander@2325
|
75 |
} |
|
dvander@2325
|
76 |
|
|
dvander@2320
|
77 |
return dc; |
|
dvander@2320
|
78 |
} |
|
dvander@2320
|
79 |
|
|
dvander@2320
|
80 |
void Sp_FreeDecomp(sp_decomp_t *decomp) |
|
dvander@2320
|
81 |
{ |
|
dvander@2320
|
82 |
FunctionInfo *info, *info_temp; |
|
dvander@2320
|
83 |
|
|
dvander@2320
|
84 |
info = decomp->funcs; |
|
dvander@2320
|
85 |
while (info != NULL) |
|
dvander@2320
|
86 |
{ |
|
dvander@2320
|
87 |
info_temp = info->next; |
|
dvander@2320
|
88 |
delete info; |
|
dvander@2320
|
89 |
info = info_temp; |
|
dvander@2320
|
90 |
} |
|
dvander@2320
|
91 |
|
|
dvander@2320
|
92 |
Sp_FreePlugin(decomp->plugin); |
|
dvander@2320
|
93 |
free(decomp->pcode_map); |
|
dvander@2325
|
94 |
delete [] decomp->natives; |
|
dvander@2320
|
95 |
delete decomp; |
|
dvander@2320
|
96 |
} |
|
dvander@2320
|
97 |
|
|
dvander@2320
|
98 |
PrintBuffer::PrintBuffer() : printbuf(NULL), printbuf_alloc(0), printbuf_pos(0) |
|
dvander@2320
|
99 |
{ |
|
dvander@2320
|
100 |
} |
|
dvander@2320
|
101 |
|
|
dvander@2320
|
102 |
PrintBuffer::~PrintBuffer() |
|
dvander@2320
|
103 |
{ |
|
dvander@2320
|
104 |
free(printbuf); |
|
dvander@2320
|
105 |
} |
|
dvander@2320
|
106 |
|
|
dvander@2320
|
107 |
void PrintBuffer::Grow(size_t len) |
|
dvander@2320
|
108 |
{ |
|
dvander@2320
|
109 |
if (printbuf_pos + len > printbuf_alloc) |
|
dvander@2320
|
110 |
{ |
|
dvander@2320
|
111 |
if (printbuf_alloc == 0) |
|
dvander@2320
|
112 |
{ |
|
dvander@2320
|
113 |
printbuf_alloc = len * 8; |
|
dvander@2320
|
114 |
} |
|
dvander@2320
|
115 |
else |
|
dvander@2320
|
116 |
{ |
|
dvander@2320
|
117 |
printbuf_alloc += len; |
|
dvander@2320
|
118 |
printbuf_alloc *= 2; |
|
dvander@2320
|
119 |
} |
|
dvander@2320
|
120 |
|
|
dvander@2320
|
121 |
printbuf = (char *)realloc(printbuf, printbuf_alloc); |
|
dvander@2320
|
122 |
} |
|
dvander@2320
|
123 |
} |
|
dvander@2320
|
124 |
|
|
dvander@2320
|
125 |
void PrintBuffer::Append(const char *fmt, ...) |
|
dvander@2320
|
126 |
{ |
|
dvander@2320
|
127 |
size_t len; |
|
dvander@2320
|
128 |
va_list ap; |
|
dvander@2320
|
129 |
char buffer[2048]; |
|
dvander@2320
|
130 |
|
|
dvander@2320
|
131 |
va_start(ap, fmt); |
|
dvander@2320
|
132 |
len = Sp_FormatArgs(buffer, sizeof(buffer), fmt, ap); |
|
dvander@2320
|
133 |
va_end(ap); |
|
dvander@2320
|
134 |
|
|
dvander@2325
|
135 |
Grow(len + 1); |
|
dvander@2320
|
136 |
|
|
dvander@2320
|
137 |
strcpy(&printbuf[printbuf_pos], buffer); |
|
dvander@2320
|
138 |
printbuf_pos += len; |
|
dvander@2320
|
139 |
} |
|
dvander@2320
|
140 |
|
|
dvander@2320
|
141 |
void PrintBuffer::Set(const char *fmt, ...) |
|
dvander@2320
|
142 |
{ |
|
dvander@2320
|
143 |
size_t len; |
|
dvander@2320
|
144 |
va_list ap; |
|
dvander@2320
|
145 |
char buffer[2048]; |
|
dvander@2320
|
146 |
|
|
dvander@2320
|
147 |
va_start(ap, fmt); |
|
dvander@2320
|
148 |
len = Sp_FormatArgs(buffer, sizeof(buffer), fmt, ap); |
|
dvander@2320
|
149 |
va_end(ap); |
|
dvander@2320
|
150 |
|
|
dvander@2320
|
151 |
Reset(); |
|
dvander@2325
|
152 |
Grow(len + 1); |
|
dvander@2320
|
153 |
|
|
dvander@2320
|
154 |
printbuf = (char *)realloc(printbuf, printbuf_alloc); |
|
dvander@2320
|
155 |
strcpy(&printbuf[printbuf_pos], buffer); |
|
dvander@2320
|
156 |
printbuf_pos += len; |
|
dvander@2320
|
157 |
} |
|
dvander@2320
|
158 |
|
|
dvander@2320
|
159 |
void PrintBuffer::Prepend(const char *fmt, ...) |
|
dvander@2320
|
160 |
{ |
|
dvander@2320
|
161 |
size_t len; |
|
dvander@2320
|
162 |
va_list ap; |
|
dvander@2320
|
163 |
char buffer[2048]; |
|
dvander@2320
|
164 |
|
|
dvander@2320
|
165 |
va_start(ap, fmt); |
|
dvander@2320
|
166 |
len = Sp_FormatArgs(buffer, sizeof(buffer), fmt, ap); |
|
dvander@2320
|
167 |
va_end(ap); |
|
dvander@2320
|
168 |
|
|
dvander@2320
|
169 |
Grow(len + 1); |
|
dvander@2320
|
170 |
|
|
dvander@2320
|
171 |
/* Move old data forward. Move one extra byte for the null terminator. */ |
|
dvander@2320
|
172 |
memmove(&printbuf[len], printbuf, printbuf_pos + 1); |
|
dvander@2320
|
173 |
printbuf_pos += len; |
|
dvander@2320
|
174 |
/* Move the new data in. */ |
|
dvander@2320
|
175 |
memcpy(printbuf, buffer, len); |
|
dvander@2320
|
176 |
} |
|
dvander@2320
|
177 |
|
|
dvander@2320
|
178 |
void PrintBuffer::Reset() |
|
dvander@2320
|
179 |
{ |
|
dvander@2320
|
180 |
printbuf_pos = 0; |
|
dvander@2320
|
181 |
} |
|
dvander@2320
|
182 |
|
|
dvander@2320
|
183 |
void PrintBuffer::Dump(FILE *fp) |
|
dvander@2320
|
184 |
{ |
|
dvander@2320
|
185 |
fprintf(fp, "%s", printbuf); |
|
dvander@2320
|
186 |
} |