1 |
|
/* #define GMP */ |
2 |
|
#define BSD386 |
3 |
|
#include "bsd.h" |
4 |
|
|
5 |
|
|
6 |
|
#ifdef __ELF__ |
7 |
|
/* #if ! defined(IN_UNIXFASL) */ |
8 |
|
#undef HAVE_AOUT |
9 |
|
#define HAVE_AOUT <elf.h> |
10 |
|
#define HAVE_ELF |
11 |
|
|
12 |
|
/* Seeking to the end of ELF data is a little messy... */ |
13 |
|
#define SEEK_TO_END_OFILE(fp)\ |
14 |
|
do { \ |
15 |
|
long offset = 0, endofelf; int j; \ |
16 |
|
Elf32_Ehdr eheader; Elf32_Shdr shdr; \ |
17 |
|
fseek(fp, 0, SEEK_SET); \ |
18 |
|
fread(&eheader, sizeof(eheader), 1, fp); \ |
19 |
|
/* in case the headers themselves come AFTER the actual sections */ \ |
20 |
|
endofelf=offset = eheader.e_shoff+ eheader.e_shentsize *eheader.e_shnum;\ |
21 |
|
fseek(fp, eheader.e_shoff, SEEK_SET); \ |
22 |
|
if ( eheader.e_shentsize != sizeof(Elf32_Shdr) ) \ |
23 |
|
{ FEerror("Bad ELF section header size",0); } \ |
24 |
|
for ( j = 0; j < eheader.e_shnum; j++ ) \ |
25 |
|
{ fread(&shdr,eheader.e_shentsize,1,fp); \ |
26 |
|
if ( (shdr.sh_offset > offset) && (shdr.sh_type != SHT_NOBITS) ) \ |
27 |
|
{ offset = shdr.sh_offset; endofelf = offset+shdr.sh_size; } \ |
28 |
|
} \ |
29 |
|
if ( fseek(fp, endofelf, SEEK_SET) ) \ |
30 |
|
FEerror("Bad ELF file",0); \ |
31 |
|
} while(0) |
32 |
|
|
33 |
|
|
34 |
|
#ifdef IN_GBC |
35 |
|
/* Based upon sun4.h */ |
36 |
|
#define INSTALL_MPROTECT_HANDLER \ |
37 |
|
do {static struct sigaction action; \ |
38 |
|
action.sa_handler = memprotect_handler; \ |
39 |
|
action.sa_flags = SA_RESTART; \ |
40 |
|
action.sa_restorer = 0; \ |
41 |
|
sigemptyset(&action.sa_mask); \ |
42 |
|
sigaddset(&action.sa_mask,SIGINT); \ |
43 |
|
sigaddset(&action.sa_mask,SIGALRM); \ |
44 |
|
sigaction(SIGSEGV,&action,0); \ |
45 |
|
sigaction(SIGBUS,&action,0);} while (0) |
46 |
|
|
47 |
|
/* the following two files have changed back |
48 |
|
and forth in recent versions of linux... |
49 |
|
Include both if they both exist, otherwise |
50 |
|
include whatever one exists... |
51 |
|
basically one wants the |
52 |
|
struct sigcontext_struct { ... } ; |
53 |
|
so as to get the fault address. |
54 |
|
*/ |
55 |
|
|
56 |
|
#ifdef SIGNAL_H_HAS_SIGCONTEXT |
57 |
|
#include <signal.h> |
58 |
|
#else |
59 |
|
#ifdef HAVE_ASM_SIGCONTEXT_H |
60 |
|
#include <asm/sigcontext.h> |
61 |
|
#endif |
62 |
|
#ifdef HAVE_ASM_SIGNAL_H |
63 |
|
#include <asm/signal.h> |
64 |
|
#endif |
65 |
|
#ifdef HAVE_SIGCONTEXT |
66 |
|
#define sigcontext_struct sigcontext |
67 |
|
#endif |
68 |
|
#endif |
69 |
|
|
70 |
|
|
71 |
|
/* #define GET_FAULT_ADDR(sig,code,sv,a) \ */ |
72 |
|
/* ((void *)(((struct sigcontext_struct *)(&code))->cr2)) */ |
73 |
|
#endif |
74 |
|
|
75 |
|
|
76 |
|
/* is #define ELF_TEXT_BASE 0x8000000 on current linux */ |
77 |
|
#define ELF_TEXT_BASE DBEGIN |
78 |
|
|
79 |
|
/* on some linux x86 machines the C stack starts in positive number |
80 |
|
range, however since we might compile on one and run on another |
81 |
|
we will have to do this: |
82 |
|
*/ |
83 |
|
#define NULL_OR_ON_C_STACK(x) ((x)==0 || ((unsigned int)x) > (unsigned int)(pagetochar(MAXPAGE+1))) |
84 |
|
|
85 |
|
#undef SET_REAL_MAXPAGE |
86 |
|
#define SET_REAL_MAXPAGE do { struct rlimit data_rlimit; \ |
87 |
|
extern char etext; \ |
88 |
|
real_maxpage = MAXPAGE ;\ |
89 |
|
getrlimit(RLIMIT_DATA, &data_rlimit); \ |
90 |
|
real_maxpage = ((unsigned int)&etext/PAGESIZE \ |
91 |
|
+ data_rlimit.rlim_cur/PAGESIZE - ELF_TEXT_BASE/PAGESIZE); \ |
92 |
|
if (real_maxpage > MAXPAGE) \ |
93 |
|
real_maxpage = MAXPAGE ; } while(0) |
94 |
|
|
95 |
|
#define SPECIAL_RSYM "rsym_elf.c" |
96 |
|
#define SEPARATE_SFASL_FILE "sfaslelf.c" |
97 |
|
|
98 |
|
#define UNEXEC_USE_MAP_PRIVATE |
99 |
|
#define UNIXSAVE "unexelf.c" |
100 |
|
/* end ELF */ |
101 |
|
#else |
102 |
|
#define RELOC_FILE "rel_sun3.c" |
103 |
|
#define UNIXSAVE "unexec.c" |
104 |
|
|
105 |
|
#define start_of_data() &etext |
106 |
|
#define start_of_text() ( (char *) 0 ) |
107 |
|
#define A_TEXT_OFFSET(hdr) (N_MAGIC(hdr) == QMAGIC ? sizeof (struct exec) : 0) |
108 |
|
#define A_TEXT_SEEK(hdr) (N_TXTOFF(hdr) + A_TEXT_OFFSET(hdr)) |
109 |
|
#define ADJUST_EXEC_HEADER \ |
110 |
|
unexec_text_start = N_TXTADDR(ohdr) + A_TEXT_OFFSET(ohdr) |
111 |
|
|
112 |
|
#endif |
113 |
|
|
114 |
|
|
115 |
|
/* #include "386.h" */ |
116 |
|
#undef HAVE_SIGVEC |
117 |
|
/* #define NEED_TO_REINSTALL_SIGNALS */ |
118 |
|
#define HAVE_SIGACTION |
119 |
|
/* make this a noop */ |
120 |
|
#define SETUP_SIG_STACK |
121 |
|
#ifndef HAVE_SV_ONSTACK |
122 |
|
#define SV_ONSTACK 0 |
123 |
|
#endif |
124 |
|
|
125 |
|
/* unblock signals m and n, and set val to signal_mask(m) | signal_mask(n) |
126 |
|
if they were set */ |
127 |
|
#define SIG_UNBLOCK_SIGNALS(val,m,n) \ |
128 |
|
current_mask = sigblock(0); \ |
129 |
|
sigsetmask(~(sigmask(m)) & ~(sigmask(n)) & current_mask); \ |
130 |
|
result = (current_mask & sigmask(m) ? signal_mask(m) : 0) \ |
131 |
|
| (current_mask & sigmask(n) ? signal_mask(n) : 0); |
132 |
|
|
133 |
|
#undef RUN_PROCESS |
134 |
|
|
135 |
|
#define ADDITIONAL_FEATURES \ |
136 |
|
ADD_FEATURE("BSD386"); \ |
137 |
|
ADD_FEATURE("MC68020") |
138 |
|
|
139 |
|
|
140 |
|
#define I386 |
141 |
|
#define IEEEFLOAT |
142 |
|
|
143 |
|
|
144 |
|
/* Pages on Linux are 4096 bytes. */ |
145 |
|
#ifdef PAGEWIDTH |
146 |
|
#error PAGEWIDTH definition conflict |
147 |
|
#endif |
148 |
|
#define PAGEWIDTH 12 /* page width */ |
149 |
|
|
150 |
|
|
151 |
|
#undef HAVE_XDR |
152 |
|
|
153 |
|
#ifdef IN_UNIXSAVE |
154 |
|
#include <linux/user.h> |
155 |
|
#endif |
156 |
|
|
157 |
|
#define USE_ULONG_ |
158 |
|
|
159 |
|
/* How to check for input */ |
160 |
|
#undef LISTEN_FOR_INPUT |
161 |
|
|
162 |
|
#define LISTEN_FOR_INPUT(fp) \ |
163 |
|
do { int c = 0; \ |
164 |
|
if(((fp)->_IO_read_ptr >= (fp)->_IO_read_end) \ |
165 |
|
&& (ioctl((fp)->_fileno, FIONREAD, &c),c<=0)) \ |
166 |
|
return 0;} while (0) |
167 |
|
|
168 |
|
/* we dont need to worry about zeroing fp->_base , to prevent */ |
169 |
|
#define FCLOSE_SETBUF_OK |
170 |
|
|
171 |
|
/* #define DATA_BEGIN((TXTRELOC+header.a_text+(SEGSIZ-1)) & ~(SEGSIZ-1)); */ |
172 |
|
#define DATA_BEGIN (char *)(char *)N_DATADDR(header); |
173 |
|
|
174 |
|
/* |
175 |
|
#undef FILECPY_HEADER |
176 |
|
#define FILECPY_HEADER \ |
177 |
|
if (header.a_magic == ZMAGIC) \ |
178 |
|
filecpy(save, original, PAGSIZ - sizeof(header)); \ |
179 |
|
filecpy(save, original, header.a_text); |
180 |
|
*/ |
181 |
|
|
182 |
|
|
183 |
|
#define LITTLE_END |
184 |
|
|
185 |
|
#define PAGSIZ (NBPG) |
186 |
|
#define SEGSIZ (NBPG * CLSIZE) |
187 |
|
#define TXTRELOC 0 |
188 |
|
|
189 |
|
#define USE_DIRENT |
190 |
|
#define GETPATHNAME |
191 |
|
#define PATHNAME_CACHE 10 |
192 |
|
|
193 |
|
|
194 |
|
/* try out the gnu malloc */ |
195 |
|
/* #define GNU_MALLOC */ |
196 |
|
|
197 |
|
#define INSTALL_SEGMENTATION_CATCHER \ |
198 |
|
(void) signal(SIGSEGV,segmentation_catcher) |
199 |
|
/* if you are in an early version of linux without SIGBUS, uncomment |
200 |
|
the next line */ |
201 |
|
/* #define SIGBUS SIGSEGV */ |
202 |
|
#ifndef HAVE_SIGSYS |
203 |
|
#define SIGSYS SIGSEGV |
204 |
|
#endif |
205 |
|
|
206 |
|
#ifndef HAVE_SIGEMT |
207 |
|
#define SIGEMT SIGSEGV |
208 |
|
#endif |
209 |
|
|
210 |
|
|
211 |
|
/* get the fileno of a FILE* */ |
212 |
|
#define FILENO(x) fileno(x) |
213 |
|
|
214 |
|
#define ULONG_DEFINED |
215 |
|
/* #define NO_PROFILE */ |
216 |
|
|
217 |
|
|
218 |
|
|
219 |
|
#undef LD_COMMAND |
220 |
|
#define LD_COMMAND(command,main,start,input,ldarg,output) \ |
221 |
|
sprintf(command, "ld -d -S -N -x -A %s -T %x %s %s -o %s", \ |
222 |
|
main,start,input,ldarg,output) |
223 |
|
|
224 |
|
#define SET_SESSION_ID() (setpgrp() ? -1 : 0) |
225 |
|
|
226 |
|
|
227 |
|
|
228 |
|
|
229 |
|
/* NOTE: The following text will be automatically included in a |
230 |
|
constructed file cmpinclude.h */ |
231 |
|
/* Begin for cmpinclude */ |
232 |
|
|
233 |
|
|
234 |
|
/* NOTE: If you don't have the system call mprotect DON'T |
235 |
|
define this. |
236 |
|
All Linux ELF systems should have mprotect. */ |
237 |
|
#ifdef __ELF__ |
238 |
|
#define SGC |
239 |
|
#endif |
240 |
|
|
241 |
|
/* _setjmp and _longjmp exist on bsd and are more efficient |
242 |
|
and handle the C stack which is all we need. [I think!] |
243 |
|
*/ |
244 |
|
|
245 |
|
/* End for cmpinclude */ |
246 |
|
/* define if there is no _cleanup, do here what needs |
247 |
|
to be done before calling unexec |
248 |
|
*/ |
249 |
|
#define CLEANUP_CODE \ |
250 |
|
setbuf(stdin,0); \ |
251 |
|
setbuf(stdout,0); |
252 |
|
|
253 |
|
/* the following will try to make sure that the stdin and stdout are |
254 |
|
set correctly on startup after a save */ |
255 |
|
|
256 |
|
|
257 |
|
#define INIT_CORE_END terminal_io->sm.sm_object0->sm.sm_fp = stdin;terminal_io->sm.sm_object1->sm.sm_fp = stdout; |
258 |
|
|
259 |
|
|