|
ds@1952
|
1 |
#include <stdio.h> |
|
ds@1952
|
2 |
#include <setjmp.h> |
|
ds@1952
|
3 |
#include <assert.h> |
|
ds@1952
|
4 |
#include <string.h> |
|
ds@1952
|
5 |
#include "memfile.h" |
|
ds@1952
|
6 |
#include "sp_file.h" |
|
ds@1952
|
7 |
#include "amx.h" |
|
ds@1952
|
8 |
#include "amxdbg.h" |
|
ds@1952
|
9 |
#include "osdefs.h" |
|
ds@1952
|
10 |
#include "zlib/zlib.h" |
|
ds@1952
|
11 |
|
|
ds@1952
|
12 |
enum FileSections |
|
ds@1952
|
13 |
{ |
|
ds@1952
|
14 |
FS_Code, /* required */ |
|
ds@1952
|
15 |
FS_Data, /* required */ |
|
ds@1952
|
16 |
FS_Publics, |
|
ds@1952
|
17 |
FS_Pubvars, |
|
ds@1952
|
18 |
FS_Natives, |
|
ds@1952
|
19 |
FS_Nametable, /* required */ |
|
ds@1952
|
20 |
FS_DbgFile, |
|
ds@1952
|
21 |
FS_DbgSymbol, |
|
ds@1952
|
22 |
FS_DbgLine, |
|
ds@1952
|
23 |
FS_DbgTags, |
|
dvander@2326
|
24 |
FS_DbgNatives, |
|
ds@1952
|
25 |
FS_DbgAutomaton, |
|
ds@1952
|
26 |
FS_DbgState, |
|
ds@1952
|
27 |
FS_DbgStrings, |
|
ds@1952
|
28 |
FS_DbgInfo, |
|
ds@1952
|
29 |
FS_Tags, |
|
ds@1952
|
30 |
/* --- */ |
|
ds@1952
|
31 |
FS_Number, |
|
ds@1952
|
32 |
}; |
|
ds@1952
|
33 |
|
|
ds@1952
|
34 |
int pc_printf(const char *message,...); |
|
ds@1952
|
35 |
int pc_compile(int argc, char **argv); |
|
ds@1952
|
36 |
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf); |
|
ds@1952
|
37 |
|
|
ds@1952
|
38 |
memfile_t *bin_file = NULL; |
|
ds@1952
|
39 |
jmp_buf brkout; |
|
ds@1952
|
40 |
|
|
dvander@2326
|
41 |
#define sARGS_MAX 32 /* number of arguments a function can have, max */ |
|
dvander@2326
|
42 |
#define sDIMEN_MAX 4 /* maximum number of array dimensions */ |
|
dvander@2326
|
43 |
|
|
dvander@2326
|
44 |
typedef struct t_arg_s |
|
dvander@2326
|
45 |
{ |
|
dvander@2326
|
46 |
uint8_t ident; |
|
dvander@2326
|
47 |
int16_t tag; |
|
dvander@2326
|
48 |
char *name; |
|
dvander@2326
|
49 |
uint16_t dimcount; |
|
dvander@2326
|
50 |
sp_fdbg_arraydim_t dims[sDIMEN_MAX]; |
|
dvander@2326
|
51 |
} t_arg; |
|
dvander@2326
|
52 |
|
|
dvander@2326
|
53 |
typedef struct t_native_s |
|
dvander@2326
|
54 |
{ |
|
dvander@2326
|
55 |
char *name; |
|
dvander@2326
|
56 |
int16_t ret_tag; |
|
dvander@2326
|
57 |
uint16_t num_args; |
|
dvander@2326
|
58 |
t_arg args[sARGS_MAX]; |
|
dvander@2326
|
59 |
} t_native; |
|
dvander@2326
|
60 |
|
|
dvander@2326
|
61 |
t_native *native_list = NULL; |
|
dvander@2326
|
62 |
|
|
ds@1952
|
63 |
int main(int argc, char *argv[]) |
|
ds@1952
|
64 |
{ |
|
ds@1952
|
65 |
#if defined _DEBUG |
|
ds@1952
|
66 |
getchar(); |
|
ds@1952
|
67 |
#endif |
|
ds@1952
|
68 |
if (pc_compile(argc,argv) == 0) |
|
ds@1952
|
69 |
{ |
|
ds@1952
|
70 |
AMX_HEADER *hdr; |
|
ds@1952
|
71 |
AMX_DBG_HDR *dbg = NULL; |
|
ds@1952
|
72 |
int err; |
|
ds@1952
|
73 |
uint32_t i; |
|
ds@1952
|
74 |
sp_file_t *spf; |
|
ds@1952
|
75 |
memfile_t *dbgtab = NULL; //dbgcrab |
|
ds@1952
|
76 |
unsigned char *dbgptr = NULL; |
|
dvander@2326
|
77 |
uint32_t sections[FS_Number] = {1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0}; |
|
ds@1952
|
78 |
FILE *fp; |
|
ds@1952
|
79 |
|
|
ds@1952
|
80 |
if (bin_file == NULL) |
|
ds@1952
|
81 |
{ |
|
ds@1952
|
82 |
return 0; |
|
ds@1952
|
83 |
} |
|
ds@1952
|
84 |
|
|
ds@1952
|
85 |
hdr = (AMX_HEADER *)bin_file->base; |
|
ds@1952
|
86 |
|
|
ds@1952
|
87 |
if ((spf=spfw_create(bin_file->name, NULL)) == NULL) |
|
ds@1952
|
88 |
{ |
|
ds@1952
|
89 |
pc_printf("Error creating binary file!\n"); |
|
ds@1952
|
90 |
memfile_destroy(bin_file); |
|
ds@1952
|
91 |
return 0; |
|
ds@1952
|
92 |
} |
|
ds@1952
|
93 |
|
|
ds@1952
|
94 |
if ((err=setjmp(brkout))!=0) |
|
ds@1952
|
95 |
{ |
|
ds@1952
|
96 |
goto write_error; |
|
ds@1952
|
97 |
} |
|
ds@1952
|
98 |
|
|
ds@1952
|
99 |
spfw_add_section(spf, ".code"); |
|
ds@1952
|
100 |
spfw_add_section(spf, ".data"); |
|
ds@1952
|
101 |
|
|
ds@1952
|
102 |
sections[FS_Publics] = (hdr->natives - hdr->publics) / hdr->defsize; |
|
ds@1952
|
103 |
if (sections[FS_Publics]) |
|
ds@1952
|
104 |
{ |
|
ds@1952
|
105 |
spfw_add_section(spf, ".publics"); |
|
ds@1952
|
106 |
} |
|
ds@1952
|
107 |
sections[FS_Pubvars] = (hdr->tags - hdr->pubvars) / hdr->defsize; |
|
ds@1952
|
108 |
if (sections[FS_Pubvars]) |
|
ds@1952
|
109 |
{ |
|
ds@1952
|
110 |
spfw_add_section(spf, ".pubvars"); |
|
ds@1952
|
111 |
} |
|
ds@1952
|
112 |
sections[FS_Natives] = (hdr->libraries - hdr->natives) / hdr->defsize; |
|
ds@1952
|
113 |
if (sections[FS_Natives]) |
|
ds@1952
|
114 |
{ |
|
ds@1952
|
115 |
spfw_add_section(spf, ".natives"); |
|
ds@1952
|
116 |
} |
|
ds@1952
|
117 |
sections[FS_Tags] = (hdr->nametable - hdr->tags) / hdr->defsize; |
|
ds@1952
|
118 |
if (sections[FS_Tags]) |
|
ds@1952
|
119 |
{ |
|
ds@1952
|
120 |
spfw_add_section(spf, ".tags"); |
|
ds@1952
|
121 |
} |
|
ds@1952
|
122 |
|
|
ds@1952
|
123 |
spfw_add_section(spf, ".names"); |
|
ds@1952
|
124 |
|
|
ds@1952
|
125 |
if (hdr->flags & AMX_FLAG_DEBUG) |
|
ds@1952
|
126 |
{ |
|
ds@1952
|
127 |
dbg = (AMX_DBG_HDR *)((unsigned char *)hdr + hdr->size); |
|
ds@1952
|
128 |
if (dbg->magic != AMX_DBG_MAGIC) |
|
ds@1952
|
129 |
{ |
|
ds@1952
|
130 |
pc_printf("Error reading AMX_DBG_HDR, debug data will not be written."); |
|
ds@1952
|
131 |
} else { |
|
ds@1952
|
132 |
dbgtab = memfile_creat("", 512); |
|
ds@1952
|
133 |
dbgptr = (unsigned char *)dbg + sizeof(AMX_DBG_HDR); |
|
dvander@2326
|
134 |
if ((sections[FS_DbgNatives] = sections[FS_Natives]) > 0) |
|
dvander@2326
|
135 |
{ |
|
dvander@2326
|
136 |
spfw_add_section(spf, ".dbg.natives"); |
|
dvander@2326
|
137 |
} |
|
ds@1952
|
138 |
if (dbg->files) |
|
ds@1952
|
139 |
{ |
|
ds@1952
|
140 |
spfw_add_section(spf, ".dbg.files"); |
|
ds@1952
|
141 |
sections[FS_DbgFile] = dbg->files; |
|
ds@1952
|
142 |
} |
|
ds@1952
|
143 |
if (dbg->lines) |
|
ds@1952
|
144 |
{ |
|
ds@1952
|
145 |
spfw_add_section(spf, ".dbg.lines"); |
|
ds@1952
|
146 |
sections[FS_DbgLine] = dbg->lines; |
|
ds@1952
|
147 |
} |
|
ds@1952
|
148 |
if (dbg->symbols) |
|
ds@1952
|
149 |
{ |
|
ds@1952
|
150 |
spfw_add_section(spf, ".dbg.symbols"); |
|
ds@1952
|
151 |
sections[FS_DbgSymbol] = dbg->symbols; |
|
ds@1952
|
152 |
} |
|
ds@1952
|
153 |
sections[FS_DbgInfo] = 1; |
|
ds@1952
|
154 |
sections[FS_DbgStrings] = 1; |
|
ds@1952
|
155 |
spfw_add_section(spf, ".dbg.info"); |
|
ds@1952
|
156 |
spfw_add_section(spf, ".dbg.strings"); |
|
ds@1952
|
157 |
} |
|
ds@1952
|
158 |
} |
|
ds@1952
|
159 |
|
|
ds@1952
|
160 |
spfw_finalize_header(spf); |
|
ds@1952
|
161 |
|
|
ds@1952
|
162 |
/** |
|
ds@1952
|
163 |
* Begin writing each of our known tables out |
|
ds@1952
|
164 |
*/ |
|
ds@1952
|
165 |
|
|
ds@1952
|
166 |
if (sections[FS_Code]) |
|
ds@1952
|
167 |
{ |
|
ds@1952
|
168 |
sp_file_code_t cod; |
|
ds@1952
|
169 |
unsigned char *cbase; |
|
ds@1952
|
170 |
|
|
ds@1952
|
171 |
cod.cellsize = sizeof(cell); |
|
ds@1952
|
172 |
|
|
ds@1952
|
173 |
cod.codesize = hdr->dat - hdr->cod; |
|
ds@1952
|
174 |
cod.codeversion = hdr->amx_version; |
|
ds@1952
|
175 |
cod.flags = 0; |
|
ds@1952
|
176 |
if (hdr->flags & AMX_FLAG_DEBUG) |
|
ds@1952
|
177 |
{ |
|
ds@1952
|
178 |
cod.flags |= SP_FLAG_DEBUG; |
|
ds@1952
|
179 |
} |
|
ds@1952
|
180 |
cod.code = sizeof(cod); |
|
ds@1952
|
181 |
cod.main = hdr->cip; |
|
ds@1952
|
182 |
|
|
ds@1952
|
183 |
/* write the code */ |
|
ds@1952
|
184 |
cbase = (unsigned char *)hdr + hdr->cod; |
|
ds@1952
|
185 |
sfwrite(&cod, sizeof(cod), 1, spf); |
|
ds@1952
|
186 |
sfwrite(cbase, cod.codesize, 1, spf); |
|
ds@1952
|
187 |
|
|
ds@1952
|
188 |
spfw_next_section(spf); |
|
ds@1952
|
189 |
} |
|
ds@1952
|
190 |
|
|
ds@1952
|
191 |
if (sections[FS_Data]) |
|
ds@1952
|
192 |
{ |
|
ds@1952
|
193 |
sp_file_data_t dat; |
|
ds@1952
|
194 |
unsigned char *dbase = (unsigned char *)hdr + hdr->dat; |
|
ds@1952
|
195 |
|
|
ds@1952
|
196 |
dat.datasize = hdr->hea - hdr->dat; |
|
ds@1952
|
197 |
dat.memsize = hdr->stp; |
|
ds@1952
|
198 |
dat.data = sizeof(dat); |
|
ds@1952
|
199 |
|
|
ds@1952
|
200 |
/* write header */ |
|
ds@1952
|
201 |
sfwrite(&dat, sizeof(dat), 1, spf); |
|
ds@1952
|
202 |
|
|
ds@1952
|
203 |
if (dat.datasize) |
|
ds@1952
|
204 |
{ |
|
ds@1952
|
205 |
/* write data */ |
|
ds@1952
|
206 |
sfwrite(dbase, dat.datasize, 1, spf); |
|
ds@1952
|
207 |
} |
|
ds@1952
|
208 |
|
|
ds@1952
|
209 |
spfw_next_section(spf); |
|
ds@1952
|
210 |
} |
|
ds@1952
|
211 |
|
|
ds@1952
|
212 |
if (sections[FS_Publics]) |
|
ds@1952
|
213 |
{ |
|
ds@1952
|
214 |
sp_file_publics_t *pbtbl; |
|
ds@1952
|
215 |
AMX_FUNCSTUBNT *stub; |
|
ds@1952
|
216 |
unsigned char *stubptr; |
|
ds@1952
|
217 |
uint32_t publics = sections[FS_Publics]; |
|
ds@1952
|
218 |
|
|
ds@1952
|
219 |
pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics); |
|
ds@1952
|
220 |
stubptr = (unsigned char *)hdr + hdr->publics; |
|
ds@1952
|
221 |
|
|
ds@1952
|
222 |
for (i=0; i<publics; i++) |
|
ds@1952
|
223 |
{ |
|
ds@1952
|
224 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
ds@1952
|
225 |
pbtbl[i].address = stub->address; |
|
ds@1952
|
226 |
pbtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
ds@1952
|
227 |
|
|
ds@1952
|
228 |
stubptr += hdr->defsize; |
|
ds@1952
|
229 |
} |
|
ds@1952
|
230 |
if (publics) |
|
ds@1952
|
231 |
{ |
|
ds@1952
|
232 |
sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, spf); |
|
ds@1952
|
233 |
} |
|
ds@1952
|
234 |
free(pbtbl); |
|
ds@1952
|
235 |
|
|
ds@1952
|
236 |
spfw_next_section(spf); |
|
ds@1952
|
237 |
} |
|
ds@1952
|
238 |
|
|
ds@1952
|
239 |
if (sections[FS_Pubvars]) |
|
ds@1952
|
240 |
{ |
|
ds@1952
|
241 |
sp_file_pubvars_t *pbvars; |
|
ds@1952
|
242 |
AMX_FUNCSTUBNT *stub; |
|
ds@1952
|
243 |
unsigned char *stubptr; |
|
ds@1952
|
244 |
uint32_t pubvars = sections[FS_Pubvars]; |
|
ds@1952
|
245 |
|
|
ds@1952
|
246 |
pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars); |
|
ds@1952
|
247 |
stubptr = (unsigned char *)hdr + hdr->pubvars; |
|
ds@1952
|
248 |
|
|
ds@1952
|
249 |
for (i=0; i<pubvars; i++) |
|
ds@1952
|
250 |
{ |
|
ds@1952
|
251 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
ds@1952
|
252 |
pbvars[i].address = stub->address; |
|
ds@1952
|
253 |
pbvars[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
ds@1952
|
254 |
|
|
ds@1952
|
255 |
stubptr += hdr->defsize; |
|
ds@1952
|
256 |
} |
|
ds@1952
|
257 |
if (pubvars) |
|
ds@1952
|
258 |
{ |
|
ds@1952
|
259 |
sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, spf); |
|
ds@1952
|
260 |
} |
|
ds@1952
|
261 |
free(pbvars); |
|
ds@1952
|
262 |
spfw_next_section(spf); |
|
ds@1952
|
263 |
} |
|
ds@1952
|
264 |
|
|
ds@1952
|
265 |
if (sections[FS_Natives]) |
|
ds@1952
|
266 |
{ |
|
ds@1952
|
267 |
sp_file_natives_t *nvtbl; |
|
ds@1952
|
268 |
AMX_FUNCSTUBNT *stub; |
|
ds@1952
|
269 |
unsigned char *stubptr; |
|
ds@1952
|
270 |
uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize; |
|
ds@1952
|
271 |
|
|
ds@1952
|
272 |
nvtbl = (sp_file_natives_t *)malloc(sizeof(sp_file_natives_t) * natives); |
|
ds@1952
|
273 |
stubptr = (unsigned char *)hdr + hdr->natives; |
|
ds@1952
|
274 |
|
|
ds@1952
|
275 |
for (i=0; i<natives; i++) |
|
ds@1952
|
276 |
{ |
|
ds@1952
|
277 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
ds@1952
|
278 |
nvtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
ds@1952
|
279 |
|
|
ds@1952
|
280 |
stubptr += hdr->defsize; |
|
ds@1952
|
281 |
} |
|
ds@1952
|
282 |
if (natives) |
|
ds@1952
|
283 |
{ |
|
ds@1952
|
284 |
sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, spf); |
|
ds@1952
|
285 |
} |
|
ds@1952
|
286 |
free(nvtbl); |
|
ds@1952
|
287 |
spfw_next_section(spf); |
|
ds@1952
|
288 |
} |
|
ds@1952
|
289 |
|
|
ds@1952
|
290 |
if (sections[FS_Tags]) |
|
ds@1952
|
291 |
{ |
|
ds@1952
|
292 |
uint32_t numTags = (uint32_t)sections[FS_Tags]; |
|
ds@1952
|
293 |
AMX_FUNCSTUBNT *stub; |
|
ds@1952
|
294 |
sp_file_tag_t tag; |
|
ds@1952
|
295 |
|
|
ds@1952
|
296 |
for (i=0; i<numTags; i++) |
|
ds@1952
|
297 |
{ |
|
ds@1952
|
298 |
stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->tags + (i * hdr->defsize)); |
|
ds@1952
|
299 |
tag.tag_id = stub->address; |
|
ds@1952
|
300 |
tag.name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
ds@1952
|
301 |
sfwrite(&tag, sizeof(sp_file_tag_t), 1, spf); |
|
ds@1952
|
302 |
} |
|
ds@1952
|
303 |
spfw_next_section(spf); |
|
ds@1952
|
304 |
} |
|
ds@1952
|
305 |
|
|
ds@1952
|
306 |
if (sections[FS_Nametable]) |
|
ds@1952
|
307 |
{ |
|
ds@1952
|
308 |
unsigned char *base; |
|
ds@1952
|
309 |
uint32_t namelen; |
|
ds@1952
|
310 |
|
|
ds@1952
|
311 |
/* write the entire block */ |
|
ds@1952
|
312 |
base = (unsigned char *)hdr + hdr->nametable + sizeof(uint16_t); |
|
ds@1952
|
313 |
/** |
|
ds@1952
|
314 |
* note - the name table will be padded to sizeof(cell) bytes. |
|
ds@1952
|
315 |
* this may clip at most an extra three bytes in! |
|
ds@1952
|
316 |
*/ |
|
ds@1952
|
317 |
namelen = hdr->cod - hdr->nametable; |
|
ds@1952
|
318 |
sfwrite(base, namelen, 1, spf); |
|
ds@1952
|
319 |
spfw_next_section(spf); |
|
ds@1952
|
320 |
} |
|
ds@1952
|
321 |
|
|
ds@1952
|
322 |
if (hdr->flags & AMX_FLAG_DEBUG) |
|
ds@1952
|
323 |
{ |
|
ds@1952
|
324 |
sp_fdbg_info_t info; |
|
ds@1952
|
325 |
|
|
ds@1952
|
326 |
memset(&info, 0, sizeof(sp_fdbg_info_t)); |
|
ds@1952
|
327 |
|
|
dvander@2326
|
328 |
if (sections[FS_Natives]) |
|
dvander@2326
|
329 |
{ |
|
dvander@2326
|
330 |
uint16_t j; |
|
dvander@2326
|
331 |
uint32_t idx; |
|
dvander@2326
|
332 |
uint32_t name; |
|
dvander@2326
|
333 |
uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize; |
|
dvander@2326
|
334 |
|
|
dvander@2326
|
335 |
sfwrite(&natives, sizeof(uint32_t), 1, spf); |
|
dvander@2326
|
336 |
for (idx=0; idx<natives; idx++) |
|
dvander@2326
|
337 |
{ |
|
dvander@2326
|
338 |
sfwrite(&idx, sizeof(uint32_t), 1, spf); |
|
dvander@2326
|
339 |
name = (uint32_t)memfile_tell(dbgtab); |
|
dvander@2326
|
340 |
memfile_write(dbgtab, native_list[idx].name, strlen(native_list[idx].name) + 1); |
|
dvander@2326
|
341 |
sfwrite(&name, sizeof(uint32_t), 1, spf); |
|
dvander@2326
|
342 |
sfwrite(&native_list[idx].ret_tag, sizeof(int16_t), 1, spf); |
|
dvander@2326
|
343 |
sfwrite(&native_list[idx].num_args, sizeof(uint16_t), 1, spf); |
|
dvander@2326
|
344 |
|
|
dvander@2326
|
345 |
/* Go through arguments */ |
|
dvander@2326
|
346 |
for (j = 0; j < native_list[idx].num_args; j++) |
|
dvander@2326
|
347 |
{ |
|
dvander@2326
|
348 |
sfwrite(&native_list[idx].args[j].ident, sizeof(uint8_t), 1, spf); |
|
dvander@2326
|
349 |
sfwrite(&native_list[idx].args[j].tag, sizeof(int16_t), 1, spf); |
|
dvander@2326
|
350 |
sfwrite(&native_list[idx].args[j].dimcount, sizeof(uint16_t), 1, spf); |
|
dvander@2326
|
351 |
name = (uint32_t)memfile_tell(dbgtab); |
|
dvander@2326
|
352 |
sfwrite(&name, sizeof(uint32_t), 1, spf); |
|
dvander@2326
|
353 |
memfile_write(dbgtab, |
|
dvander@2326
|
354 |
native_list[idx].args[j].name, |
|
dvander@2326
|
355 |
strlen(native_list[idx].args[j].name) + 1); |
|
dvander@2326
|
356 |
if (native_list[idx].args[j].dimcount) |
|
dvander@2326
|
357 |
{ |
|
dvander@2326
|
358 |
sfwrite(native_list[idx].args[j].dims, |
|
dvander@2326
|
359 |
sizeof(sp_fdbg_arraydim_t), |
|
dvander@2326
|
360 |
native_list[idx].args[j].dimcount, |
|
dvander@2326
|
361 |
spf); |
|
dvander@2326
|
362 |
} |
|
dvander@2326
|
363 |
free(native_list[idx].args[j].name); |
|
dvander@2326
|
364 |
} |
|
dvander@2326
|
365 |
free(native_list[idx].name); |
|
dvander@2326
|
366 |
} |
|
dvander@2326
|
367 |
free(native_list); |
|
dvander@2326
|
368 |
spfw_next_section(spf); |
|
dvander@2326
|
369 |
} |
|
dvander@2326
|
370 |
|
|
ds@1952
|
371 |
if (sections[FS_DbgFile]) |
|
ds@1952
|
372 |
{ |
|
ds@1952
|
373 |
uint32_t idx; |
|
ds@1952
|
374 |
sp_fdbg_file_t dbgfile; |
|
ds@1952
|
375 |
AMX_DBG_FILE *_ptr; |
|
ds@1952
|
376 |
uint32_t len; |
|
ds@1952
|
377 |
for (idx=0; idx<sections[FS_DbgFile]; idx++) |
|
ds@1952
|
378 |
{ |
|
ds@1952
|
379 |
/* get entry info */ |
|
ds@1952
|
380 |
_ptr = (AMX_DBG_FILE *)dbgptr; |
|
ds@1952
|
381 |
len = strlen(_ptr->name); |
|
ds@1952
|
382 |
/* store */ |
|
ds@1952
|
383 |
dbgfile.addr = _ptr->address; |
|
ds@1952
|
384 |
dbgfile.name = (uint32_t)memfile_tell(dbgtab); |
|
ds@1952
|
385 |
sfwrite(&dbgfile, sizeof(sp_fdbg_file_t), 1, spf); |
|
ds@1952
|
386 |
/* write to tab, then move to next */ |
|
ds@1952
|
387 |
memfile_write(dbgtab, _ptr->name, len + 1); |
|
ds@1952
|
388 |
dbgptr += sizeof(AMX_DBG_FILE) + len; |
|
ds@1952
|
389 |
info.num_files++; |
|
ds@1952
|
390 |
} |
|
ds@1952
|
391 |
spfw_next_section(spf); |
|
ds@1952
|
392 |
} |
|
ds@1952
|
393 |
|
|
ds@1952
|
394 |
if (sections[FS_DbgLine]) |
|
ds@1952
|
395 |
{ |
|
ds@1952
|
396 |
uint32_t idx; |
|
ds@1952
|
397 |
AMX_DBG_LINE *line; |
|
ds@1952
|
398 |
sp_fdbg_line_t dbgline; |
|
ds@1952
|
399 |
for (idx=0; idx<sections[FS_DbgLine]; idx++) |
|
ds@1952
|
400 |
{ |
|
ds@1952
|
401 |
/* get entry info */ |
|
ds@1952
|
402 |
line = (AMX_DBG_LINE *)dbgptr; |
|
ds@1952
|
403 |
/* store */ |
|
ds@1952
|
404 |
dbgline.addr = (uint32_t)line->address; |
|
ds@1952
|
405 |
dbgline.line = (uint32_t)line->line; |
|
ds@1952
|
406 |
sfwrite(&dbgline, sizeof(sp_fdbg_line_t), 1, spf); |
|
ds@1952
|
407 |
/* move to next */ |
|
ds@1952
|
408 |
dbgptr += sizeof(AMX_DBG_LINE); |
|
ds@1952
|
409 |
info.num_lines++; |
|
ds@1952
|
410 |
} |
|
ds@1952
|
411 |
spfw_next_section(spf); |
|
ds@1952
|
412 |
} |
|
ds@1952
|
413 |
|
|
ds@1952
|
414 |
if (sections[FS_DbgSymbol]) |
|
ds@1952
|
415 |
{ |
|
ds@1952
|
416 |
uint32_t idx; |
|
ds@1952
|
417 |
uint32_t dnum; |
|
ds@1952
|
418 |
AMX_DBG_SYMBOL *sym; |
|
ds@1952
|
419 |
AMX_DBG_SYMDIM *dim; |
|
ds@1952
|
420 |
sp_fdbg_symbol_t dbgsym; |
|
ds@1952
|
421 |
sp_fdbg_arraydim_t dbgdim; |
|
ds@1952
|
422 |
uint32_t len; |
|
ds@1952
|
423 |
|
|
ds@1952
|
424 |
for (idx=0; idx<sections[FS_DbgSymbol]; idx++) |
|
ds@1952
|
425 |
{ |
|
ds@1952
|
426 |
/* get entry info */ |
|
ds@1952
|
427 |
sym = (AMX_DBG_SYMBOL *)dbgptr; |
|
ds@1952
|
428 |
/* store */ |
|
ds@1952
|
429 |
dbgsym.addr = *(int32_t *)&sym->address; |
|
ds@1952
|
430 |
dbgsym.tagid = sym->tag; |
|
ds@1952
|
431 |
dbgsym.codestart = (uint32_t)sym->codestart; |
|
ds@1952
|
432 |
dbgsym.codeend = (uint32_t)sym->codeend; |
|
ds@1952
|
433 |
dbgsym.dimcount = (uint16_t)sym->dim; |
|
ds@1952
|
434 |
dbgsym.vclass = (uint8_t)sym->vclass; |
|
ds@1952
|
435 |
dbgsym.ident = (uint8_t)sym->ident; |
|
ds@1952
|
436 |
dbgsym.name = (uint32_t)memfile_tell(dbgtab); |
|
ds@1952
|
437 |
sfwrite(&dbgsym, sizeof(sp_fdbg_symbol_t), 1, spf); |
|
ds@1952
|
438 |
/* write to tab */ |
|
ds@1952
|
439 |
len = strlen(sym->name); |
|
ds@1952
|
440 |
memfile_write(dbgtab, sym->name, len + 1); |
|
ds@1952
|
441 |
/* move to next */ |
|
ds@1952
|
442 |
dbgptr += sizeof(AMX_DBG_SYMBOL) + len; |
|
ds@1952
|
443 |
/* look for any dimensions */ |
|
ds@1952
|
444 |
info.num_syms++; |
|
ds@1952
|
445 |
for (dnum=0; dnum<dbgsym.dimcount; dnum++) |
|
ds@1952
|
446 |
{ |
|
ds@1952
|
447 |
/* get entry info */ |
|
ds@1952
|
448 |
dim = (AMX_DBG_SYMDIM *)dbgptr; |
|
ds@1952
|
449 |
/* store */ |
|
ds@1952
|
450 |
dbgdim.size = (uint32_t)dim->size; |
|
ds@1952
|
451 |
dbgdim.tagid = dim->tag; |
|
ds@1952
|
452 |
sfwrite(&dbgdim, sizeof(sp_fdbg_arraydim_t), 1, spf); |
|
ds@1952
|
453 |
/* move to next */ |
|
ds@1952
|
454 |
dbgptr += sizeof(AMX_DBG_SYMDIM); |
|
ds@1952
|
455 |
info.num_arrays++; |
|
ds@1952
|
456 |
} |
|
ds@1952
|
457 |
} |
|
ds@1952
|
458 |
spfw_next_section(spf); |
|
ds@1952
|
459 |
} |
|
ds@1952
|
460 |
|
|
ds@1952
|
461 |
sfwrite(&info, sizeof(sp_fdbg_info_t), 1, spf); |
|
ds@1952
|
462 |
spfw_next_section(spf); |
|
ds@1952
|
463 |
|
|
ds@1952
|
464 |
if (sections[FS_DbgStrings]) |
|
ds@1952
|
465 |
{ |
|
ds@1952
|
466 |
sfwrite(dbgtab->base, sizeof(char), dbgtab->usedoffs, spf); |
|
ds@1952
|
467 |
spfw_next_section(spf); |
|
ds@1952
|
468 |
} |
|
ds@1952
|
469 |
} |
|
ds@1952
|
470 |
|
|
ds@1952
|
471 |
spfw_finalize_all(spf); |
|
ds@1952
|
472 |
|
|
ds@1952
|
473 |
/** |
|
ds@1952
|
474 |
* do compression |
|
ds@1952
|
475 |
* new block for scoping only |
|
ds@1952
|
476 |
*/ |
|
ds@1952
|
477 |
{ |
|
ds@1952
|
478 |
memfile_t *pOrig = (memfile_t *)spf->handle; |
|
ds@1952
|
479 |
sp_file_hdr_t *pHdr; |
|
ds@1952
|
480 |
unsigned char *proper; |
|
ds@1952
|
481 |
size_t size; |
|
ds@1952
|
482 |
Bytef *zcmp; |
|
ds@1952
|
483 |
uLong disksize; |
|
ds@1952
|
484 |
size_t header_size; |
|
ds@1952
|
485 |
int err = Z_OK; |
|
ds@1952
|
486 |
|
|
ds@1952
|
487 |
/* reuse this memory block! */ |
|
ds@1952
|
488 |
memfile_reset(bin_file); |
|
ds@1952
|
489 |
|
|
ds@1952
|
490 |
/* copy tip of header */ |
|
ds@1952
|
491 |
memfile_write(bin_file, pOrig->base, sizeof(sp_file_hdr_t)); |
|
ds@1952
|
492 |
|
|
ds@1952
|
493 |
/* get pointer to header */ |
|
ds@1952
|
494 |
pHdr = (sp_file_hdr_t *)bin_file->base; |
|
ds@1952
|
495 |
|
|
ds@1952
|
496 |
/* copy the rest of the header */ |
|
ds@1952
|
497 |
memfile_write(bin_file, |
|
ds@1952
|
498 |
(unsigned char *)pOrig->base + sizeof(sp_file_hdr_t), |
|
ds@1952
|
499 |
pHdr->dataoffs - sizeof(sp_file_hdr_t)); |
|
ds@1952
|
500 |
|
|
ds@1952
|
501 |
header_size = pHdr->dataoffs; |
|
ds@1952
|
502 |
size = pHdr->imagesize - header_size; |
|
ds@1952
|
503 |
proper = (unsigned char *)pOrig->base + header_size; |
|
ds@1952
|
504 |
|
|
ds@1952
|
505 |
/* get initial size estimate */ |
|
ds@1952
|
506 |
disksize = compressBound(pHdr->imagesize); |
|
ds@1952
|
507 |
pHdr->disksize = (uint32_t)disksize; |
|
ds@1952
|
508 |
zcmp = (Bytef *)malloc(pHdr->disksize); |
|
ds@1952
|
509 |
|
|
ds@1952
|
510 |
if ((err=compress2(zcmp, |
|
ds@1952
|
511 |
&disksize, |
|
ds@1952
|
512 |
(Bytef *)proper, |
|
ds@1952
|
513 |
(uLong)size, |
|
ds@1952
|
514 |
Z_BEST_COMPRESSION)) |
|
ds@1952
|
515 |
!= Z_OK) |
|
ds@1952
|
516 |
{ |
|
ds@1952
|
517 |
free(zcmp); |
|
ds@1952
|
518 |
pc_printf("Unable to compress (Z): error %d\n", err); |
|
ds@1952
|
519 |
pc_printf("Falling back to no compression."); |
|
ds@1952
|
520 |
memfile_write(bin_file, |
|
ds@1952
|
521 |
proper, |
|
ds@1952
|
522 |
size); |
|
ds@1952
|
523 |
} else { |
|
ds@1952
|
524 |
pHdr->disksize = (uint32_t)disksize + header_size; |
|
ds@1952
|
525 |
pHdr->compression = SPFILE_COMPRESSION_GZ; |
|
ds@1952
|
526 |
memfile_write(bin_file, |
|
ds@1952
|
527 |
(unsigned char *)zcmp, |
|
ds@1952
|
528 |
disksize); |
|
ds@1952
|
529 |
free(zcmp); |
|
ds@1952
|
530 |
} |
|
ds@1952
|
531 |
} |
|
ds@1952
|
532 |
|
|
ds@1952
|
533 |
spfw_destroy(spf); |
|
ds@1952
|
534 |
memfile_destroy(dbgtab); |
|
ds@1952
|
535 |
|
|
ds@1952
|
536 |
/** |
|
ds@1952
|
537 |
* write file |
|
ds@1952
|
538 |
*/ |
|
ds@1952
|
539 |
if ((fp=fopen(bin_file->name, "wb")) != NULL) |
|
ds@1952
|
540 |
{ |
|
ds@1952
|
541 |
fwrite(bin_file->base, bin_file->usedoffs, 1, fp); |
|
ds@1952
|
542 |
fclose(fp); |
|
ds@1952
|
543 |
} else { |
|
ds@1952
|
544 |
pc_printf("Unable to open %s for writing!", bin_file->name); |
|
ds@1952
|
545 |
} |
|
ds@1952
|
546 |
|
|
ds@1952
|
547 |
memfile_destroy(bin_file); |
|
ds@1952
|
548 |
|
|
ds@1952
|
549 |
return 0; |
|
ds@1952
|
550 |
|
|
ds@1952
|
551 |
write_error: |
|
ds@1952
|
552 |
pc_printf("Error writing to file: %s", bin_file->name); |
|
ds@1952
|
553 |
|
|
ds@1952
|
554 |
spfw_destroy(spf); |
|
ds@1952
|
555 |
unlink(bin_file->name); |
|
ds@1952
|
556 |
memfile_destroy(bin_file); |
|
ds@1952
|
557 |
memfile_destroy(dbgtab); |
|
ds@1952
|
558 |
|
|
ds@1952
|
559 |
return 1; |
|
ds@1952
|
560 |
} |
|
ds@1952
|
561 |
|
|
ds@1952
|
562 |
return 1; |
|
ds@1952
|
563 |
} |
|
ds@1952
|
564 |
|
|
ds@1952
|
565 |
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf) |
|
ds@1952
|
566 |
{ |
|
ds@1952
|
567 |
if (spf->funcs.fnWrite(buf, size, count, spf->handle) != count) |
|
ds@1952
|
568 |
{ |
|
ds@1952
|
569 |
longjmp(brkout, 1); |
|
ds@1952
|
570 |
} |
|
ds@1952
|
571 |
} |
|
dvander@2326
|
572 |
|
|
dvander@2326
|
573 |
void sp_fdbg_ntv_start(int num_natives) |
|
dvander@2326
|
574 |
{ |
|
dvander@2326
|
575 |
if (num_natives == 0) |
|
dvander@2326
|
576 |
{ |
|
dvander@2326
|
577 |
return; |
|
dvander@2326
|
578 |
} |
|
dvander@2326
|
579 |
|
|
dvander@2326
|
580 |
native_list = (t_native *)malloc(sizeof(t_native) * num_natives); |
|
dvander@2326
|
581 |
memset(native_list, 0, sizeof(t_native) * num_natives); |
|
dvander@2326
|
582 |
} |
|
dvander@2326
|
583 |
|
|
dvander@2326
|
584 |
#include "sc.h" |
|
dvander@2326
|
585 |
|
|
dvander@2326
|
586 |
void sp_fdbg_ntv_hook(int index, symbol *sym) |
|
dvander@2326
|
587 |
{ |
|
dvander@2326
|
588 |
int i, j; |
|
dvander@2326
|
589 |
t_native *native; |
|
dvander@2326
|
590 |
|
|
dvander@2326
|
591 |
native = &native_list[index]; |
|
dvander@2326
|
592 |
native->name = strdup(sym->name); |
|
dvander@2326
|
593 |
|
|
dvander@2326
|
594 |
for (i = 0; i < sMAXARGS; i++) |
|
dvander@2326
|
595 |
{ |
|
dvander@2326
|
596 |
if (sym->dim.arglist[i].ident == 0) |
|
dvander@2326
|
597 |
{ |
|
dvander@2326
|
598 |
break; |
|
dvander@2326
|
599 |
} |
|
dvander@2326
|
600 |
native->num_args++; |
|
dvander@2326
|
601 |
native->args[i].tag = sym->dim.arglist[i].tags == NULL ? 0 : sym->dim.arglist[i].tags[0]; |
|
dvander@2326
|
602 |
native->args[i].name = strdup(sym->dim.arglist[i].name); |
|
dvander@2326
|
603 |
native->args[i].ident = sym->dim.arglist[i].ident; |
|
dvander@2326
|
604 |
native->args[i].dimcount = sym->dim.arglist[i].numdim; |
|
dvander@2326
|
605 |
for (j = 0; j < native->args[i].dimcount; j++) |
|
dvander@2326
|
606 |
{ |
|
dvander@2326
|
607 |
native->args[i].dims[j].size = sym->dim.arglist[i].dim[j]; |
|
dvander@2326
|
608 |
native->args[i].dims[j].tagid = sym->dim.arglist[i].idxtag[j]; |
|
dvander@2326
|
609 |
} |
|
dvander@2326
|
610 |
} |
|
dvander@2326
|
611 |
|
|
dvander@2326
|
612 |
native->ret_tag = sym->tag; |
|
dvander@2326
|
613 |
} |