sourcepawn/vm/sp_reader.c
author Borja Ferrer <faluco@alliedmods.net>
Fri Aug 04 19:09:41 2006 +0000 (2006-08-04)
changeset 53 805202a58dba
parent 49 6e490d2f1df5
child 60 1828af9008a5
permissions -rw-r--r--
push functions and some little fixes
faluco@41
     1
#include <malloc.h>
faluco@41
     2
#include <string.h>
faluco@41
     3
#include "sp_vm.h"
faluco@41
     4
#include "zlib/zlib.h"
faluco@41
     5
faluco@41
     6
sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin, int *err)
faluco@41
     7
{
faluco@41
     8
	char *nameptr;
faluco@41
     9
	uint8_t sectnum = 0;
faluco@41
    10
	sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
faluco@41
    11
faluco@41
    12
	memset(plugin, 0, sizeof(sp_plugin_t));
faluco@41
    13
faluco@41
    14
	plugin->base = base;
faluco@41
    15
faluco@41
    16
	while (sectnum < hdr->sections)
faluco@41
    17
	{
faluco@41
    18
		nameptr = base + hdr->stringtab + secptr->nameoffs;
faluco@41
    19
faluco@41
    20
		if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
faluco@41
    21
		{
faluco@41
    22
			sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
faluco@41
    23
			plugin->pcode = base + secptr->dataoffs + cod->code;
faluco@41
    24
			plugin->pcode_size = cod->codesize;
faluco@41
    25
			plugin->flags = cod->flags;
faluco@41
    26
		}
faluco@41
    27
		else if (!(plugin->data) && !strcmp(nameptr, ".data"))
faluco@41
    28
		{
faluco@41
    29
			sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
faluco@41
    30
			plugin->data = base + secptr->dataoffs + dat->data;
faluco@41
    31
			plugin->data_size = dat->datasize;
faluco@41
    32
			plugin->memory = dat->memsize;
faluco@41
    33
		}
faluco@49
    34
		else if (!(plugin->info.publics) && !strcmp(nameptr, ".publics"))
faluco@41
    35
		{
faluco@49
    36
			plugin->info.publics_num = secptr->size / sizeof(sp_file_publics_t);
faluco@49
    37
			plugin->info.publics = (sp_file_publics_t *)(base + secptr->dataoffs);
faluco@41
    38
		}
faluco@49
    39
		else if (!(plugin->info.pubvars) && !strcmp(nameptr, ".pubvars"))
faluco@41
    40
		{
faluco@49
    41
			plugin->info.pubvars_num = secptr->size / sizeof(sp_file_pubvars_t);
faluco@49
    42
			plugin->info.pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
faluco@41
    43
		}
faluco@49
    44
		else if (!(plugin->info.natives) && !strcmp(nameptr, ".natives"))
faluco@41
    45
		{
faluco@49
    46
			plugin->info.natives_num = secptr->size / sizeof(sp_file_natives_t);
faluco@49
    47
			plugin->info.natives = (sp_file_natives_t *)(base + secptr->dataoffs);
faluco@41
    48
		}
faluco@49
    49
		else if (!(plugin->info.stringbase) && !strcmp(nameptr, ".names"))
faluco@47
    50
		{
faluco@49
    51
			plugin->info.stringbase = base + secptr->dataoffs;
faluco@47
    52
		}
faluco@49
    53
		else if (!(plugin->debug.files) && !strcmp(nameptr, ".dbg.files"))
faluco@41
    54
		{
faluco@49
    55
			plugin->debug.files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
faluco@41
    56
		}
faluco@49
    57
		else if (!(plugin->debug.lines) && !strcmp(nameptr, ".dbg.lines"))
faluco@47
    58
		{
faluco@49
    59
			plugin->debug.lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
faluco@47
    60
		}
faluco@49
    61
		else if (!(plugin->debug.symbols) && !strcmp(nameptr, ".dbg.symbols"))
faluco@47
    62
		{
faluco@49
    63
			plugin->debug.symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
faluco@47
    64
		}
faluco@49
    65
		else if (!(plugin->debug.lines_num) && !strcmp(nameptr, ".dbg.info"))
faluco@47
    66
		{
faluco@47
    67
			sp_fdbg_info_t *inf = (sp_fdbg_info_t *)(base + secptr->dataoffs);
faluco@49
    68
			plugin->debug.files_num = inf->num_files;
faluco@49
    69
			plugin->debug.lines_num = inf->num_lines;
faluco@49
    70
			plugin->debug.syms_num = inf->num_syms;
faluco@47
    71
		}
faluco@49
    72
		else if (!(plugin->debug.stringbase) && !strcmp(nameptr, ".dbg.strings"))
faluco@41
    73
		{
faluco@49
    74
			plugin->debug.stringbase = base + secptr->dataoffs;
faluco@41
    75
		}
faluco@47
    76
faluco@41
    77
		secptr++;
faluco@41
    78
		sectnum++;
faluco@41
    79
	}
faluco@41
    80
faluco@49
    81
	if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
faluco@53
    82
	{
faluco@41
    83
		goto return_error;
faluco@53
    84
	}
faluco@41
    85
faluco@49
    86
	if ((plugin->flags == SP_FILE_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
faluco@53
    87
	{
faluco@41
    88
		goto return_error;
faluco@53
    89
	}
faluco@41
    90
faluco@44
    91
	if (err)
faluco@53
    92
	{
faluco@44
    93
		*err = SP_ERR_NONE;
faluco@53
    94
	}
faluco@44
    95
faluco@41
    96
	return plugin;
faluco@41
    97
faluco@41
    98
return_error:
faluco@41
    99
	if (err)
faluco@53
   100
	{
faluco@41
   101
		*err = SP_ERR_FILE_FORMAT;
faluco@53
   102
	}
faluco@41
   103
faluco@41
   104
	return NULL;
faluco@41
   105
}
faluco@41
   106
faluco@41
   107
sp_plugin_t *SP_LoadFromFilePointer(FILE *fp, int *err)
faluco@41
   108
{
faluco@41
   109
	sp_file_hdr_t hdr;
faluco@41
   110
	sp_plugin_t *plugin;
faluco@41
   111
	uint8_t *base;
faluco@41
   112
	int z_result;
faluco@41
   113
	int error;
faluco@41
   114
faluco@41
   115
	if (!fp)
faluco@41
   116
	{
faluco@41
   117
		error = SP_ERR_NOT_FOUND;
faluco@41
   118
		goto return_error;
faluco@41
   119
	}
faluco@41
   120
faluco@41
   121
	/* Rewind for safety */
faluco@41
   122
	rewind(fp);
faluco@41
   123
	fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
faluco@41
   124
faluco@41
   125
	if (hdr.magic != SPFILE_MAGIC)
faluco@41
   126
	{
faluco@41
   127
		error = SP_ERR_FILE_FORMAT;
faluco@41
   128
		goto return_error;
faluco@41
   129
	}
faluco@41
   130
faluco@41
   131
	switch (hdr.compression)
faluco@41
   132
	{
faluco@41
   133
	case SPFILE_COMPRESSION_GZ:
faluco@41
   134
		{
faluco@41
   135
			uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
faluco@41
   136
			uint32_t compsize = hdr.disksize - hdr.dataoffs;
faluco@41
   137
			uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
faluco@41
   138
			uLongf destlen = uncompsize;
faluco@41
   139
faluco@41
   140
			char *tempbuf = (char *)malloc(compsize);
faluco@41
   141
			void *uncompdata = malloc(uncompsize);
faluco@41
   142
			void *sectheader = malloc(sectsize);
faluco@41
   143
faluco@41
   144
			fread(sectheader, sectsize, 1, fp);
faluco@41
   145
			fread(tempbuf, compsize, 1, fp);
faluco@41
   146
faluco@41
   147
			z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
faluco@41
   148
			free(tempbuf);
faluco@41
   149
			if (z_result != Z_OK)
faluco@41
   150
			{
faluco@41
   151
				free(sectheader);
faluco@41
   152
				free(uncompdata);
faluco@41
   153
				error = SP_ERR_DECOMPRESSOR;
faluco@41
   154
				goto return_error;
faluco@41
   155
			}
faluco@41
   156
faluco@41
   157
			base = (uint8_t *)malloc(hdr.imagesize);
faluco@41
   158
			memcpy(base, &hdr, sizeof(sp_file_hdr_t));
faluco@41
   159
			memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
faluco@41
   160
			free(sectheader);
faluco@41
   161
			memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
faluco@41
   162
			free(uncompdata);
faluco@41
   163
			break;
faluco@41
   164
		}
faluco@41
   165
	case SPFILE_COMPRESSION_NONE:
faluco@41
   166
		{
faluco@41
   167
			base = (uint8_t *)malloc(hdr.imagesize);
faluco@41
   168
			rewind(fp);
faluco@41
   169
			fread(base, hdr.imagesize, 1, fp);
faluco@41
   170
			break;
faluco@41
   171
		}
faluco@41
   172
	default:
faluco@41
   173
		{
faluco@41
   174
			error = SP_ERR_DECOMPRESSOR;
faluco@41
   175
			goto return_error;
faluco@41
   176
		}
faluco@41
   177
	}
faluco@41
   178
faluco@41
   179
	plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
faluco@41
   180
	if (!_ReadPlugin(&hdr, base, plugin, err))
faluco@41
   181
	{
faluco@41
   182
		free(plugin);
faluco@41
   183
		free(base);
faluco@41
   184
		return NULL;
faluco@41
   185
	}
faluco@41
   186
faluco@41
   187
	return plugin;
faluco@41
   188
faluco@41
   189
return_error:
faluco@41
   190
	if (err)
faluco@53
   191
	{
faluco@41
   192
		*err = error;
faluco@53
   193
	}
faluco@41
   194
	return NULL;
faluco@41
   195
}
faluco@41
   196
faluco@41
   197
sp_plugin_t *SP_LoadFromMemory(void *base, sp_plugin_t *plugin, int *err)
faluco@41
   198
{
faluco@41
   199
	sp_file_hdr_t hdr;
faluco@41
   200
	uint8_t noptr = 0;
faluco@41
   201
faluco@41
   202
	memcpy(&hdr, base, sizeof(sp_file_hdr_t));
faluco@41
   203
faluco@41
   204
	if (!plugin)
faluco@41
   205
	{
faluco@41
   206
		plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
faluco@41
   207
		noptr = 1;
faluco@41
   208
	}
faluco@41
   209
faluco@41
   210
	if (!_ReadPlugin(&hdr, base, plugin, err))
faluco@41
   211
	{
faluco@41
   212
		if (noptr)
faluco@53
   213
		{
faluco@41
   214
			free(plugin);
faluco@53
   215
		}
faluco@41
   216
		return NULL;
faluco@41
   217
	}
faluco@41
   218
faluco@41
   219
	return plugin;
faluco@41
   220
}