sourcepawn/compiler/pawncc.c
author David Anderson <dvander@alliedmods.net>
Wed Feb 25 20:07:12 2009 -0500 (2009-02-25)
changeset 2607 f3b8bbe17f85
parent 2326 73d538a35c26
child 2783 5f333027ef04
permissions -rw-r--r--
Backed out changeset fa286305bd3f
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
}