|
dvander@27
|
1 |
#include <stdio.h> |
|
dvander@27
|
2 |
#include <setjmp.h> |
|
dvander@27
|
3 |
#include <assert.h> |
|
dvander@27
|
4 |
#include <string.h> |
|
dvander@27
|
5 |
#include "memfile.h" |
|
dvander@27
|
6 |
#include "sp_file.h" |
|
dvander@27
|
7 |
#include "amx.h" |
|
dvander@31
|
8 |
#include "amxdbg.h" |
|
dvander@27
|
9 |
#include "osdefs.h" |
|
dvander@27
|
10 |
#include "zlib/zlib.h" |
|
dvander@27
|
11 |
|
|
dvander@29
|
12 |
enum FileSections |
|
dvander@29
|
13 |
{ |
|
dvander@29
|
14 |
FS_Code, /* required */ |
|
dvander@29
|
15 |
FS_Data, /* required */ |
|
dvander@29
|
16 |
FS_Publics, |
|
dvander@29
|
17 |
FS_Pubvars, |
|
dvander@29
|
18 |
FS_Natives, |
|
faluco@144
|
19 |
FS_Libraries, |
|
dvander@29
|
20 |
FS_Nametable, /* required */ |
|
dvander@29
|
21 |
FS_DbgFile, |
|
dvander@29
|
22 |
FS_DbgSymbol, |
|
dvander@29
|
23 |
FS_DbgLine, |
|
dvander@29
|
24 |
FS_DbgTags, |
|
dvander@29
|
25 |
FS_DbgAutomaton, |
|
dvander@29
|
26 |
FS_DbgState, |
|
dvander@31
|
27 |
FS_DbgStrings, |
|
dvander@46
|
28 |
FS_DbgInfo, |
|
dvander@29
|
29 |
/* --- */ |
|
dvander@29
|
30 |
FS_Number, |
|
dvander@29
|
31 |
}; |
|
dvander@27
|
32 |
|
|
dvander@27
|
33 |
int pc_printf(const char *message,...); |
|
dvander@27
|
34 |
int pc_compile(int argc, char **argv); |
|
dvander@29
|
35 |
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf); |
|
dvander@27
|
36 |
|
|
dvander@27
|
37 |
memfile_t *bin_file = NULL; |
|
dvander@27
|
38 |
jmp_buf brkout; |
|
dvander@27
|
39 |
|
|
dvander@27
|
40 |
int main(int argc, char *argv[]) |
|
dvander@27
|
41 |
{ |
|
dvander@343
|
42 |
#if defined _DEBUG |
|
dvander@343
|
43 |
getchar(); |
|
dvander@343
|
44 |
#endif |
|
dvander@27
|
45 |
if (pc_compile(argc,argv) == 0) |
|
dvander@27
|
46 |
{ |
|
dvander@27
|
47 |
AMX_HEADER *hdr; |
|
dvander@31
|
48 |
AMX_DBG_HDR *dbg = NULL; |
|
dvander@27
|
49 |
int err; |
|
dvander@27
|
50 |
uint32_t i; |
|
dvander@29
|
51 |
sp_file_t *spf; |
|
dvander@132
|
52 |
memfile_t *dbgtab = NULL; //dbgcrab |
|
dvander@31
|
53 |
unsigned char *dbgptr = NULL; |
|
faluco@144
|
54 |
uint32_t sections[FS_Number] = {1,1,0,0,0,0,1,0,0,0,0,0,0}; |
|
dvander@31
|
55 |
FILE *fp; |
|
dvander@27
|
56 |
|
|
dvander@27
|
57 |
if (bin_file == NULL) |
|
dvander@27
|
58 |
{ |
|
dvander@27
|
59 |
return 0; |
|
dvander@27
|
60 |
} |
|
dvander@27
|
61 |
|
|
dvander@27
|
62 |
hdr = (AMX_HEADER *)bin_file->base; |
|
dvander@27
|
63 |
|
|
dvander@29
|
64 |
if ((spf=spfw_create(bin_file->name, NULL)) == NULL) |
|
dvander@27
|
65 |
{ |
|
dvander@29
|
66 |
pc_printf("Error creating binary file!\n"); |
|
dvander@29
|
67 |
memfile_destroy(bin_file); |
|
dvander@29
|
68 |
return 0; |
|
dvander@27
|
69 |
} |
|
dvander@27
|
70 |
|
|
dvander@27
|
71 |
if ((err=setjmp(brkout))!=0) |
|
dvander@27
|
72 |
{ |
|
dvander@27
|
73 |
goto write_error; |
|
dvander@27
|
74 |
} |
|
dvander@27
|
75 |
|
|
dvander@29
|
76 |
spfw_add_section(spf, ".code"); |
|
dvander@29
|
77 |
spfw_add_section(spf, ".data"); |
|
dvander@27
|
78 |
|
|
dvander@29
|
79 |
sections[FS_Publics] = (hdr->natives - hdr->publics) / hdr->defsize; |
|
dvander@29
|
80 |
if (sections[FS_Publics]) |
|
dvander@27
|
81 |
{ |
|
dvander@29
|
82 |
spfw_add_section(spf, ".publics"); |
|
dvander@29
|
83 |
} |
|
dvander@29
|
84 |
sections[FS_Pubvars] = (hdr->tags - hdr->pubvars) / hdr->defsize; |
|
dvander@29
|
85 |
if (sections[FS_Pubvars]) |
|
dvander@29
|
86 |
{ |
|
dvander@29
|
87 |
spfw_add_section(spf, ".pubvars"); |
|
dvander@29
|
88 |
} |
|
dvander@29
|
89 |
sections[FS_Natives] = (hdr->libraries - hdr->natives) / hdr->defsize; |
|
dvander@29
|
90 |
if (sections[FS_Natives]) |
|
dvander@29
|
91 |
{ |
|
dvander@29
|
92 |
spfw_add_section(spf, ".natives"); |
|
dvander@27
|
93 |
} |
|
faluco@144
|
94 |
sections[FS_Libraries] = (hdr->pubvars - hdr->libraries) / hdr->defsize; |
|
faluco@144
|
95 |
if (sections[FS_Libraries]) |
|
faluco@144
|
96 |
{ |
|
faluco@144
|
97 |
spfw_add_section(spf, ".libraries"); |
|
faluco@144
|
98 |
} |
|
dvander@27
|
99 |
|
|
dvander@29
|
100 |
spfw_add_section(spf, ".names"); |
|
dvander@27
|
101 |
|
|
dvander@31
|
102 |
if (hdr->flags & AMX_FLAG_DEBUG) |
|
dvander@31
|
103 |
{ |
|
dvander@31
|
104 |
dbg = (AMX_DBG_HDR *)((unsigned char *)hdr + hdr->size); |
|
dvander@31
|
105 |
if (dbg->magic != AMX_DBG_MAGIC) |
|
dvander@31
|
106 |
{ |
|
dvander@31
|
107 |
pc_printf("Error reading AMX_DBG_HDR, debug data will not be written."); |
|
dvander@31
|
108 |
} else { |
|
dvander@31
|
109 |
dbgtab = memfile_creat("", 512); |
|
dvander@31
|
110 |
dbgptr = (unsigned char *)dbg + sizeof(AMX_DBG_HDR); |
|
dvander@31
|
111 |
if (dbg->files) |
|
dvander@31
|
112 |
{ |
|
dvander@31
|
113 |
spfw_add_section(spf, ".dbg.files"); |
|
dvander@31
|
114 |
sections[FS_DbgFile] = dbg->files; |
|
dvander@31
|
115 |
} |
|
dvander@31
|
116 |
if (dbg->lines) |
|
dvander@31
|
117 |
{ |
|
dvander@31
|
118 |
spfw_add_section(spf, ".dbg.lines"); |
|
dvander@31
|
119 |
sections[FS_DbgLine] = dbg->lines; |
|
dvander@31
|
120 |
} |
|
dvander@31
|
121 |
if (dbg->symbols) |
|
dvander@31
|
122 |
{ |
|
dvander@31
|
123 |
spfw_add_section(spf, ".dbg.symbols"); |
|
dvander@31
|
124 |
sections[FS_DbgSymbol] = dbg->symbols; |
|
dvander@31
|
125 |
} |
|
dvander@46
|
126 |
sections[FS_DbgInfo] = 1; |
|
dvander@31
|
127 |
sections[FS_DbgStrings] = 1; |
|
dvander@46
|
128 |
spfw_add_section(spf, ".dbg.info"); |
|
dvander@31
|
129 |
spfw_add_section(spf, ".dbg.strings"); |
|
dvander@31
|
130 |
} |
|
dvander@31
|
131 |
} |
|
dvander@31
|
132 |
|
|
dvander@29
|
133 |
spfw_finalize_header(spf); |
|
dvander@29
|
134 |
|
|
dvander@27
|
135 |
/** |
|
dvander@27
|
136 |
* Begin writing each of our known tables out |
|
dvander@27
|
137 |
*/ |
|
dvander@27
|
138 |
|
|
dvander@29
|
139 |
if (sections[FS_Code]) |
|
dvander@27
|
140 |
{ |
|
dvander@27
|
141 |
sp_file_code_t cod; |
|
dvander@27
|
142 |
unsigned char *cbase; |
|
dvander@27
|
143 |
|
|
dvander@27
|
144 |
cod.cellsize = sizeof(cell); |
|
dvander@27
|
145 |
|
|
dvander@38
|
146 |
cod.codesize = hdr->dat - hdr->cod; |
|
dvander@27
|
147 |
cod.codeversion = hdr->amx_version; |
|
dvander@27
|
148 |
cod.flags = 0; |
|
dvander@27
|
149 |
if (hdr->flags & AMX_FLAG_DEBUG) |
|
dvander@27
|
150 |
{ |
|
faluco@62
|
151 |
cod.flags |= SP_FLAG_DEBUG; |
|
dvander@27
|
152 |
} |
|
dvander@27
|
153 |
cod.code = sizeof(cod); |
|
dvander@27
|
154 |
cod.main = hdr->cip; |
|
dvander@27
|
155 |
|
|
dvander@38
|
156 |
/* write the code */ |
|
dvander@27
|
157 |
cbase = (unsigned char *)hdr + hdr->cod; |
|
dvander@29
|
158 |
sfwrite(&cod, sizeof(cod), 1, spf); |
|
dvander@38
|
159 |
sfwrite(cbase, cod.codesize, 1, spf); |
|
dvander@27
|
160 |
|
|
dvander@29
|
161 |
spfw_next_section(spf); |
|
dvander@27
|
162 |
} |
|
dvander@27
|
163 |
|
|
dvander@29
|
164 |
if (sections[FS_Data]) |
|
dvander@27
|
165 |
{ |
|
dvander@27
|
166 |
sp_file_data_t dat; |
|
dvander@31
|
167 |
unsigned char *dbase = (unsigned char *)hdr + hdr->dat; |
|
dvander@27
|
168 |
|
|
dvander@27
|
169 |
dat.datasize = hdr->hea - hdr->dat; |
|
dvander@27
|
170 |
dat.memsize = hdr->stp; |
|
dvander@27
|
171 |
dat.data = sizeof(dat); |
|
dvander@31
|
172 |
|
|
dvander@31
|
173 |
/* write header */ |
|
dvander@31
|
174 |
sfwrite(&dat, sizeof(dat), 1, spf); |
|
dvander@27
|
175 |
|
|
dvander@27
|
176 |
if (dat.datasize) |
|
dvander@27
|
177 |
{ |
|
dvander@31
|
178 |
/* write data */ |
|
dvander@31
|
179 |
sfwrite(dbase, dat.datasize, 1, spf); |
|
dvander@27
|
180 |
} |
|
dvander@27
|
181 |
|
|
dvander@29
|
182 |
spfw_next_section(spf); |
|
dvander@27
|
183 |
} |
|
dvander@27
|
184 |
|
|
dvander@29
|
185 |
if (sections[FS_Publics]) |
|
dvander@27
|
186 |
{ |
|
dvander@27
|
187 |
sp_file_publics_t *pbtbl; |
|
dvander@27
|
188 |
AMX_FUNCSTUBNT *stub; |
|
dvander@45
|
189 |
unsigned char *stubptr; |
|
dvander@29
|
190 |
uint32_t publics = sections[FS_Publics]; |
|
dvander@27
|
191 |
|
|
dvander@27
|
192 |
pbtbl = (sp_file_publics_t *)malloc(sizeof(sp_file_publics_t) * publics); |
|
dvander@45
|
193 |
stubptr = (unsigned char *)hdr + hdr->publics; |
|
dvander@27
|
194 |
|
|
dvander@27
|
195 |
for (i=0; i<publics; i++) |
|
dvander@27
|
196 |
{ |
|
dvander@45
|
197 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
dvander@27
|
198 |
pbtbl[i].address = stub->address; |
|
dvander@27
|
199 |
pbtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
dvander@27
|
200 |
|
|
dvander@45
|
201 |
stubptr += hdr->defsize; |
|
dvander@27
|
202 |
} |
|
dvander@27
|
203 |
if (publics) |
|
dvander@27
|
204 |
{ |
|
dvander@29
|
205 |
sfwrite(pbtbl, sizeof(sp_file_publics_t), publics, spf); |
|
dvander@27
|
206 |
} |
|
dvander@27
|
207 |
free(pbtbl); |
|
dvander@27
|
208 |
|
|
dvander@29
|
209 |
spfw_next_section(spf); |
|
dvander@27
|
210 |
} |
|
dvander@27
|
211 |
|
|
dvander@29
|
212 |
if (sections[FS_Pubvars]) |
|
dvander@27
|
213 |
{ |
|
dvander@27
|
214 |
sp_file_pubvars_t *pbvars; |
|
dvander@27
|
215 |
AMX_FUNCSTUBNT *stub; |
|
dvander@45
|
216 |
unsigned char *stubptr; |
|
dvander@29
|
217 |
uint32_t pubvars = sections[FS_Pubvars]; |
|
dvander@27
|
218 |
|
|
dvander@27
|
219 |
pbvars = (sp_file_pubvars_t *)malloc(sizeof(sp_file_pubvars_t) * pubvars); |
|
dvander@45
|
220 |
stubptr = (unsigned char *)hdr + hdr->pubvars; |
|
dvander@27
|
221 |
|
|
dvander@27
|
222 |
for (i=0; i<pubvars; i++) |
|
dvander@27
|
223 |
{ |
|
dvander@45
|
224 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
dvander@27
|
225 |
pbvars[i].address = stub->address; |
|
dvander@27
|
226 |
pbvars[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
dvander@27
|
227 |
|
|
dvander@45
|
228 |
stubptr += hdr->defsize; |
|
dvander@27
|
229 |
} |
|
dvander@27
|
230 |
if (pubvars) |
|
dvander@27
|
231 |
{ |
|
dvander@29
|
232 |
sfwrite(pbvars, sizeof(sp_file_pubvars_t), pubvars, spf); |
|
dvander@27
|
233 |
} |
|
dvander@27
|
234 |
free(pbvars); |
|
dvander@29
|
235 |
spfw_next_section(spf); |
|
dvander@27
|
236 |
} |
|
dvander@27
|
237 |
|
|
dvander@29
|
238 |
if (sections[FS_Natives]) |
|
dvander@27
|
239 |
{ |
|
dvander@27
|
240 |
sp_file_natives_t *nvtbl; |
|
dvander@27
|
241 |
AMX_FUNCSTUBNT *stub; |
|
dvander@45
|
242 |
unsigned char *stubptr; |
|
dvander@27
|
243 |
uint32_t natives = (hdr->libraries - hdr->natives) / hdr->defsize; |
|
dvander@27
|
244 |
|
|
dvander@27
|
245 |
nvtbl = (sp_file_natives_t *)malloc(sizeof(sp_file_natives_t) * natives); |
|
dvander@45
|
246 |
stubptr = (unsigned char *)hdr + hdr->natives; |
|
dvander@27
|
247 |
|
|
dvander@27
|
248 |
for (i=0; i<natives; i++) |
|
dvander@27
|
249 |
{ |
|
dvander@45
|
250 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
dvander@27
|
251 |
nvtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
dvander@27
|
252 |
|
|
dvander@45
|
253 |
stubptr += hdr->defsize; |
|
dvander@27
|
254 |
} |
|
dvander@27
|
255 |
if (natives) |
|
dvander@27
|
256 |
{ |
|
dvander@29
|
257 |
sfwrite(nvtbl, sizeof(sp_file_natives_t), natives, spf); |
|
dvander@27
|
258 |
} |
|
dvander@27
|
259 |
free(nvtbl); |
|
dvander@29
|
260 |
spfw_next_section(spf); |
|
dvander@27
|
261 |
} |
|
dvander@27
|
262 |
|
|
faluco@144
|
263 |
if (sections[FS_Libraries]) |
|
faluco@144
|
264 |
{ |
|
faluco@144
|
265 |
sp_file_libraries_t *libtbl; |
|
faluco@144
|
266 |
AMX_FUNCSTUBNT *stub; |
|
faluco@144
|
267 |
unsigned char *stubptr; |
|
faluco@144
|
268 |
uint32_t libraries = sections[FS_Libraries]; |
|
faluco@144
|
269 |
|
|
faluco@144
|
270 |
libtbl = (sp_file_libraries_t *)malloc(sizeof(sp_file_libraries_t) * libraries); |
|
faluco@144
|
271 |
stubptr = (unsigned char *)hdr + hdr->libraries; |
|
faluco@144
|
272 |
|
|
faluco@144
|
273 |
for (i=0; i<libraries; i++) |
|
faluco@144
|
274 |
{ |
|
faluco@144
|
275 |
stub = (AMX_FUNCSTUBNT *)stubptr; |
|
faluco@144
|
276 |
libtbl[i].name = stub->nameofs - (hdr->nametable + sizeof(uint16_t)); |
|
faluco@144
|
277 |
|
|
faluco@144
|
278 |
stubptr += hdr->defsize; |
|
faluco@144
|
279 |
} |
|
faluco@144
|
280 |
if (libraries) |
|
faluco@144
|
281 |
{ |
|
faluco@144
|
282 |
sfwrite(libtbl, sizeof(sp_file_libraries_t), libraries, spf); |
|
faluco@144
|
283 |
} |
|
faluco@144
|
284 |
free(libtbl); |
|
faluco@144
|
285 |
spfw_next_section(spf); |
|
faluco@144
|
286 |
} |
|
faluco@144
|
287 |
|
|
dvander@29
|
288 |
if (sections[FS_Nametable]) |
|
dvander@27
|
289 |
{ |
|
dvander@27
|
290 |
unsigned char *base; |
|
dvander@27
|
291 |
uint32_t namelen; |
|
dvander@27
|
292 |
|
|
dvander@27
|
293 |
/* write the entire block */ |
|
dvander@27
|
294 |
base = (unsigned char *)hdr + hdr->nametable + sizeof(uint16_t); |
|
dvander@27
|
295 |
/** |
|
dvander@27
|
296 |
* note - the name table will be padded to sizeof(cell) bytes. |
|
dvander@27
|
297 |
* this may clip at most an extra three bytes in! |
|
dvander@27
|
298 |
*/ |
|
dvander@27
|
299 |
namelen = hdr->cod - hdr->nametable; |
|
dvander@29
|
300 |
sfwrite(base, namelen, 1, spf); |
|
dvander@29
|
301 |
spfw_next_section(spf); |
|
dvander@27
|
302 |
} |
|
dvander@27
|
303 |
|
|
dvander@31
|
304 |
if (hdr->flags & AMX_FLAG_DEBUG) |
|
dvander@31
|
305 |
{ |
|
dvander@46
|
306 |
sp_fdbg_info_t info; |
|
dvander@46
|
307 |
|
|
dvander@46
|
308 |
memset(&info, 0, sizeof(sp_fdbg_info_t)); |
|
dvander@46
|
309 |
|
|
dvander@31
|
310 |
if (sections[FS_DbgFile]) |
|
dvander@31
|
311 |
{ |
|
dvander@31
|
312 |
uint32_t idx; |
|
dvander@31
|
313 |
sp_fdbg_file_t dbgfile; |
|
dvander@31
|
314 |
AMX_DBG_FILE *_ptr; |
|
dvander@31
|
315 |
uint32_t len; |
|
dvander@31
|
316 |
for (idx=0; idx<sections[FS_DbgFile]; idx++) |
|
dvander@31
|
317 |
{ |
|
dvander@31
|
318 |
/* get entry info */ |
|
dvander@31
|
319 |
_ptr = (AMX_DBG_FILE *)dbgptr; |
|
dvander@31
|
320 |
len = strlen(_ptr->name); |
|
dvander@31
|
321 |
/* store */ |
|
dvander@31
|
322 |
dbgfile.addr = _ptr->address; |
|
dvander@31
|
323 |
dbgfile.name = (uint32_t)memfile_tell(dbgtab); |
|
dvander@31
|
324 |
sfwrite(&dbgfile, sizeof(sp_fdbg_file_t), 1, spf); |
|
dvander@31
|
325 |
/* write to tab, then move to next */ |
|
dvander@31
|
326 |
memfile_write(dbgtab, _ptr->name, len + 1); |
|
dvander@31
|
327 |
dbgptr += sizeof(AMX_DBG_FILE) + len; |
|
dvander@46
|
328 |
info.num_files++; |
|
dvander@31
|
329 |
} |
|
dvander@31
|
330 |
spfw_next_section(spf); |
|
dvander@31
|
331 |
} |
|
dvander@31
|
332 |
|
|
dvander@31
|
333 |
if (sections[FS_DbgLine]) |
|
dvander@31
|
334 |
{ |
|
dvander@31
|
335 |
uint32_t idx; |
|
dvander@31
|
336 |
AMX_DBG_LINE *line; |
|
dvander@31
|
337 |
sp_fdbg_line_t dbgline; |
|
dvander@31
|
338 |
for (idx=0; idx<sections[FS_DbgLine]; idx++) |
|
dvander@31
|
339 |
{ |
|
dvander@31
|
340 |
/* get entry info */ |
|
dvander@31
|
341 |
line = (AMX_DBG_LINE *)dbgptr; |
|
dvander@31
|
342 |
/* store */ |
|
dvander@31
|
343 |
dbgline.addr = (uint32_t)line->address; |
|
dvander@31
|
344 |
dbgline.line = (uint32_t)line->line; |
|
dvander@31
|
345 |
sfwrite(&dbgline, sizeof(sp_fdbg_line_t), 1, spf); |
|
dvander@31
|
346 |
/* move to next */ |
|
dvander@31
|
347 |
dbgptr += sizeof(AMX_DBG_LINE); |
|
dvander@46
|
348 |
info.num_lines++; |
|
dvander@31
|
349 |
} |
|
dvander@31
|
350 |
spfw_next_section(spf); |
|
dvander@31
|
351 |
} |
|
dvander@31
|
352 |
|
|
dvander@31
|
353 |
if (sections[FS_DbgSymbol]) |
|
dvander@31
|
354 |
{ |
|
dvander@31
|
355 |
uint32_t idx; |
|
dvander@31
|
356 |
uint32_t dnum; |
|
dvander@31
|
357 |
AMX_DBG_SYMBOL *sym; |
|
dvander@31
|
358 |
AMX_DBG_SYMDIM *dim; |
|
dvander@31
|
359 |
sp_fdbg_symbol_t dbgsym; |
|
dvander@31
|
360 |
sp_fdbg_arraydim_t dbgdim; |
|
dvander@31
|
361 |
uint32_t len; |
|
dvander@31
|
362 |
|
|
dvander@31
|
363 |
for (idx=0; idx<sections[FS_DbgSymbol]; idx++) |
|
dvander@31
|
364 |
{ |
|
dvander@31
|
365 |
/* get entry info */ |
|
dvander@31
|
366 |
sym = (AMX_DBG_SYMBOL *)dbgptr; |
|
dvander@31
|
367 |
/* store */ |
|
dvander@31
|
368 |
dbgsym.addr = *(int32_t *)&sym->address; |
|
dvander@31
|
369 |
dbgsym.tagid = sym->tag; |
|
dvander@31
|
370 |
dbgsym.codestart = (uint32_t)sym->codestart; |
|
dvander@31
|
371 |
dbgsym.codeend = (uint32_t)sym->codeend; |
|
dvander@31
|
372 |
dbgsym.dimcount = (uint16_t)sym->dim; |
|
dvander@31
|
373 |
dbgsym.vclass = (uint8_t)sym->vclass; |
|
dvander@31
|
374 |
dbgsym.ident = (uint8_t)sym->ident; |
|
dvander@31
|
375 |
dbgsym.name = (uint32_t)memfile_tell(dbgtab); |
|
dvander@31
|
376 |
sfwrite(&dbgsym, sizeof(sp_fdbg_symbol_t), 1, spf); |
|
dvander@31
|
377 |
/* write to tab */ |
|
dvander@31
|
378 |
len = strlen(sym->name); |
|
dvander@31
|
379 |
memfile_write(dbgtab, sym->name, len + 1); |
|
dvander@31
|
380 |
/* move to next */ |
|
dvander@31
|
381 |
dbgptr += sizeof(AMX_DBG_SYMBOL) + len; |
|
dvander@31
|
382 |
/* look for any dimensions */ |
|
dvander@46
|
383 |
info.num_syms++; |
|
dvander@31
|
384 |
for (dnum=0; dnum<dbgsym.dimcount; dnum++) |
|
dvander@31
|
385 |
{ |
|
dvander@31
|
386 |
/* get entry info */ |
|
dvander@31
|
387 |
dim = (AMX_DBG_SYMDIM *)dbgptr; |
|
dvander@31
|
388 |
/* store */ |
|
dvander@31
|
389 |
dbgdim.size = (uint32_t)dim->size; |
|
dvander@31
|
390 |
dbgdim.tagid = dim->tag; |
|
dvander@31
|
391 |
sfwrite(&dbgdim, sizeof(sp_fdbg_arraydim_t), 1, spf); |
|
dvander@31
|
392 |
/* move to next */ |
|
dvander@31
|
393 |
dbgptr += sizeof(AMX_DBG_SYMDIM); |
|
dvander@46
|
394 |
info.num_arrays++; |
|
dvander@31
|
395 |
} |
|
dvander@31
|
396 |
} |
|
dvander@31
|
397 |
spfw_next_section(spf); |
|
dvander@31
|
398 |
} |
|
dvander@31
|
399 |
|
|
dvander@46
|
400 |
sfwrite(&info, sizeof(sp_fdbg_info_t), 1, spf); |
|
dvander@46
|
401 |
spfw_next_section(spf); |
|
dvander@46
|
402 |
|
|
dvander@31
|
403 |
if (sections[FS_DbgStrings]) |
|
dvander@31
|
404 |
{ |
|
dvander@31
|
405 |
sfwrite(dbgtab->base, sizeof(char), dbgtab->usedoffs, spf); |
|
dvander@31
|
406 |
spfw_next_section(spf); |
|
dvander@31
|
407 |
} |
|
dvander@31
|
408 |
} |
|
dvander@31
|
409 |
|
|
dvander@29
|
410 |
spfw_finalize_all(spf); |
|
dvander@31
|
411 |
|
|
dvander@31
|
412 |
/** |
|
dvander@31
|
413 |
* do compression |
|
dvander@31
|
414 |
* new block for scoping only |
|
dvander@31
|
415 |
*/ |
|
dvander@31
|
416 |
if (1) |
|
dvander@31
|
417 |
{ |
|
dvander@31
|
418 |
memfile_t *pOrig = (memfile_t *)spf->handle; |
|
dvander@31
|
419 |
sp_file_hdr_t *pHdr; |
|
dvander@31
|
420 |
unsigned char *proper; |
|
dvander@31
|
421 |
size_t size; |
|
dvander@31
|
422 |
Bytef *zcmp; |
|
dvander@31
|
423 |
uLong disksize; |
|
dvander@35
|
424 |
size_t header_size; |
|
dvander@31
|
425 |
int err = Z_OK; |
|
dvander@31
|
426 |
|
|
dvander@31
|
427 |
/* reuse this memory block! */ |
|
dvander@31
|
428 |
memfile_reset(bin_file); |
|
dvander@31
|
429 |
|
|
dvander@31
|
430 |
/* copy tip of header */ |
|
dvander@31
|
431 |
memfile_write(bin_file, pOrig->base, sizeof(sp_file_hdr_t)); |
|
dvander@31
|
432 |
|
|
dvander@31
|
433 |
/* get pointer to header */ |
|
dvander@31
|
434 |
pHdr = (sp_file_hdr_t *)bin_file->base; |
|
dvander@31
|
435 |
|
|
dvander@31
|
436 |
/* copy the rest of the header */ |
|
dvander@31
|
437 |
memfile_write(bin_file, |
|
dvander@31
|
438 |
(unsigned char *)pOrig->base + sizeof(sp_file_hdr_t), |
|
dvander@31
|
439 |
pHdr->dataoffs - sizeof(sp_file_hdr_t)); |
|
dvander@31
|
440 |
|
|
dvander@35
|
441 |
header_size = pHdr->dataoffs; |
|
dvander@35
|
442 |
size = pHdr->imagesize - header_size; |
|
dvander@35
|
443 |
proper = (unsigned char *)pOrig->base + header_size; |
|
dvander@31
|
444 |
|
|
dvander@31
|
445 |
/* get initial size estimate */ |
|
dvander@295
|
446 |
pHdr->disksize = (uint32_t)compressBound(pHdr->imagesize) * 2; |
|
dvander@31
|
447 |
zcmp = (Bytef *)malloc(pHdr->disksize); |
|
dvander@31
|
448 |
|
|
dvander@31
|
449 |
if ((err=compress2(zcmp, |
|
dvander@31
|
450 |
&disksize, |
|
dvander@31
|
451 |
(Bytef *)proper, |
|
dvander@31
|
452 |
(uLong)size, |
|
dvander@31
|
453 |
Z_BEST_COMPRESSION)) |
|
dvander@31
|
454 |
!= Z_OK) |
|
dvander@31
|
455 |
{ |
|
dvander@31
|
456 |
free(zcmp); |
|
dvander@295
|
457 |
pc_printf("Unable to compress (Z): error %d\n", err); |
|
dvander@31
|
458 |
pc_printf("Falling back to no compression."); |
|
dvander@31
|
459 |
memfile_write(bin_file, |
|
dvander@31
|
460 |
proper, |
|
dvander@31
|
461 |
size); |
|
dvander@31
|
462 |
} else { |
|
dvander@35
|
463 |
pHdr->disksize = (uint32_t)disksize + header_size; |
|
dvander@31
|
464 |
pHdr->compression = SPFILE_COMPRESSION_GZ; |
|
dvander@31
|
465 |
memfile_write(bin_file, |
|
dvander@31
|
466 |
(unsigned char *)zcmp, |
|
dvander@35
|
467 |
disksize); |
|
dvander@31
|
468 |
free(zcmp); |
|
dvander@31
|
469 |
} |
|
dvander@31
|
470 |
} |
|
dvander@31
|
471 |
|
|
dvander@29
|
472 |
spfw_destroy(spf); |
|
dvander@31
|
473 |
memfile_destroy(dbgtab); |
|
dvander@31
|
474 |
|
|
dvander@31
|
475 |
/** |
|
dvander@31
|
476 |
* write file |
|
dvander@31
|
477 |
*/ |
|
dvander@31
|
478 |
if ((fp=fopen(bin_file->name, "wb")) != NULL) |
|
dvander@31
|
479 |
{ |
|
dvander@31
|
480 |
fwrite(bin_file->base, bin_file->usedoffs, 1, fp); |
|
dvander@31
|
481 |
fclose(fp); |
|
dvander@31
|
482 |
} else { |
|
dvander@31
|
483 |
pc_printf("Unable to open %s for writing!", bin_file->name); |
|
dvander@31
|
484 |
} |
|
dvander@31
|
485 |
|
|
dvander@31
|
486 |
memfile_destroy(bin_file); |
|
dvander@27
|
487 |
|
|
dvander@27
|
488 |
return 0; |
|
dvander@27
|
489 |
|
|
dvander@27
|
490 |
write_error: |
|
dvander@27
|
491 |
pc_printf("Error writing to file: %s", bin_file->name); |
|
dvander@31
|
492 |
|
|
dvander@31
|
493 |
spfw_destroy(spf); |
|
dvander@27
|
494 |
unlink(bin_file->name); |
|
dvander@27
|
495 |
memfile_destroy(bin_file); |
|
dvander@31
|
496 |
memfile_destroy(dbgtab); |
|
dvander@27
|
497 |
|
|
dvander@27
|
498 |
return 1; |
|
dvander@27
|
499 |
} |
|
dvander@27
|
500 |
|
|
dvander@27
|
501 |
return 1; |
|
dvander@27
|
502 |
} |
|
dvander@27
|
503 |
|
|
dvander@29
|
504 |
void sfwrite(const void *buf, size_t size, size_t count, sp_file_t *spf) |
|
dvander@27
|
505 |
{ |
|
dvander@29
|
506 |
if (spf->funcs.fnWrite(buf, size, count, spf->handle) != count) |
|
dvander@27
|
507 |
{ |
|
dvander@27
|
508 |
longjmp(brkout, 1); |
|
dvander@27
|
509 |
} |
|
dvander@27
|
510 |
} |