+ --debug is now --imcc-debug; make this more consistent with -D.
[parrot.git] / src / exec_save.c
blob9a6361031bf60c6c4774569e2a4eac1104ce6165
1 /*
2 Copyright (C) 2001-2003, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/exec_save.c - Save object file in native format
9 =head1 DESCRIPTION
11 Save the C<Parrot_exec_objfile_t> to the native format.
13 =head2 Functions
15 =over 4
17 =cut
21 /* HEADERIZER HFILE: none */
22 /* HEADERIZER STOP */
24 #include <parrot/parrot.h>
25 #include "parrot/exec.h"
26 #include "exec_save.h"
28 static void save_zero(FILE *fp);
29 static void save_int(FILE *fp, int i);
30 static void save_short(FILE *fp, short s);
31 static void save_struct(FILE *fp, void *sp, size_t size);
33 #ifdef EXEC_A_OUT
35 # include <a.out.h>
36 # include <link.h>
40 =item C<void
41 Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)>
43 Save the C<Parrot_exec_objfile_t> to C<file>.
45 =cut
49 void
50 Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
52 FILE *fp;
53 int i;
54 struct exec header;
55 struct relocation_info rellocation;
56 struct nlist symlst;
58 fp = fopen(file, "w");
60 header.a_midmag = 0x07018600;
61 header.a_text = obj->text.size;
62 header.a_data = obj->data.size;
63 header.a_bss = obj->bss.size;
64 header.a_syms = obj->symbol_count * sizeof (struct nlist);
65 header.a_entry = 0;
66 header.a_trsize = obj->text_rellocation_count
67 * sizeof (struct relocation_info);
68 header.a_drsize = obj->data_rellocation_count
69 * sizeof (struct relocation_info);
70 save_struct(fp, &header, sizeof (struct exec));
71 /* Text */
72 for (i = 0; i < obj->text.size; i++)
73 fprintf(fp, "%c", obj->text.code[i]);
74 /* Data */
75 for (i = 0; i < obj->data.size; i++)
76 fprintf(fp, "%c", obj->data.code[i]);
77 /* Text rellocations */
78 for (i = obj->text_rellocation_count - 1; i >= 0; i--) {
79 bzero(&rellocation, sizeof (struct relocation_info));
80 rellocation.r_address = obj->text_rellocation_table[i].offset;
81 rellocation.r_symbolnum = obj->text_rellocation_table[i].symbol_number;
82 switch (obj->text_rellocation_table[i].type) {
83 case RTYPE_FUNC:
84 rellocation.r_pcrel = 1;
85 rellocation.r_length = 2;
86 rellocation.r_extern = 1;
87 break;
88 case RTYPE_COM:
89 case RTYPE_DATA:
90 rellocation.r_length = 2;
91 rellocation.r_extern = 1;
92 break;
93 default:
94 real_exception(interp, NULL, EXEC_ERROR,
95 "Unknown text rellocation type: %d\n",
96 obj->text_rellocation_table[i].type);
97 break;
99 save_struct(fp, &rellocation, sizeof (struct relocation_info));
101 /* Symbol table */
102 for (i = 0; i < obj->symbol_count; i++) {
103 bzero(&symlst, sizeof (struct nlist));
104 symlst.n_un.n_strx = obj->symbol_table[i].offset_list;
105 switch (obj->symbol_table[i].type) {
106 case STYPE_FUNC:
107 symlst.n_type = N_EXT | N_TEXT;
108 symlst.n_other = AUX_FUNC;
109 break;
110 case STYPE_GDATA:
111 symlst.n_type = N_EXT | N_DATA;
112 symlst.n_other = AUX_OBJECT;
113 symlst.n_value = obj->symbol_table[i].value;
114 break;
115 case STYPE_COM:
116 symlst.n_type = N_EXT;
117 symlst.n_value = obj->symbol_table[i].value;
118 break;
119 case STYPE_UND:
120 symlst.n_type = N_EXT;
121 break;
122 default:
123 real_exception(interp, NULL, EXEC_ERROR, "Unknown symbol type: %d\n",
124 obj->symbol_table[i].type);
125 break;
127 save_struct(fp, &symlst, sizeof (struct nlist));
129 /* String table size */
130 save_int(fp, obj->symbol_list_size);
131 /* String table */
132 for (i = 0; i < obj->symbol_count; i++) {
133 if (obj->symbol_table[i].type != STYPE_GCC)
134 fprintf(fp, "_%s", obj->symbol_table[i].symbol);
135 else
136 fprintf(fp, "%s", obj->symbol_table[i].symbol);
137 save_zero(fp);
139 fclose(fp);
142 #endif /* EXEC_A_OUT */
144 #ifdef EXEC_ELF
146 # ifdef PARROT_EXEC_OS_OPENBSD
147 # define R_386_32 1
148 # define R_386_PC32 2
149 # include <elf_abi.h>
150 # else
151 # include <elf.h>
152 # endif
154 /* Add a section to the file
156 * n = Name
157 * t = Type
158 * f = Flags
159 * s = Size
160 * l = Link
161 * i = Info
162 * a = Align
163 * e = Entry size
165 # define sh_add(n, t, f, s, l, i, a, e) { \
166 bzero(&sechdr, sizeof (Elf32_Ehdr)); \
167 sechdr.sh_name = shste - shst; \
168 shste += sprintf(shste, "%s", n); \
169 shste++; \
170 sechdr.sh_type = t; \
171 sechdr.sh_flags = f; \
172 sechdr.sh_addr = 0; \
173 sechdr.sh_offset = current_offset; \
174 sechdr.sh_size = s; \
175 sechdr.sh_link = l; \
176 sechdr.sh_info = i; \
177 sechdr.sh_addralign = a; \
178 sechdr.sh_entsize = e; \
179 save_struct(fp, &sechdr, sizeof (Elf32_Shdr)); \
180 current_offset += s; \
181 if (s % 4) \
182 current_offset += (4 - s % 4); \
185 /* Sizeof the section header string table */
186 # define SHSTRTABSIZE 0x48
187 /* Previously defined symbols (zero, text, data, bss) */
188 # define PDFS 4
189 /* Number of sections */
190 # define NSECTIONS 8
192 void
193 Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
195 Elf32_Ehdr header;
196 Elf32_Shdr sechdr;
197 Elf32_Rel rellocation;
198 Elf32_Rela rel_addend;
199 Elf32_Sym symlst;
200 Elf32_Off current_offset;
201 FILE *fp;
202 int i;
203 char shst[SHSTRTABSIZE], *shste;
205 fp = fopen(file, "w");
207 bzero(&header, sizeof (Elf32_Ehdr));
208 header.e_ident[0] = ELFMAG0;
209 header.e_ident[1] = ELFMAG1;
210 header.e_ident[2] = ELFMAG2;
211 header.e_ident[3] = ELFMAG3;
212 header.e_ident[4] = ELFCLASS32;
213 # if PARROT_BIGENDIAN
214 header.e_ident[5] = ELFDATA2MSB;
215 # else /* PARROT_BIGENDIAN */
216 header.e_ident[5] = ELFDATA2LSB;
217 # endif /* PARROT_BIGENDIAN */
218 header.e_ident[6] = EV_CURRENT;
219 # ifdef PARROT_EXEC_OS_FREEBSD
220 header.e_ident[7] = ELFOSABI_FREEBSD;
221 # endif
222 # ifdef PARROT_EXEC_OS_NETBSD
223 header.e_ident[7] = ELFOSABI_NETBSD;
224 # endif
225 # if defined(PARROT_EXEC_OS_LINUX) && defined(ELFOSABI_LINUX) && \
226 !defined(PARROT_PPC) && !defined(PARROT_ARM)
227 header.e_ident[7] = ELFOSABI_LINUX;
228 # endif
230 header.e_type = ET_REL;
231 # ifdef PARROT_I386
232 header.e_machine = EM_386;
233 # endif
234 # ifdef PARROT_PPC
235 header.e_machine = EM_PPC;
236 # endif
237 # ifdef PARROT_ARM
238 header.e_ident[7] = ELFOSABI_ARM;
239 header.e_machine = EM_ARM;
240 # endif
241 header.e_version = EV_CURRENT;
242 header.e_entry = 0;
243 header.e_phoff = 0;
244 header.e_shoff = sizeof (Elf32_Ehdr);
245 header.e_flags = 0;
246 header.e_ehsize = sizeof (Elf32_Ehdr);
247 header.e_phentsize = 0;
248 header.e_phnum = 0;
249 header.e_shentsize = sizeof (Elf32_Shdr);
250 header.e_shnum = NSECTIONS;
251 header.e_shstrndx = 1;
253 save_struct(fp, &header, sizeof (Elf32_Ehdr));
255 current_offset = sizeof (Elf32_Ehdr) + NSECTIONS * sizeof (Elf32_Shdr);
257 /* Sections */
258 bzero(&shst, SHSTRTABSIZE);
259 shste = shst + 1;
260 /* NULL */
261 bzero(&sechdr, sizeof (Elf32_Ehdr));
262 save_struct(fp, &sechdr, sizeof (Elf32_Shdr));
263 /* Section Header String Table */
264 sh_add(".shstrtab", SHT_STRTAB, 0, SHSTRTABSIZE, 0, 0, 1, 0);
265 /* Text */
266 sh_add(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, obj->text.size,
267 0, 0, 4, 0);
268 /* Data */
269 sh_add(".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, obj->data.size,
270 0, 0, 4, 0);
271 /* Bss */
272 sh_add(".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, obj->bss.size,
273 0, 0, 4, 0);
275 * Text rellocation records.
276 * Link must be the symtab section header index.
277 * Info is the text section header index.
279 # if defined(PARROT_I386) || defined(PARROT_ARM)
280 sh_add(".rel.text", SHT_REL, 0, obj->text_rellocation_count *
281 sizeof (Elf32_Rel), 6, 2, 4, sizeof (Elf32_Rel));
282 # endif
284 * PPC requires rellocation structures with addends.
286 # ifdef PARROT_PPC
287 sh_add(".rela.text", SHT_RELA, 0, obj->text_rellocation_count *
288 sizeof (Elf32_Rela), 6, 2, 4, sizeof (Elf32_Rela));
289 # endif
291 * Symbol table.
292 * Link is the strtab section header index.
293 * Info is the index of the first symbol in the symbol table.
295 sh_add(".symtab", SHT_SYMTAB, 0, (obj->symbol_count + PDFS) *
296 sizeof (Elf32_Sym), 7, PDFS - 1, 4, sizeof (Elf32_Sym));
297 /* String Table */
298 obj->symbol_list_size += 1; /* Trailing \0 */
299 sh_add(".strtab", SHT_STRTAB, 0, obj->symbol_list_size, 0, 0, 1, 0);
301 /* Section header string table */
302 save_struct(fp, &shst, SHSTRTABSIZE);
303 save_struct(fp, obj->text.code, obj->text.size); /* Text */
304 save_struct(fp, obj->data.code, obj->data.size); /* Data */
305 /* Text rellocations */
306 for (i = 0; i < obj->text_rellocation_count; i++) {
307 # ifdef PARROT_I386
308 bzero(&rellocation, sizeof (Elf32_Rel));
309 rellocation.r_offset = obj->text_rellocation_table[i].offset;
310 switch (obj->text_rellocation_table[i].type) {
311 case RTYPE_FUNC:
312 rellocation.r_info =
313 ELF32_R_INFO(
314 obj->text_rellocation_table[i].symbol_number + PDFS,
315 R_386_PC32);
316 break;
317 case RTYPE_DATA:
318 case RTYPE_COM:
319 rellocation.r_info =
320 ELF32_R_INFO(
321 obj->text_rellocation_table[i].symbol_number + PDFS,
322 R_386_32);
323 break;
324 default:
325 real_exception(interp, NULL, EXEC_ERROR,
326 "Unknown text rellocation type: %d\n",
327 obj->text_rellocation_table[i].type);
328 break;
330 save_struct(fp, &rellocation, sizeof (Elf32_Rel));
331 # endif
332 # ifdef PARROT_PPC
333 bzero(&rel_addend, sizeof (Elf32_Rela));
334 rel_addend.r_offset = obj->text_rellocation_table[i].offset;
335 switch (obj->text_rellocation_table[i].type) {
336 case RTYPE_FUNC:
337 rel_addend.r_info =
338 ELF32_R_INFO(
339 obj->text_rellocation_table[i].symbol_number + PDFS,
340 R_PPC_REL24);
341 break;
342 case RTYPE_DATA:
343 case RTYPE_COM:
344 rel_addend.r_info =
345 ELF32_R_INFO(
346 obj->text_rellocation_table[i].symbol_number + PDFS,
347 R_PPC_ADDR16_HI);
348 rel_addend.r_addend = *((short *)
349 (&obj->text.code[obj->text_rellocation_table[i].offset]))
350 << 16;
351 rel_addend.r_addend += *((short *)
352 (&obj->text.code[
353 obj->text_rellocation_table[i].offset + 4]));
354 break;
355 case RTYPE_DATA1:
356 rel_addend.r_info =
357 ELF32_R_INFO(
358 obj->text_rellocation_table[i].symbol_number + PDFS,
359 R_PPC_ADDR16_LO);
360 rel_addend.r_addend = *((short *)
361 (&obj->text.code[obj->text_rellocation_table[i].offset]));
362 rel_addend.r_addend += *((short *)
363 (&obj->text.code[
364 obj->text_rellocation_table[i].offset - 4])) << 16;
365 break;
366 default:
367 real_exception(interp, NULL, EXEC_ERROR,
368 "Unknown text rellocation type: %d\n",
369 obj->text_rellocation_table[i].type);
370 break;
372 save_struct(fp, &rel_addend, sizeof (Elf32_Rela));
373 # endif
374 # ifdef PARROT_ARM
375 bzero(&rellocation, sizeof (Elf32_Rel));
376 rellocation.r_offset = obj->text_rellocation_table[i].offset;
377 switch (obj->text_rellocation_table[i].type) {
378 case RTYPE_FUNC:
379 rellocation.r_info =
380 ELF32_R_INFO(
381 obj->text_rellocation_table[i].symbol_number + PDFS,
382 R_ARM_ABS32);
383 break;
384 case RTYPE_DATA:
385 rellocation.r_info =
386 ELF32_R_INFO(
387 obj->text_rellocation_table[i].symbol_number + PDFS,
388 R_ARM_ABS32);
389 break;
390 default:
391 real_exception(interp, NULL, EXEC_ERROR,
392 "Unknown text rellocation type: %d\n",
393 obj->text_rellocation_table[i].type);
394 break;
396 save_struct(fp, &rellocation, sizeof (Elf32_Rel));
397 # endif
399 /* Symbol table */
400 /* zero */
401 bzero(&symlst, sizeof (Elf32_Sym));
402 save_struct(fp, &symlst, sizeof (Elf32_Sym));
403 /* Text */
404 bzero(&symlst, sizeof (Elf32_Sym));
405 symlst.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
406 symlst.st_shndx = 2;
407 save_struct(fp, &symlst, sizeof (Elf32_Sym));
408 /* Data */
409 bzero(&symlst, sizeof (Elf32_Sym));
410 symlst.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
411 symlst.st_shndx = 3;
412 save_struct(fp, &symlst, sizeof (Elf32_Sym));
413 /* Bss */
414 bzero(&symlst, sizeof (Elf32_Sym));
415 symlst.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
416 symlst.st_shndx = 4;
417 save_struct(fp, &symlst, sizeof (Elf32_Sym));
419 for (i = 0; i < obj->symbol_count; i++) {
420 bzero(&symlst, sizeof (Elf32_Sym));
421 symlst.st_name = obj->symbol_table[i].offset_list + 1;
422 switch (obj->symbol_table[i].type) {
423 case STYPE_FUNC:
424 symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC);
425 symlst.st_size = obj->text.size;
426 symlst.st_shndx = 2; /* text */
427 break;
428 case STYPE_GDATA:
429 symlst.st_value = obj->symbol_table[i].value;
430 symlst.st_size = obj->data_size[i];
431 symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
432 symlst.st_shndx = 3; /* data */
433 break;
434 case STYPE_COM:
435 symlst.st_value = obj->symbol_table[i].value;
436 /* symlst.st_size = obj->data_size[i]; XXX daniel why? */
437 symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
438 symlst.st_shndx = SHN_COMMON;
439 break;
440 case STYPE_UND:
441 symlst.st_info = ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE);
442 break;
443 default:
444 real_exception(interp, NULL, EXEC_ERROR, "Unknown symbol type: %d\n",
445 obj->symbol_table[i].type);
446 break;
448 save_struct(fp, &symlst, sizeof (Elf32_Sym));
450 /* String table */
451 save_zero(fp);
452 for (i = 0; i < obj->symbol_count; i++) {
453 fprintf(fp, "%s", obj->symbol_table[i].symbol);
454 save_zero(fp);
456 /* PAD */
457 for (i = 0; i < (4 - obj->symbol_list_size % 4); i++)
458 save_zero(fp);
459 fclose(fp);
462 #endif /* EXEC_ELF */
464 #ifdef EXEC_MACH_O
466 void
467 Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
469 FILE *fp;
470 int i;
472 fp = fopen(file, "w");
474 fprintf(fp, "\xFE\xED\xFA\xCE"); /* Header for Darwin */
475 save_int(fp, 0x12);
476 save_int(fp, 0);
477 save_int(fp, 0x1);
478 save_int(fp, 0x3);
479 save_int(fp, 0x128);
480 save_int(fp, 0);
481 save_int(fp, 0x1);
482 save_int(fp, 0xC0);
483 for (i = 0; i < 5; i++)
484 save_int(fp, 0);
485 /* Sizeof text + data */
486 save_int(fp, obj->text.size + obj->data.size);
487 /* Offset of text */
488 save_int(fp, 0x144);
489 save_int(fp, obj->text.size + obj->data.size);
490 save_int(fp, 0x7);
491 save_int(fp, 0x7);
492 save_int(fp, 0x2);
493 save_int(fp, 0);
494 fprintf(fp, "__text");
495 for (i = 0; i < 10; i++)
496 save_zero(fp);
497 fprintf(fp, "__TEXT");
498 for (i = 0; i < 10; i++)
499 save_zero(fp);
500 save_int(fp, 0);
501 /* Sizeof text */
502 save_int(fp, obj->text.size);
503 save_int(fp, 0x144);
504 save_int(fp, 0x2);
505 /* Offset of rellocation table. */
506 save_int(fp, 0x144 + obj->text.size + obj->data.size);
507 save_int(fp, obj->text_rellocation_count);
508 save_int(fp, 0x80000400);
509 save_int(fp, 0);
510 save_int(fp, 0);
511 fprintf(fp, "__data");
512 for (i = 0; i < 10; i++)
513 save_zero(fp);
514 fprintf(fp, "__DATA");
515 for (i = 0; i < 10; i++)
516 save_zero(fp);
517 /* Data VMA */
518 save_int(fp, obj->text.size);
519 /* Data size */
520 save_int(fp, obj->data.size);
521 /* Data file offset */
522 save_int(fp, 0x144 + obj->text.size);
523 save_int(fp, 0x2);
524 for (i = 0; i < 5; i++)
525 save_int(fp, 0);
526 save_int(fp, 0x2);
527 /* save_int(fp, obj->symbol_count * 0xc); */
528 save_int(fp, 0x18);
529 /* Offset of stabs */
530 save_int(fp, 0x144 +
531 obj->text.size + obj->data.size + obj->text_rellocation_count * 0x8);
532 /* Number of stabs (symbol table) */
533 save_int(fp, obj->symbol_count);
534 /* Offset of symbol list */
535 save_int(fp, 0x144 + obj->text.size + obj->data.size +
536 obj->text_rellocation_count * 0x8 + obj->symbol_count * 0xc);
537 /* Sizeof symbol list */
538 save_int(fp, obj->symbol_list_size);
539 save_int(fp, 0xB);
540 save_int(fp, 0x50);
541 for (i = 0; i < 3; i++)
542 save_int(fp, 0);
543 save_int(fp, obj->symbol_count);
544 save_int(fp, obj->symbol_count);
545 for (i = 0; i < 13; i++)
546 save_int(fp, 0);
547 /* Text */
548 for (i = 0; i < obj->text.size; i++)
549 fprintf(fp, "%c", obj->text.code[i]);
550 /* Data */
551 for (i = 0; i < obj->data.size; i++)
552 fprintf(fp, "%c", obj->data.code[i]);
553 /* Text rellocations */
554 for (i = obj->text_rellocation_count - 1; i >= 0; i--) {
555 save_int(fp, obj->text_rellocation_table[i].offset);
556 save_short(fp, obj->text_rellocation_table[i].symbol_number);
557 save_short(fp, obj->text_rellocation_table[i].type);
559 /* Symbol table */
560 for (i = 0; i < obj->symbol_count; i++) {
561 save_int(fp, obj->symbol_table[i].offset_list);
562 save_int(fp, obj->symbol_table[i].type);
563 save_int(fp, obj->symbol_table[i].value);
565 /* Symbol list */
566 for (i = 0; i < obj->symbol_count; i++) {
567 if (obj->symbol_table[i].type != STYPE_GCC)
568 fprintf(fp, "_%s", obj->symbol_table[i].symbol);
569 else
570 fprintf(fp, "%s", obj->symbol_table[i].symbol);
571 save_zero(fp);
573 fclose(fp);
576 #endif /* EXEC_MACH_O */
578 #ifdef EXEC_COFF
580 /* File offsets */
581 # define TEXT_CODE 0x14 + (3 * 0x28)
582 # define DATA_CODE TEXT_CODE + obj->text.size
583 # define TEXT_RELOC DATA_CODE + obj->data.size
584 # define DATA_RELOC TEXT_RELOC + (obj->text_rellocation_count * 0xA)
585 # define SYMTAB DATA_RELOC + (obj->data_rellocation_count * 0xA)
587 void
588 Parrot_exec_save(PARROT_INTERP, Parrot_exec_objfile_t *obj, const char *file)
590 FILE *fp;
591 int i;
593 fp = fopen(file, "wb");
595 save_short(fp, 0x14C); /* i386 */
596 save_short(fp, 3); /* Number of sections */
597 save_int(fp, Parrot_intval_time());
598 save_int(fp, SYMTAB);
599 save_int(fp, obj->symbol_count);
600 save_short(fp, 0);
601 save_short(fp, 0x104); /* 32 bit LE, no line numbers */
603 fwrite(".text\0\0\0", 8, 1, fp);
604 save_int(fp, 0);
605 save_int(fp, 0);
606 save_int(fp, obj->text.size);
607 save_int(fp, TEXT_CODE);
608 save_int(fp, TEXT_RELOC);
609 save_int(fp, 0);
610 save_short(fp, (short)obj->text_rellocation_count);
611 save_short(fp, 0);
612 save_int(fp, 0x20);
614 fwrite(".data\0\0\0", 8, 1, fp);
615 save_int(fp, 0);
616 save_int(fp, 0);
617 save_int(fp, obj->data.size);
618 save_int(fp, DATA_CODE);
619 save_int(fp, DATA_RELOC);
620 save_int(fp, 0);
621 save_short(fp, (short)obj->data_rellocation_count);
622 save_short(fp, 0);
623 save_int(fp, 0x40);
625 fwrite(".bss\0\0\0\0", 8, 1, fp);
626 save_int(fp, 0);
627 save_int(fp, 0);
628 save_int(fp, obj->bss.size);
629 save_int(fp, 0);
630 save_int(fp, 0);
631 save_int(fp, 0);
632 save_short(fp, 0);
633 save_short(fp, 0);
634 save_int(fp, 0x80);
636 /* Text */
637 for (i = 0; i < obj->text.size; i++)
638 fprintf(fp, "%c", obj->text.code[i]);
639 /* Data */
640 for (i = 0; i < obj->data.size; i++)
641 fprintf(fp, "%c", obj->data.code[i]);
642 /* Text rellocations */
643 for (i = 0; i < obj->text_rellocation_count; i++) {
644 save_int(fp, obj->text_rellocation_table[i].offset);
645 save_int(fp, obj->text_rellocation_table[i].symbol_number);
646 switch (obj->text_rellocation_table[i].type) {
647 case RTYPE_FUNC:
648 save_short(fp, 0x14);
649 break;
650 case RTYPE_COM:
651 case RTYPE_DATA:
652 save_short(fp, 0x06);
653 break;
654 default:
655 real_exception(interp, NULL, EXEC_ERROR,
656 "Unknown text rellocation type: %d\n",
657 obj->text_rellocation_table[i].type);
658 break;
661 /* Symbol table */
662 for (i = 0; i < obj->symbol_count; i++) {
663 save_int(fp, 0);
664 save_int(fp, obj->symbol_table[i].offset_list);
665 save_int(fp, obj->symbol_table[i].value);
666 switch (obj->symbol_table[i].type) {
667 case STYPE_FUNC:
668 save_short(fp, 1); /* .text */
669 save_short(fp, 0x20);
670 break;
671 case STYPE_GDATA:
672 save_short(fp, 2); /* .data */
673 save_short(fp, 0);
674 break;
675 case STYPE_COM:
676 save_short(fp, 0);
677 save_short(fp, 0);
678 break;
679 case STYPE_UND:
680 save_short(fp, 0);
681 save_short(fp, 0x20);
682 break;
683 default:
684 real_exception(interp, NULL, EXEC_ERROR, "Unknown symbol type: %d\n",
685 obj->symbol_table[i].type);
686 break;
688 putc(2, fp); /* "extern" class */
689 putc(0, fp);
691 /* Symbol list */
692 save_int(fp, obj->symbol_list_size);
693 for (i = 0; i < obj->symbol_count; i++) {
694 if (obj->symbol_table[i].type != STYPE_GCC)
695 fprintf(fp, "_%s", obj->symbol_table[i].symbol);
696 else
697 fprintf(fp, "%s", obj->symbol_table[i].symbol);
698 save_zero(fp);
700 fclose(fp);
703 #endif /* EXEC_COFF */
707 =item C<static void save_struct(FILE *fp, void *sp, size_t size)>
709 Writes the C<struct> C<sp> to the file.
711 =cut
715 static void
716 save_struct(FILE *fp, void *sp, size_t size)
718 unsigned int i;
720 for (i = 0; i < size; i++)
721 fprintf(fp, "%c", ((char *)sp)[i]);
726 =item C<static void save_zero(FILE *fp)>
728 Writes 0 to the file.
730 =cut
734 static void
735 save_zero(FILE *fp)
737 fprintf(fp, "%c", 0);
740 #if PARROT_BIGENDIAN
744 =item C<static void save_int(FILE *fp, int i)>
746 Writes C<i> to the file.
748 =cut
752 static void
753 save_int(FILE *fp, int i)
755 fprintf(fp, "%c%c%c%c", (char)(i >> 24), (char)(i >> 16),
756 (char)(i >> 8), (char)i);
761 =item C<static void save_short(FILE *fp, short s)>
763 Writes C<s> to the file.
765 =cut
769 static void
770 save_short(FILE *fp, short s)
772 fprintf(fp, "%c%c", (char)(s >> 8), (char)s);
775 #else /* PARROT_BIGENDIAN */
777 static void
778 save_short(FILE *fp, short s)
780 fprintf(fp, "%c%c", (char)s, (char)(s >> 8));
783 static void
784 save_int(FILE *fp, int i)
786 fprintf(fp, "%c%c%c%c", (char)i, (char)(i >> 8),
787 (char)(i >> 16), (char)(i >> 24));
790 #endif /* PARROT_BIGENDIAN */
794 =back
796 =head1 SEE ALSO
798 F<include/parrot/exec.h>, F<src/exec_save.h>, F<src/exec.c>
799 and F<src/exec_start.c>.
801 =head1 HISTORY
803 Initial version by Daniel Grunblatt on 2003.6.9.
805 =cut
811 * Local variables:
812 * c-file-style: "parrot"
813 * End:
814 * vim: expandtab shiftwidth=4: