10 #include "zlib/zlib.h"
14 FS_Code, /* required */
15 FS_Data, /* required */
19 FS_Nametable, /* required */
34 int pc_printf(const char *message,...);
35 int pc_compile(int argc, char **argv);
36 void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf);
38 memfile_t *bin_file = NULL;
41 #define sARGS_MAX 32 /* number of arguments a function can have, max */
42 #define sDIMEN_MAX 4 /* maximum number of array dimensions */
44 typedef struct t_arg_s
50 sp_fdbg_arraydim_t dims[sDIMEN_MAX];
53 typedef struct t_native_s
58 t_arg args[sARGS_MAX];
61 t_native *native_list = NULL;
63 int main(int argc, char *argv[])
68 if (pc_compile(argc,argv) == 0)
71 AMX_DBG_HDR *dbg = NULL;
75 memfile_t *dbgtab = NULL; //dbgcrab
76 unsigned char *dbgptr = NULL;
77 uint32_t sections[FS_Number] = {1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0};
85 hdr = (AMX_HEADER *)bin_file->base;
87 if ((spf=spfw_create(bin_file->name, NULL)) == NULL)
89 pc_printf("Error creating binary file!\n");
90 memfile_destroy(bin_file);
94 if ((err=setjmp(brkout))!=0)
99 spfw_add_section(spf, ".code");
100 spfw_add_section(spf, ".data");
102 sections[FS_Publics] = (hdr->natives - hdr->publics) / hdr->defsize;
103 if (sections[FS_Publics])
105 spfw_add_section(spf, ".publics");
107 sections[FS_Pubvars] = (hdr->tags - hdr->pubvars) / hdr->defsize;
108 if (sections[FS_Pubvars])
110 spfw_add_section(spf, ".pubvars");
112 sections[FS_Natives] = (hdr->libraries - hdr->natives) / hdr->defsize;
113 if (sections[FS_Natives])
115 spfw_add_section(spf, ".natives");
117 sections[FS_Tags] = (hdr->nametable - hdr->tags) / hdr->defsize;
118 if (sections[FS_Tags])
120 spfw_add_section(spf, ".tags");
123 spfw_add_section(spf, ".names");
125 if (hdr->flags & AMX_FLAG_DEBUG)
127 dbg = (AMX_DBG_HDR *)((unsigned char *)hdr + hdr->size);
128 if (dbg->magic != AMX_DBG_MAGIC)
130 pc_printf("Error reading AMX_DBG_HDR, debug data will not be written.");
132 dbgtab = memfile_creat("", 512);
133 dbgptr = (unsigned char *)dbg + sizeof(AMX_DBG_HDR);
134 if ((sections[FS_DbgNatives] = sections[FS_Natives]) > 0)
136 spfw_add_section(spf, ".dbg.natives");
140 spfw_add_section(spf, ".dbg.files");
141 sections[FS_DbgFile] = dbg->files;
145 spfw_add_section(spf, ".dbg.lines");
146 sections[FS_DbgLine] = dbg->lines;
150 spfw_add_section(spf, ".dbg.symbols");
151 sections[FS_DbgSymbol] = dbg->symbols;
153 sections[FS_DbgInfo] = 1;
154 sections[FS_DbgStrings] = 1;
155 spfw_add_section(spf, ".dbg.info");
156 spfw_add_section(spf, ".dbg.strings");
160 spfw_finalize_header(spf);
163 * Begin writing each of our known tables out
166 if (sections[FS_Code])
169 unsigned char *cbase;
171 cod.cellsize = sizeof(cell);
173 cod.codesize = hdr->dat - hdr->cod;
174 cod.codeversion = hdr->amx_version;
176 if (hdr->flags & AMX_FLAG_DEBUG)
178 cod.flags |= SP_FLAG_DEBUG;
180 cod.code = sizeof(cod);
184 cbase = (unsigned char *)hdr + hdr->cod;
185 sfwrite(&cod, sizeof(cod), 1, spf);
186 sfwrite(cbase, cod.codesize, 1, spf);
188 spfw_next_section(spf);
191 if (sections[FS_Data])
194 unsigned char *dbase = (unsigned char *)hdr + hdr->dat;
196 dat.datasize = hdr->hea - hdr->dat;
197 dat.memsize = hdr->stp;
198 dat.data = sizeof(dat);
201 sfwrite(&dat, sizeof(dat), 1, spf);
206 sfwrite(dbase, dat.datasize, 1, spf);
209 spfw_next_section(spf);
212 if (sections[FS_Publics])
214 sp_file_publics_t *pbtbl;
215 AMX_FUNCSTUBNT *stub;
216 unsigned char *stubptr;
217 uint32_t publics = sections[FS_Publics];
219 pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics);
220 stubptr = (unsigned char *)hdr + hdr->publics;
222 for (i=0; i<publics; i++)
224 stub = (AMX_FUNCSTUBNT *)stubptr;
225 pbtbl[i].address = stub->address;
226 pbtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
228 stubptr += hdr->defsize;
232 sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, spf);
236 spfw_next_section(spf);
239 if (sections[FS_Pubvars])
241 sp_file_pubvars_t *pbvars;
242 AMX_FUNCSTUBNT *stub;
243 unsigned char *stubptr;
244 uint32_t pubvars = sections[FS_Pubvars];
246 pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars);
247 stubptr = (unsigned char *)hdr + hdr->pubvars;
249 for (i=0; i<pubvars; i++)
251 stub = (AMX_FUNCSTUBNT *)stubptr;
252 pbvars[i].address = stub->address;
253 pbvars[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
255 stubptr += hdr->defsize;
259 sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, spf);
262 spfw_next_section(spf);
265 if (sections[FS_Natives])
267 sp_file_natives_t *nvtbl;
268 AMX_FUNCSTUBNT *stub;
269 unsigned char *stubptr;
270 uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize;
272 nvtbl = (sp_file_natives_t *)malloc(sizeof(sp_file_natives_t) * natives);
273 stubptr = (unsigned char *)hdr + hdr->natives;
275 for (i=0; i<natives; i++)
277 stub = (AMX_FUNCSTUBNT *)stubptr;
278 nvtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
280 stubptr += hdr->defsize;
284 sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, spf);
287 spfw_next_section(spf);
290 if (sections[FS_Tags])
292 uint32_t numTags = (uint32_t)sections[FS_Tags];
293 AMX_FUNCSTUBNT *stub;
296 for (i=0; i<numTags; i++)
298 stub = (AMX_FUNCSTUBNT *)((unsigned char *)hdr + hdr->tags + (i * hdr->defsize));
299 tag.tag_id = stub->address;
300 tag.name = stub->nameofs - (hdr->nametable + sizeof(uint16_t));
301 sfwrite(&tag, sizeof(sp_file_tag_t), 1, spf);
303 spfw_next_section(spf);
306 if (sections[FS_Nametable])
311 /* write the entire block */
312 base = (unsigned char *)hdr + hdr->nametable + sizeof(uint16_t);
314 * note - the name table will be padded to sizeof(cell) bytes.
315 * this may clip at most an extra three bytes in!
317 namelen = hdr->cod - hdr->nametable;
318 sfwrite(base, namelen, 1, spf);
319 spfw_next_section(spf);
322 if (hdr->flags & AMX_FLAG_DEBUG)
326 memset(&info, 0, sizeof(sp_fdbg_info_t));
328 if (sections[FS_Natives])
333 uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize;
335 sfwrite(&natives, sizeof(uint32_t), 1, spf);
336 for (idx=0; idx<natives; idx++)
338 sfwrite(&idx, sizeof(uint32_t), 1, spf);
339 name = (uint32_t)memfile_tell(dbgtab);
340 memfile_write(dbgtab, native_list[idx].name, strlen(native_list[idx].name) + 1);
341 sfwrite(&name, sizeof(uint32_t), 1, spf);
342 sfwrite(&native_list[idx].ret_tag, sizeof(int16_t), 1, spf);
343 sfwrite(&native_list[idx].num_args, sizeof(uint16_t), 1, spf);
345 /* Go through arguments */
346 for (j = 0; j < native_list[idx].num_args; j++)
348 sfwrite(&native_list[idx].args[j].ident, sizeof(uint8_t), 1, spf);
349 sfwrite(&native_list[idx].args[j].tag, sizeof(int16_t), 1, spf);
350 sfwrite(&native_list[idx].args[j].dimcount, sizeof(uint16_t), 1, spf);
351 name = (uint32_t)memfile_tell(dbgtab);
352 sfwrite(&name, sizeof(uint32_t), 1, spf);
353 memfile_write(dbgtab,
354 native_list[idx].args[j].name,
355 strlen(native_list[idx].args[j].name) + 1);
356 if (native_list[idx].args[j].dimcount)
358 sfwrite(native_list[idx].args[j].dims,
359 sizeof(sp_fdbg_arraydim_t),
360 native_list[idx].args[j].dimcount,
363 free(native_list[idx].args[j].name);
365 free(native_list[idx].name);
368 spfw_next_section(spf);
371 if (sections[FS_DbgFile])
374 sp_fdbg_file_t dbgfile;
377 for (idx=0; idx<sections[FS_DbgFile]; idx++)
380 _ptr = (AMX_DBG_FILE *)dbgptr;
381 len = strlen(_ptr->name);
383 dbgfile.addr = _ptr->address;
384 dbgfile.name = (uint32_t)memfile_tell(dbgtab);
385 sfwrite(&dbgfile, sizeof(sp_fdbg_file_t), 1, spf);
386 /* write to tab, then move to next */
387 memfile_write(dbgtab, _ptr->name, len + 1);
388 dbgptr += sizeof(AMX_DBG_FILE) + len;
391 spfw_next_section(spf);
394 if (sections[FS_DbgLine])
398 sp_fdbg_line_t dbgline;
399 for (idx=0; idx<sections[FS_DbgLine]; idx++)
402 line = (AMX_DBG_LINE *)dbgptr;
404 dbgline.addr = (uint32_t)line->address;
405 dbgline.line = (uint32_t)line->line;
406 sfwrite(&dbgline, sizeof(sp_fdbg_line_t), 1, spf);
408 dbgptr += sizeof(AMX_DBG_LINE);
411 spfw_next_section(spf);
414 if (sections[FS_DbgSymbol])
420 sp_fdbg_symbol_t dbgsym;
421 sp_fdbg_arraydim_t dbgdim;
424 for (idx=0; idx<sections[FS_DbgSymbol]; idx++)
427 sym = (AMX_DBG_SYMBOL *)dbgptr;
429 dbgsym.addr = *(int32_t *)&sym->address;
430 dbgsym.tagid = sym->tag;
431 dbgsym.codestart = (uint32_t)sym->codestart;
432 dbgsym.codeend = (uint32_t)sym->codeend;
433 dbgsym.dimcount = (uint16_t)sym->dim;
434 dbgsym.vclass = (uint8_t)sym->vclass;
435 dbgsym.ident = (uint8_t)sym->ident;
436 dbgsym.name = (uint32_t)memfile_tell(dbgtab);
437 sfwrite(&dbgsym, sizeof(sp_fdbg_symbol_t), 1, spf);
439 len = strlen(sym->name);
440 memfile_write(dbgtab, sym->name, len + 1);
442 dbgptr += sizeof(AMX_DBG_SYMBOL) + len;
443 /* look for any dimensions */
445 for (dnum=0; dnum<dbgsym.dimcount; dnum++)
448 dim = (AMX_DBG_SYMDIM *)dbgptr;
450 dbgdim.size = (uint32_t)dim->size;
451 dbgdim.tagid = dim->tag;
452 sfwrite(&dbgdim, sizeof(sp_fdbg_arraydim_t), 1, spf);
454 dbgptr += sizeof(AMX_DBG_SYMDIM);
458 spfw_next_section(spf);
461 sfwrite(&info, sizeof(sp_fdbg_info_t), 1, spf);
462 spfw_next_section(spf);
464 if (sections[FS_DbgStrings])
466 sfwrite(dbgtab->base, sizeof(char), dbgtab->usedoffs, spf);
467 spfw_next_section(spf);
471 spfw_finalize_all(spf);
475 * new block for scoping only
478 memfile_t *pOrig = (memfile_t *)spf->handle;
480 unsigned char *proper;
487 /* reuse this memory block! */
488 memfile_reset(bin_file);
490 /* copy tip of header */
491 memfile_write(bin_file, pOrig->base, sizeof(sp_file_hdr_t));
493 /* get pointer to header */
494 pHdr = (sp_file_hdr_t *)bin_file->base;
496 /* copy the rest of the header */
497 memfile_write(bin_file,
498 (unsigned char *)pOrig->base + sizeof(sp_file_hdr_t),
499 pHdr->dataoffs - sizeof(sp_file_hdr_t));
501 header_size = pHdr->dataoffs;
502 size = pHdr->imagesize - header_size;
503 proper = (unsigned char *)pOrig->base + header_size;
505 /* get initial size estimate */
506 disksize = compressBound(pHdr->imagesize);
507 pHdr->disksize = (uint32_t)disksize;
508 zcmp = (Bytef *)malloc(pHdr->disksize);
510 if ((err=compress2(zcmp,
518 pc_printf("Unable to compress (Z): error %d\n", err);
519 pc_printf("Falling back to no compression.");
520 memfile_write(bin_file,
524 pHdr->disksize = (uint32_t)disksize + header_size;
525 pHdr->compression = SPFILE_COMPRESSION_GZ;
526 memfile_write(bin_file,
527 (unsigned char *)zcmp,
534 memfile_destroy(dbgtab);
539 if ((fp=fopen(bin_file->name, "wb")) != NULL)
541 fwrite(bin_file->base, bin_file->usedoffs, 1, fp);
544 pc_printf("Unable to open %s for writing!", bin_file->name);
547 memfile_destroy(bin_file);
552 pc_printf("Error writing to file: %s", bin_file->name);
555 unlink(bin_file->name);
556 memfile_destroy(bin_file);
557 memfile_destroy(dbgtab);
565 void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf)
567 if (spf->funcs.fnWrite(buf, size, count, spf->handle) != count)
573 void sp_fdbg_ntv_start(int num_natives)
575 if (num_natives == 0)
580 native_list = (t_native *)malloc(sizeof(t_native) * num_natives);
581 memset(native_list, 0, sizeof(t_native) * num_natives);
586 void sp_fdbg_ntv_hook(int index, symbol *sym)
591 native = &native_list[index];
592 native->name = strdup(sym->name);
594 for (i = 0; i < sMAXARGS; i++)
596 if (sym->dim.arglist[i].ident == 0)
601 native->args[i].tag = sym->dim.arglist[i].tags == NULL ? 0 : sym->dim.arglist[i].tags[0];
602 native->args[i].name = strdup(sym->dim.arglist[i].name);
603 native->args[i].ident = sym->dim.arglist[i].ident;
604 native->args[i].dimcount = sym->dim.arglist[i].numdim;
605 for (j = 0; j < native->args[i].dimcount; j++)
607 native->args[i].dims[j].size = sym->dim.arglist[i].dim[j];
608 native->args[i].dims[j].tagid = sym->dim.arglist[i].idxtag[j];
612 native->ret_tag = sym->tag;