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