1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/sourcepawn/vm/sp_reader.c Tue Aug 01 00:21:00 2006 +0000
1.3 @@ -0,0 +1,211 @@
1.4 +#include <malloc.h>
1.5 +#include <string.h>
1.6 +#include "sp_vm.h"
1.7 +#include "zlib/zlib.h"
1.8 +
1.9 +sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin, int *err)
1.10 +{
1.11 + char *nameptr;
1.12 + uint8_t sectnum = 0;
1.13 +
1.14 + sp_plugin_infotab_t *info = (sp_plugin_infotab_t *)malloc(sizeof(sp_plugin_infotab_t));
1.15 + sp_plugin_debug_t *dbg = (sp_plugin_debug_t *)malloc(sizeof(sp_plugin_debug_t));
1.16 +
1.17 + sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
1.18 +
1.19 + memset(plugin, 0, sizeof(sp_plugin_t));
1.20 + memset(info, 0, sizeof(sp_plugin_infotab_t));
1.21 + memset(dbg, 0, sizeof(sp_plugin_debug_t));
1.22 +
1.23 + plugin->base = base;
1.24 + plugin->info = info;
1.25 + plugin->debug = dbg;
1.26 +
1.27 + while (sectnum < hdr->sections)
1.28 + {
1.29 + nameptr = base + hdr->stringtab + secptr->nameoffs;
1.30 +
1.31 + if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
1.32 + {
1.33 + sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
1.34 + plugin->pcode = base + secptr->dataoffs + cod->code;
1.35 + plugin->pcode_size = cod->codesize;
1.36 + plugin->flags = cod->flags;
1.37 + }
1.38 + else if (!(plugin->data) && !strcmp(nameptr, ".data"))
1.39 + {
1.40 + sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
1.41 + plugin->data = base + secptr->dataoffs + dat->data;
1.42 + plugin->data_size = dat->datasize;
1.43 + plugin->memory = dat->memsize;
1.44 + }
1.45 + else if (!(plugin->info->stringbase) && !strcmp(nameptr, ".names"))
1.46 + {
1.47 + plugin->info->stringbase = base + secptr->dataoffs;
1.48 + }
1.49 + else if (!(plugin->info->publics) && !strcmp(nameptr, ".publics"))
1.50 + {
1.51 + plugin->info->publics_num = secptr->size / sizeof(sp_file_publics_t);
1.52 + plugin->info->publics = (sp_file_publics_t *)(base + secptr->dataoffs);
1.53 + }
1.54 + else if (!(plugin->info->pubvars) && !strcmp(nameptr, ".pubvars"))
1.55 + {
1.56 + plugin->info->pubvars_num = secptr->size / sizeof(sp_file_pubvars_t);
1.57 + plugin->info->pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
1.58 + }
1.59 + else if (!(plugin->info->natives) && !strcmp(nameptr, ".natives"))
1.60 + {
1.61 + plugin->info->natives_num = secptr->size / sizeof(sp_file_natives_t);
1.62 + plugin->info->natives = (sp_file_natives_t *)(base + secptr->dataoffs);
1.63 + }
1.64 + else if (!(plugin->debug->files) && !strcmp(nameptr, ".dbg.files"))
1.65 + {
1.66 + plugin->debug->files_num = secptr->size / sizeof(sp_fdbg_file_t);
1.67 + plugin->debug->files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
1.68 + }
1.69 + else if (!(plugin->debug->stringbase) && !strcmp(nameptr, ".dbg.strings"))
1.70 + {
1.71 + plugin->debug->stringbase = base + secptr->dataoffs;
1.72 + }
1.73 + else if (!(plugin->debug->lines) && !strcmp(nameptr, ".dbg.lines"))
1.74 + {
1.75 + plugin->debug->lines_num = secptr->size / sizeof(sp_fdbg_line_t);
1.76 + plugin->debug->lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
1.77 + }
1.78 + else if (!(plugin->debug->symbols) && !strcmp(nameptr, ".dbg.symbols"))
1.79 + {
1.80 + plugin->debug->syms_num = secptr->size / sizeof(sp_fdbg_symbol_t);
1.81 + plugin->debug->symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
1.82 + }
1.83 + secptr++;
1.84 + sectnum++;
1.85 + }
1.86 +
1.87 + if (!(plugin->pcode) || !(plugin->data) || !(plugin->info->stringbase))
1.88 + goto return_error;
1.89 +
1.90 + if ((plugin->flags == SP_FILE_DEBUG) && (!(plugin->debug->files) || !(plugin->debug->lines) || !(plugin->debug->symbols)))
1.91 + goto return_error;
1.92 +
1.93 + return plugin;
1.94 +
1.95 +return_error:
1.96 + free(dbg);
1.97 + free(info);
1.98 +
1.99 + if (err)
1.100 + *err = SP_ERR_FILE_FORMAT;
1.101 +
1.102 + return NULL;
1.103 +}
1.104 +
1.105 +sp_plugin_t *SP_LoadFromFilePointer(FILE *fp, int *err)
1.106 +{
1.107 + sp_file_hdr_t hdr;
1.108 + sp_plugin_t *plugin;
1.109 + uint8_t *base;
1.110 + int z_result;
1.111 + int error;
1.112 +
1.113 + if (!fp)
1.114 + {
1.115 + error = SP_ERR_NOT_FOUND;
1.116 + goto return_error;
1.117 + }
1.118 +
1.119 + /* Rewind for safety */
1.120 + rewind(fp);
1.121 + fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
1.122 +
1.123 + if (hdr.magic != SPFILE_MAGIC)
1.124 + {
1.125 + error = SP_ERR_FILE_FORMAT;
1.126 + goto return_error;
1.127 + }
1.128 +
1.129 + switch (hdr.compression)
1.130 + {
1.131 + case SPFILE_COMPRESSION_GZ:
1.132 + {
1.133 + uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
1.134 + uint32_t compsize = hdr.disksize - hdr.dataoffs;
1.135 + uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
1.136 + uLongf destlen = uncompsize;
1.137 +
1.138 + char *tempbuf = (char *)malloc(compsize);
1.139 + void *uncompdata = malloc(uncompsize);
1.140 + void *sectheader = malloc(sectsize);
1.141 +
1.142 + fread(sectheader, sectsize, 1, fp);
1.143 + fread(tempbuf, compsize, 1, fp);
1.144 +
1.145 + z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
1.146 + free(tempbuf);
1.147 + if (z_result != Z_OK)
1.148 + {
1.149 + free(sectheader);
1.150 + free(uncompdata);
1.151 + error = SP_ERR_DECOMPRESSOR;
1.152 + goto return_error;
1.153 + }
1.154 +
1.155 + base = (uint8_t *)malloc(hdr.imagesize);
1.156 + memcpy(base, &hdr, sizeof(sp_file_hdr_t));
1.157 + memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
1.158 + free(sectheader);
1.159 + memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
1.160 + free(uncompdata);
1.161 + break;
1.162 + }
1.163 + case SPFILE_COMPRESSION_NONE:
1.164 + {
1.165 + base = (uint8_t *)malloc(hdr.imagesize);
1.166 + rewind(fp);
1.167 + fread(base, hdr.imagesize, 1, fp);
1.168 + break;
1.169 + }
1.170 + default:
1.171 + {
1.172 + error = SP_ERR_DECOMPRESSOR;
1.173 + goto return_error;
1.174 + }
1.175 + }
1.176 +
1.177 + plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
1.178 + if (!_ReadPlugin(&hdr, base, plugin, err))
1.179 + {
1.180 + free(plugin);
1.181 + free(base);
1.182 + return NULL;
1.183 + }
1.184 +
1.185 + return plugin;
1.186 +
1.187 +return_error:
1.188 + if (err)
1.189 + *err = error;
1.190 + return NULL;
1.191 +}
1.192 +
1.193 +sp_plugin_t *SP_LoadFromMemory(void *base, sp_plugin_t *plugin, int *err)
1.194 +{
1.195 + sp_file_hdr_t hdr;
1.196 + uint8_t noptr = 0;
1.197 +
1.198 + memcpy(&hdr, base, sizeof(sp_file_hdr_t));
1.199 +
1.200 + if (!plugin)
1.201 + {
1.202 + plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
1.203 + noptr = 1;
1.204 + }
1.205 +
1.206 + if (!_ReadPlugin(&hdr, base, plugin, err))
1.207 + {
1.208 + if (noptr)
1.209 + free(plugin);
1.210 + return NULL;
1.211 + }
1.212 +
1.213 + return plugin;
1.214 +}