1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 /* Contains information relating to the format of FASL files.
28    The machine/opsys information is contained in config.h
29    The processor and compiled code version information is
30    contained in the appropriate cmp* file, or compiler.c.  */
31 
32 #ifndef SCM_FASL_H
33 #define SCM_FASL_H 1
34 
35 #include "object.h"
36 #include "cmpint.h"
37 
38 #if (SIZEOF_UNSIGNED_LONG == 4)
39 #  define FASL_FILE_MARKER 0xFAFAFAFAUL
40 #else
41 #  if (SIZEOF_UNSIGNED_LONG == 8)
42 #    define FASL_FILE_MARKER 0xFAFAFAFAFAFAFAFAUL
43 #  endif
44 #endif
45 
46 /* The FASL file has a header which begins as follows: */
47 
48 #define FASL_HEADER_LENGTH	50	/* Scheme objects in header */
49 
50 #define FASL_OFFSET_MARKER	0	/* Marker to indicate FASL format */
51 #define FASL_OFFSET_HEAP_SIZE	1	/* # of words in heap */
52 #define FASL_OFFSET_HEAP_BASE	2	/* Address of heap when dumped */
53 #define FASL_OFFSET_DUMPED_OBJ	3	/* Where dumped object was */
54 #define FASL_OFFSET_CONST_SIZE	4	/* # of words in constant area */
55 #define FASL_OFFSET_CONST_BASE	5	/* Address of const. area at dump */
56 #define FASL_OFFSET_VERSION	6	/* FASL format version info. */
57 #define FASL_OFFSET_STACK_START	7	/* value of stack_start when dumped */
58 #define FASL_OFFSET_PRIM_LENGTH 8	/* # of entries in primitive table */
59 #define FASL_OFFSET_PRIM_SIZE	9	/* # of words in primitive table */
60 #define FASL_OFFSET_CI_VERSION	10	/* Version of comp. code interface */
61 #define FASL_OFFSET_UT_BASE	11	/* Address of the utilities vector */
62 
63 #if 0
64 #define FASL_OFFSET_CHECK_SUM	12	/* Header and data checksum. */
65 #endif
66 
67 #define FASL_OFFSET_C_LENGTH	13	/* # of entries in the C code table */
68 #define FASL_OFFSET_C_SIZE	14	/* # of words in the C code table */
69 #define FASL_OFFSET_MEM_BASE	15	/* Saved value of memory_base */
70 #define FASL_OFFSET_STACK_SIZE	16	/* # of words in stack area */
71 #define FASL_OFFSET_HEAP_RSVD	17	/* value of heap_reserved */
72 #define FASL_OFFSET_EPHEMERONS	18	/* # of ephemerons in fasl */
73 
74 /* Version information encoding */
75 
76 #define FASL_ARCH_LENGTH (OBJECT_LENGTH / 2)
77 #define FASL_ARCH(P) ((P) & ((1UL << FASL_ARCH_LENGTH) - 1))
78 
79 #define FASL_VERSION_LENGTH (FASL_ARCH_LENGTH - TYPE_CODE_LENGTH)
80 #define FASL_VERSION(P)						\
81   (((P) >> FASL_ARCH_LENGTH) & ((1UL << FASL_VERSION_LENGTH) - 1))
82 
83 /* The '1' here is for upwards compatibility.  */
84 #define MAKE_FASL_VERSION(s, a)					\
85   (MAKE_OBJECT (1, ((((unsigned long) (s)) << FASL_ARCH_LENGTH) | (a))))
86 
87 #define CI_VERSION(P) (((P) >> HALF_DATUM_LENGTH) & HALF_DATUM_MASK)
88 #define CI_PROCESSOR(P) ((cc_arch_t) ((P) & HALF_DATUM_MASK))
89 #define CI_BAND_P(P) ((OBJECT_TYPE (P)) == TC_CONSTANT)
90 
91 #define MAKE_CI_VERSION(b, v, a)					\
92   (MAKE_OBJECT (((b) ? TC_CONSTANT : TC_NULL),				\
93 		((((unsigned long) (v)) << HALF_DATUM_LENGTH)		\
94 		 | ((unsigned long) (a)))))
95 
96 typedef enum
97 {
98   FASL_VERSION_NONE,
99   FASL_VERSION_LONG_HEADER = 3,
100   FASL_VERSION_DENSE_TYPES,
101   FASL_VERSION_PADDED_STRINGS,
102   FASL_VERSION_REFERENCE_TRAP,
103   FASL_VERSION_MERGED_PRIMITIVES,
104   FASL_VERSION_INTERFACE_VERSION,
105   FASL_VERSION_NEW_BIGNUMS,
106   FASL_VERSION_C_CODE,
107   FASL_VERSION_STACK_END,
108   FASL_VERSION_EPHEMERONS,
109 } fasl_version_t;
110 
111 #define OLDEST_INPUT_FASL_VERSION FASL_VERSION_C_CODE
112 #define NEWEST_INPUT_FASL_VERSION FASL_VERSION_EPHEMERONS
113 
114 /* Nothing uses this at the moment -- the fasdumper selects C_CODE for
115    non-bands, STACK_END if there are no ephemerons, or EPHEMERONS if
116    there is at least one ephemeron in the fasl.  */
117 #define OUTPUT_FASL_VERSION FASL_VERSION_EPHEMERONS
118 
119 typedef struct
120 {
121   fasl_version_t version;
122   fasl_arch_t arch;
123   unsigned int cc_version;
124   cc_arch_t cc_arch;
125   bool band_p;
126   SCHEME_OBJECT * memory_base;
127   SCHEME_OBJECT * root_pointer;
128   SCHEME_OBJECT * heap_start;
129   SCHEME_OBJECT * heap_end;
130   unsigned long heap_reserved;
131   SCHEME_OBJECT * constant_start;
132   SCHEME_OBJECT * constant_end;
133   SCHEME_OBJECT * stack_start;
134   SCHEME_OBJECT * stack_end;
135   unsigned long n_primitives;
136   unsigned long primitive_table_size;
137   unsigned long n_c_code_blocks;
138   unsigned long c_code_table_size;
139   SCHEME_OBJECT utilities_vector;
140   SCHEME_OBJECT * utilities_start;
141   SCHEME_OBJECT * utilities_end;
142   unsigned long ephemeron_count;
143 } fasl_header_t;
144 
145 #define FASLHDR_VERSION(h) ((h)->version)
146 #define FASLHDR_ARCH(h) ((h)->arch)
147 #define FASLHDR_CC_VERSION(h) ((h)->cc_version)
148 #define FASLHDR_CC_ARCH(h) ((h)->cc_arch)
149 #define FASLHDR_BAND_P(h) ((h)->band_p)
150 #define FASLHDR_MEMORY_BASE(h) ((h)->memory_base)
151 #define FASLHDR_ROOT_POINTER(h) ((h)->root_pointer)
152 #define FASLHDR_HEAP_START(h) ((h)->heap_start)
153 #define FASLHDR_HEAP_END(h) ((h)->heap_end)
154 #define FASLHDR_HEAP_RESERVED(h) ((h)->heap_reserved)
155 #define FASLHDR_CONSTANT_START(h) ((h)->constant_start)
156 #define FASLHDR_CONSTANT_END(h) ((h)->constant_end)
157 #define FASLHDR_STACK_START(h) ((h)->stack_start)
158 #define FASLHDR_STACK_END(h) ((h)->stack_end)
159 #define FASLHDR_N_PRIMITIVES(h) ((h)->n_primitives)
160 #define FASLHDR_PRIMITIVE_TABLE_SIZE(h) ((h)->primitive_table_size)
161 #define FASLHDR_N_C_CODE_BLOCKS(h) ((h)->n_c_code_blocks)
162 #define FASLHDR_C_CODE_TABLE_SIZE(h) ((h)->c_code_table_size)
163 #define FASLHDR_UTILITIES_VECTOR(h) ((h)->utilities_vector)
164 #define FASLHDR_UTILITIES_START(h) ((h)->utilities_start)
165 #define __FASLHDR_UTILITIES_END(h) ((h)->utilities_end)
166 #define FASLHDR_EPHEMERON_COUNT(h) ((h)->ephemeron_count)
167 
168 #define FASLHDR_UTILITIES_END(h) (faslhdr_utilities_end (h))
169 
170 #define FASLHDR_HEAP_SIZE(h)						\
171   ((unsigned long)							\
172    ((FASLHDR_HEAP_END (h)) - (FASLHDR_HEAP_START (h))))
173 
174 #define FASLHDR_CONSTANT_SIZE(h)					\
175   ((unsigned long)							\
176    ((FASLHDR_CONSTANT_END (h)) - (FASLHDR_CONSTANT_START (h))))
177 
178 #define FASLHDR_STACK_SIZE(h)						\
179   ((unsigned long)							\
180    ((FASLHDR_STACK_END (h)) - (FASLHDR_STACK_START (h))))
181 
182 typedef enum
183 {
184   FASL_FILE_FINE,
185   FASL_FILE_TOO_SHORT,
186   FASL_FILE_NOT_FASL,
187   FASL_FILE_BAD_MACHINE,
188   FASL_FILE_BAD_VERSION,
189   FASL_FILE_BAD_SUBVERSION,	/* unused */
190   FASL_FILE_BAD_PROCESSOR,
191   FASL_FILE_BAD_INTERFACE
192 } fasl_read_status_t;
193 
194 typedef FILE * fasl_file_handle_t;
195 
196 extern bool open_fasl_output_file (const char *, fasl_file_handle_t *);
197 extern bool close_fasl_output_file (fasl_file_handle_t);
198 extern bool write_fasl_header (fasl_header_t *, fasl_file_handle_t);
199 extern bool write_to_fasl_file (const void *, size_t, fasl_file_handle_t);
200 extern bool open_fasl_input_file (const char *, fasl_file_handle_t *);
201 extern bool close_fasl_input_file (fasl_file_handle_t);
202 extern bool read_fasl_header (fasl_header_t *, fasl_file_handle_t);
203 extern bool read_from_fasl_file (void *, size_t, fasl_file_handle_t);
204 extern SCHEME_OBJECT * fasl_object_address (SCHEME_OBJECT, fasl_header_t *);
205 extern insn_t * fasl_cc_address (SCHEME_OBJECT, fasl_header_t *);
206 extern SCHEME_OBJECT fasl_raw_address_to_object
207   (unsigned int, SCHEME_OBJECT *, fasl_header_t *);
208 extern SCHEME_OBJECT fasl_raw_address_to_cc_entry (insn_t *, fasl_header_t *);
209 extern SCHEME_OBJECT * faslhdr_utilities_end (fasl_header_t *);
210 extern fasl_read_status_t check_fasl_version (fasl_header_t *);
211 extern fasl_read_status_t check_fasl_cc_version
212   (fasl_header_t *, unsigned long, unsigned long);
213 
214 #endif /* not SCM_FASL_H */
215