2 Copyright (C) 2001-2008, Parrot Foundation.
7 src/exec_save.c - Save object file in native format
11 Save the C<Parrot_exec_objfile_t> to the native format.
21 /* HEADERIZER HFILE: none */
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
);
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>.
50 Parrot_exec_save(PARROT_INTERP
, Parrot_exec_objfile_t
*obj
, const char *file
)
52 FILE * const fp
= fopen(file
, "w");
55 struct relocation_info rellocation
;
59 header
.a_midmag
= 0x07018600;
60 header
.a_text
= obj
->text
.size
;
61 header
.a_data
= obj
->data
.size
;
62 header
.a_bss
= obj
->bss
.size
;
63 header
.a_syms
= obj
->symbol_count
* sizeof (struct nlist
);
65 header
.a_trsize
= obj
->text_rellocation_count
66 * sizeof (struct relocation_info
);
67 header
.a_drsize
= obj
->data_rellocation_count
68 * sizeof (struct relocation_info
);
69 save_struct(fp
, &header
, sizeof (struct exec
));
71 for (i
= 0; i
< obj
->text
.size
; i
++)
72 fprintf(fp
, "%c", obj
->text
.code
[i
]);
74 for (i
= 0; i
< obj
->data
.size
; i
++)
75 fprintf(fp
, "%c", obj
->data
.code
[i
]);
76 /* Text rellocations */
77 for (i
= obj
->text_rellocation_count
- 1; i
>= 0; i
--) {
78 memset(&rellocation
, 0, sizeof (struct relocation_info
));
79 rellocation
.r_address
= obj
->text_rellocation_table
[i
].offset
;
80 rellocation
.r_symbolnum
= obj
->text_rellocation_table
[i
].symbol_number
;
81 switch (obj
->text_rellocation_table
[i
].type
) {
83 rellocation
.r_pcrel
= 1;
84 rellocation
.r_length
= 2;
85 rellocation
.r_extern
= 1;
89 rellocation
.r_length
= 2;
90 rellocation
.r_extern
= 1;
93 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
94 "Unknown text rellocation type: %d\n",
95 obj
->text_rellocation_table
[i
].type
);
98 save_struct(fp
, &rellocation
, sizeof (struct relocation_info
));
101 for (i
= 0; i
< obj
->symbol_count
; i
++) {
102 memset(&symlst
, 0, sizeof (struct nlist
));
103 symlst
.n_un
.n_strx
= obj
->symbol_table
[i
].offset_list
;
104 switch (obj
->symbol_table
[i
].type
) {
106 symlst
.n_type
= N_EXT
| N_TEXT
;
107 symlst
.n_other
= AUX_FUNC
;
110 symlst
.n_type
= N_EXT
| N_DATA
;
111 symlst
.n_other
= AUX_OBJECT
;
112 symlst
.n_value
= obj
->symbol_table
[i
].value
;
115 symlst
.n_type
= N_EXT
;
116 symlst
.n_value
= obj
->symbol_table
[i
].value
;
119 symlst
.n_type
= N_EXT
;
122 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
123 "Unknown symbol type: %d\n", obj
->symbol_table
[i
].type
);
126 save_struct(fp
, &symlst
, sizeof (struct nlist
));
128 /* String table size */
129 save_int(fp
, obj
->symbol_list_size
);
131 for (i
= 0; i
< obj
->symbol_count
; i
++) {
132 if (obj
->symbol_table
[i
].type
!= STYPE_GCC
)
133 fprintf(fp
, "_%s", obj
->symbol_table
[i
].symbol
);
135 fprintf(fp
, "%s", obj
->symbol_table
[i
].symbol
);
141 #endif /* EXEC_A_OUT */
145 # ifdef PARROT_EXEC_OS_OPENBSD
147 # define R_386_PC32 2
148 # include <elf_abi.h>
153 # if defined(PARROT_PPC)
154 # if !defined(R_PPC_ADDR16_HI) && !defined(R_PPC_ADDR16_LO) && \
155 defined(R_PPC_16_HI) && defined(R_PPC_16_LO)
156 # define R_PPC_ADDR16_HI R_PPC_16_HI
157 # define R_PPC_ADDR16_LO R_PPC_16_LO
160 * NetBSD/powerpc 3.x and OpenBSD/powerpc doesn't define these constants,
161 * but instead has them as enums, so add some workarounds for those.
163 # if !defined(R_PPC_ADDR16_HI) && !defined(R_PPC_ADDR16_LO) && \
164 (defined(__NetBSD__) || defined(__OpenBSD__))
165 # define R_PPC_ADDR16_HI RELOC_16_HI
166 # define R_PPC_ADDR16_LO RELOC_16_LO
168 # if !defined(R_PPC_REL24) && (defined(__NetBSD__) || defined(__OpenBSD__))
169 # define R_PPC_REL24 RELOC_REL24
171 # endif /* PARROT_PPC */
173 /* Add a section to the file
184 # define sh_add(n, t, f, s, l, i, a, e) { \
185 memset(&sechdr, 0, sizeof (Elf32_Shdr)); \
186 sechdr.sh_name = shste - shst; \
187 shste += sprintf(shste, "%s", (n)); \
189 sechdr.sh_type = (t); \
190 sechdr.sh_flags = (f); \
191 sechdr.sh_addr = 0; \
192 sechdr.sh_offset = current_offset; \
193 sechdr.sh_size = (s); \
194 sechdr.sh_link = (l); \
195 sechdr.sh_info = (i); \
196 sechdr.sh_addralign = (a); \
197 sechdr.sh_entsize = (e); \
198 save_struct(fp, &sechdr, sizeof (Elf32_Shdr)); \
199 current_offset += (s); \
201 current_offset += (4 - (s) % 4); \
204 /* Sizeof the section header string table */
205 # define SHSTRTABSIZE 0x48
206 /* Previously defined symbols (zero, text, data, bss) */
208 /* Number of sections */
212 Parrot_exec_save(PARROT_INTERP
, Parrot_exec_objfile_t
*obj
, const char *file
)
214 FILE *fp
= fopen(file
, "w");
216 char shst
[SHSTRTABSIZE
];
220 Elf32_Rel rellocation
;
221 Elf32_Rela rel_addend
;
223 Elf32_Off current_offset
;
226 memset(&header
, 0, sizeof (Elf32_Ehdr
));
227 header
.e_ident
[0] = ELFMAG0
;
228 header
.e_ident
[1] = ELFMAG1
;
229 header
.e_ident
[2] = ELFMAG2
;
230 header
.e_ident
[3] = ELFMAG3
;
231 header
.e_ident
[4] = ELFCLASS32
;
232 # if PARROT_BIGENDIAN
233 header
.e_ident
[5] = ELFDATA2MSB
;
234 # else /* PARROT_BIGENDIAN */
235 header
.e_ident
[5] = ELFDATA2LSB
;
236 # endif /* PARROT_BIGENDIAN */
237 header
.e_ident
[6] = EV_CURRENT
;
238 # ifdef PARROT_EXEC_OS_FREEBSD
239 header
.e_ident
[7] = ELFOSABI_FREEBSD
;
241 # ifdef PARROT_EXEC_OS_NETBSD
242 header
.e_ident
[7] = ELFOSABI_NETBSD
;
244 # if defined(PARROT_EXEC_OS_LINUX) && defined(ELFOSABI_LINUX) && \
245 !defined(PARROT_PPC) && !defined(PARROT_ARM)
246 header
.e_ident
[7] = ELFOSABI_LINUX
;
249 header
.e_type
= ET_REL
;
251 header
.e_machine
= EM_386
;
254 header
.e_machine
= EM_PPC
;
257 header
.e_ident
[7] = ELFOSABI_ARM
;
258 header
.e_machine
= EM_ARM
;
260 header
.e_version
= EV_CURRENT
;
263 header
.e_shoff
= sizeof (Elf32_Ehdr
);
265 header
.e_ehsize
= sizeof (Elf32_Ehdr
);
266 header
.e_phentsize
= 0;
268 header
.e_shentsize
= sizeof (Elf32_Shdr
);
269 header
.e_shnum
= NSECTIONS
;
270 header
.e_shstrndx
= 1;
272 save_struct(fp
, &header
, sizeof (Elf32_Ehdr
));
274 current_offset
= sizeof (Elf32_Ehdr
) + NSECTIONS
* sizeof (Elf32_Shdr
);
277 memset(&shst
, 0, SHSTRTABSIZE
);
281 memset(&sechdr
, 0, sizeof (Elf32_Shdr
));
282 save_struct(fp
, &sechdr
, sizeof (Elf32_Shdr
));
284 /* Section Header String Table */
285 sh_add(".shstrtab", SHT_STRTAB
, 0, SHSTRTABSIZE
, 0, 0, 1, 0);
288 sh_add(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
, obj
->text
.size
,
292 sh_add(".data", SHT_PROGBITS
, SHF_WRITE
| SHF_ALLOC
, obj
->data
.size
,
296 sh_add(".bss", SHT_NOBITS
, SHF_WRITE
| SHF_ALLOC
, obj
->bss
.size
,
299 * Text rellocation records.
300 * Link must be the symtab section header index.
301 * Info is the text section header index.
303 # if defined(PARROT_I386) || defined(PARROT_ARM)
304 sh_add(".rel.text", SHT_REL
, 0, obj
->text_rellocation_count
*
305 sizeof (Elf32_Rel
), 6, 2, 4, sizeof (Elf32_Rel
));
308 * PPC requires rellocation structures with addends.
311 sh_add(".rela.text", SHT_RELA
, 0, obj
->text_rellocation_count
*
312 sizeof (Elf32_Rela
), 6, 2, 4, sizeof (Elf32_Rela
));
316 * Link is the strtab section header index.
317 * Info is the index of the first symbol in the symbol table.
319 sh_add(".symtab", SHT_SYMTAB
, 0, (obj
->symbol_count
+ PDFS
) *
320 sizeof (Elf32_Sym
), 7, PDFS
- 1, 4, sizeof (Elf32_Sym
));
322 obj
->symbol_list_size
+= 1; /* Trailing \0 */
323 sh_add(".strtab", SHT_STRTAB
, 0, obj
->symbol_list_size
, 0, 0, 1, 0);
325 /* Section header string table */
326 save_struct(fp
, &shst
, SHSTRTABSIZE
);
327 save_struct(fp
, obj
->text
.code
, obj
->text
.size
); /* Text */
328 save_struct(fp
, obj
->data
.code
, obj
->data
.size
); /* Data */
329 /* Text rellocations */
330 for (i
= 0; i
< obj
->text_rellocation_count
; i
++) {
332 memset(&rellocation
, 0, sizeof (Elf32_Rel
));
334 rellocation
.r_offset
= obj
->text_rellocation_table
[i
].offset
;
335 switch (obj
->text_rellocation_table
[i
].type
) {
339 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
346 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
350 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
351 "Unknown text rellocation type: %d\n",
352 obj
->text_rellocation_table
[i
].type
);
355 save_struct(fp
, &rellocation
, sizeof (Elf32_Rel
));
358 memset(&rel_addend
, 0, sizeof (Elf32_Rela
));
359 rel_addend
.r_offset
= obj
->text_rellocation_table
[i
].offset
;
360 switch (obj
->text_rellocation_table
[i
].type
) {
364 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
371 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
373 rel_addend
.r_addend
= *((short *)
374 (&obj
->text
.code
[obj
->text_rellocation_table
[i
].offset
]))
376 rel_addend
.r_addend
+= *((short *)
378 obj
->text_rellocation_table
[i
].offset
+ 4]));
383 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
385 rel_addend
.r_addend
= *((short *)
386 (&obj
->text
.code
[obj
->text_rellocation_table
[i
].offset
]));
387 rel_addend
.r_addend
+= *((short *)
389 obj
->text_rellocation_table
[i
].offset
- 4])) << 16;
392 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
393 "Unknown text rellocation type: %d\n",
394 obj
->text_rellocation_table
[i
].type
);
397 save_struct(fp
, &rel_addend
, sizeof (Elf32_Rela
));
400 memset(&rellocation
, 0, sizeof (Elf32_Rel
));
401 rellocation
.r_offset
= obj
->text_rellocation_table
[i
].offset
;
402 switch (obj
->text_rellocation_table
[i
].type
) {
406 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
412 obj
->text_rellocation_table
[i
].symbol_number
+ PDFS
,
416 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
417 "Unknown text rellocation type: %d\n",
418 obj
->text_rellocation_table
[i
].type
);
421 save_struct(fp
, &rellocation
, sizeof (Elf32_Rel
));
426 memset(&symlst
, 0, sizeof (Elf32_Sym
));
427 save_struct(fp
, &symlst
, sizeof (Elf32_Sym
));
430 memset(&symlst
, 0, sizeof (Elf32_Sym
));
431 symlst
.st_info
= ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
);
433 save_struct(fp
, &symlst
, sizeof (Elf32_Sym
));
436 memset(&symlst
, 0, sizeof (Elf32_Sym
));
437 symlst
.st_info
= ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
);
439 save_struct(fp
, &symlst
, sizeof (Elf32_Sym
));
442 memset(&symlst
, 0, sizeof (Elf32_Sym
));
443 symlst
.st_info
= ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
);
445 save_struct(fp
, &symlst
, sizeof (Elf32_Sym
));
447 for (i
= 0; i
< obj
->symbol_count
; i
++) {
448 memset(&symlst
, 0, sizeof (Elf32_Sym
));
449 symlst
.st_name
= obj
->symbol_table
[i
].offset_list
+ 1;
450 switch (obj
->symbol_table
[i
].type
) {
452 symlst
.st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_FUNC
);
453 symlst
.st_size
= obj
->text
.size
;
454 symlst
.st_shndx
= 2; /* text */
457 symlst
.st_value
= obj
->symbol_table
[i
].value
;
458 symlst
.st_size
= obj
->data_size
[i
];
459 symlst
.st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
);
460 symlst
.st_shndx
= 3; /* data */
463 symlst
.st_value
= obj
->symbol_table
[i
].value
;
464 /* symlst.st_size = obj->data_size[i]; XXX daniel why? */
465 symlst
.st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
);
466 symlst
.st_shndx
= SHN_COMMON
;
469 symlst
.st_info
= ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
);
472 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
473 "Unknown symbol type: %d\n", obj
->symbol_table
[i
].type
);
476 save_struct(fp
, &symlst
, sizeof (Elf32_Sym
));
480 for (i
= 0; i
< obj
->symbol_count
; i
++) {
481 fprintf(fp
, "%s", obj
->symbol_table
[i
].symbol
);
485 for (i
= 0; i
< (4 - obj
->symbol_list_size
% 4); i
++)
490 #endif /* EXEC_ELF */
495 Parrot_exec_save(PARROT_INTERP
, Parrot_exec_objfile_t
*obj
, const char *file
)
497 FILE *fp
= fopen(file
, "w");
500 fprintf(fp
, "\xFE\xED\xFA\xCE"); /* Header for Darwin */
509 for (i
= 0; i
< 5; i
++)
511 /* Sizeof text + data */
512 save_int(fp
, obj
->text
.size
+ obj
->data
.size
);
515 save_int(fp
, obj
->text
.size
+ obj
->data
.size
);
520 fprintf(fp
, "__text");
521 for (i
= 0; i
< 10; i
++)
523 fprintf(fp
, "__TEXT");
524 for (i
= 0; i
< 10; i
++)
528 save_int(fp
, obj
->text
.size
);
531 /* Offset of rellocation table. */
532 save_int(fp
, 0x144 + obj
->text
.size
+ obj
->data
.size
);
533 save_int(fp
, obj
->text_rellocation_count
);
534 save_int(fp
, 0x80000400);
537 fprintf(fp
, "__data");
538 for (i
= 0; i
< 10; i
++)
540 fprintf(fp
, "__DATA");
541 for (i
= 0; i
< 10; i
++)
544 save_int(fp
, obj
->text
.size
);
546 save_int(fp
, obj
->data
.size
);
547 /* Data file offset */
548 save_int(fp
, 0x144 + obj
->text
.size
);
550 for (i
= 0; i
< 5; i
++)
553 /* save_int(fp, obj->symbol_count * 0xc); */
555 /* Offset of stabs */
557 obj
->text
.size
+ obj
->data
.size
+ obj
->text_rellocation_count
* 0x8);
558 /* Number of stabs (symbol table) */
559 save_int(fp
, obj
->symbol_count
);
560 /* Offset of symbol list */
561 save_int(fp
, 0x144 + obj
->text
.size
+ obj
->data
.size
+
562 obj
->text_rellocation_count
* 0x8 + obj
->symbol_count
* 0xc);
563 /* Sizeof symbol list */
564 save_int(fp
, obj
->symbol_list_size
);
567 for (i
= 0; i
< 3; i
++)
569 save_int(fp
, obj
->symbol_count
);
570 save_int(fp
, obj
->symbol_count
);
571 for (i
= 0; i
< 13; i
++)
575 for (i
= 0; i
< obj
->text
.size
; i
++)
576 fprintf(fp
, "%c", obj
->text
.code
[i
]);
578 for (i
= 0; i
< obj
->data
.size
; i
++)
579 fprintf(fp
, "%c", obj
->data
.code
[i
]);
580 /* Text rellocations */
581 /* XXX This is an infinite loop. When i = 0, i-- goes to very large. */
582 for (i
= obj
->text_rellocation_count
- 1; i
>= 0; i
--) {
583 save_int(fp
, obj
->text_rellocation_table
[i
].offset
);
584 save_short(fp
, obj
->text_rellocation_table
[i
].symbol_number
);
585 save_short(fp
, obj
->text_rellocation_table
[i
].type
);
588 for (i
= 0; i
< obj
->symbol_count
; i
++) {
589 save_int(fp
, obj
->symbol_table
[i
].offset_list
);
590 save_int(fp
, obj
->symbol_table
[i
].type
);
591 save_int(fp
, obj
->symbol_table
[i
].value
);
594 for (i
= 0; i
< obj
->symbol_count
; i
++) {
595 if (obj
->symbol_table
[i
].type
!= STYPE_GCC
)
596 fprintf(fp
, "_%s", obj
->symbol_table
[i
].symbol
);
598 fprintf(fp
, "%s", obj
->symbol_table
[i
].symbol
);
604 #endif /* EXEC_MACH_O */
609 # define TEXT_CODE 0x14 + (3 * 0x28)
610 # define DATA_CODE TEXT_CODE + obj->text.size
611 # define TEXT_RELOC DATA_CODE + obj->data.size
612 # define DATA_RELOC TEXT_RELOC + (obj->text_rellocation_count * 0xA)
613 # define SYMTAB DATA_RELOC + (obj->data_rellocation_count * 0xA)
616 Parrot_exec_save(PARROT_INTERP
, Parrot_exec_objfile_t
*obj
, const char *file
)
622 fp
= fopen(file
, "wb");
624 save_short(fp
, 0x14C); /* i386 */
625 save_short(fp
, 3); /* Number of sections */
626 save_int(fp
, Parrot_intval_time());
627 save_int(fp
, SYMTAB
);
628 save_int(fp
, obj
->symbol_count
);
630 save_short(fp
, 0x104); /* 32 bit LE, no line numbers */
632 fwrite(".text\0\0\0", 8, 1, fp
);
635 save_int(fp
, obj
->text
.size
);
636 save_int(fp
, TEXT_CODE
);
637 save_int(fp
, TEXT_RELOC
);
639 save_short(fp
, (short)obj
->text_rellocation_count
);
643 fwrite(".data\0\0\0", 8, 1, fp
);
646 save_int(fp
, obj
->data
.size
);
647 save_int(fp
, DATA_CODE
);
648 save_int(fp
, DATA_RELOC
);
650 save_short(fp
, (short)obj
->data_rellocation_count
);
654 fwrite(".bss\0\0\0\0", 8, 1, fp
);
657 save_int(fp
, obj
->bss
.size
);
666 for (j
= 0; j
< obj
->text
.size
; j
++)
667 fprintf(fp
, "%c", obj
->text
.code
[j
]);
669 for (j
= 0; j
< obj
->data
.size
; j
++)
670 fprintf(fp
, "%c", obj
->data
.code
[j
]);
671 /* Text rellocations */
672 for (i
= 0; i
< obj
->text_rellocation_count
; i
++) {
673 save_int(fp
, obj
->text_rellocation_table
[i
].offset
);
674 save_int(fp
, obj
->text_rellocation_table
[i
].symbol_number
);
675 switch (obj
->text_rellocation_table
[i
].type
) {
677 save_short(fp
, 0x14);
681 save_short(fp
, 0x06);
684 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
685 "Unknown text rellocation type: %d\n",
686 obj
->text_rellocation_table
[i
].type
);
691 for (i
= 0; i
< obj
->symbol_count
; i
++) {
693 save_int(fp
, obj
->symbol_table
[i
].offset_list
);
694 save_int(fp
, obj
->symbol_table
[i
].value
);
695 switch (obj
->symbol_table
[i
].type
) {
697 save_short(fp
, 1); /* .text */
698 save_short(fp
, 0x20);
701 save_short(fp
, 2); /* .data */
710 save_short(fp
, 0x20);
713 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_EXEC_ERROR
,
714 "Unknown symbol type: %d\n", obj
->symbol_table
[i
].type
);
717 putc(2, fp
); /* "extern" class */
721 save_int(fp
, obj
->symbol_list_size
);
722 for (i
= 0; i
< obj
->symbol_count
; i
++) {
723 if (obj
->symbol_table
[i
].type
!= STYPE_GCC
)
724 fprintf(fp
, "_%s", obj
->symbol_table
[i
].symbol
);
726 fprintf(fp
, "%s", obj
->symbol_table
[i
].symbol
);
732 #endif /* EXEC_COFF */
736 =item C<static void save_struct(FILE *fp, void *sp, size_t size)>
738 Writes the C<struct> C<sp> to the file.
745 save_struct(FILE *fp
, void *sp
, size_t size
)
749 for (i
= 0; i
< size
; i
++)
750 fprintf(fp
, "%c", ((char *)sp
)[i
]);
755 =item C<static void save_zero(FILE *fp)>
757 Writes 0 to the file.
766 fprintf(fp
, "%c", 0);
773 =item C<static void save_int(FILE *fp, int i)>
775 Writes C<i> to the file.
782 save_int(FILE *fp
, int i
)
784 fprintf(fp
, "%c%c%c%c", (char)(i
>> 24), (char)(i
>> 16),
785 (char)(i
>> 8), (char)i
);
790 =item C<static void save_short(FILE *fp, short s)>
792 Writes C<s> to the file.
799 save_short(FILE *fp
, short s
)
801 fprintf(fp
, "%c%c", (char)(s
>> 8), (char)s
);
804 #else /* PARROT_BIGENDIAN */
807 save_short(FILE *fp
, short s
)
809 fprintf(fp
, "%c%c", (char)s
, (char)(s
>> 8));
813 save_int(FILE *fp
, int i
)
815 fprintf(fp
, "%c%c%c%c", (char)i
, (char)(i
>> 8),
816 (char)(i
>> 16), (char)(i
>> 24));
819 #endif /* PARROT_BIGENDIAN */
827 F<include/parrot/exec.h>, F<src/exec_save.h>, F<src/exec.c>
828 and F<src/exec_start.c>.
832 Initial version by Daniel Grunblatt on 2003.6.9.
841 * c-file-style: "parrot"
843 * vim: expandtab shiftwidth=4: