aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1994-09-17 00:59:56 +0000
committerRichard M. Stallman1994-09-17 00:59:56 +0000
commitb061d5f1ee381550f844843d02cae9afbe2199b4 (patch)
tree90ecb8f8753cdb4b6512d97d63f950b89dc62858 /src
parentce99fd6592360172ad88189e2e187344f17f23af (diff)
downloademacs-b061d5f1ee381550f844843d02cae9afbe2199b4.tar.gz
emacs-b061d5f1ee381550f844843d02cae9afbe2199b4.zip
Initial revision
Diffstat (limited to 'src')
-rw-r--r--src/m/alpha.h201
-rw-r--r--src/unexalpha.c440
2 files changed, 641 insertions, 0 deletions
diff --git a/src/m/alpha.h b/src/m/alpha.h
new file mode 100644
index 00000000000..a78aec54fc7
--- /dev/null
+++ b/src/m/alpha.h
@@ -0,0 +1,201 @@
1/* machine description file For the alpha chip.
2 Copyright (C) 1994 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21/* The following line tells the configuration script what sort of
22 operating system this machine is likely to run.
23 USUAL-OPSYS="note"
24
25NOTE-START
26Use -opsystem=osf1
27NOTE-END
28
29*/
30
31/* The following three symbols give information on
32 the size of various data types. */
33
34#define SHORTBITS 16 /* Number of bits in a short */
35
36#define INTBITS 32 /* Number of bits in an int */
37
38#define LONGBITS 64 /* Number of bits in a long */
39
40/* Define BIG_ENDIAN iff lowest-numbered byte in a word
41 is the most significant byte. */
42
43/* Alpha is not big-endian #define BIG_ENDIAN */
44
45/* Define NO_ARG_ARRAY if you cannot take the address of the first of a
46 * group of arguments and treat it as an array of the arguments. */
47
48#define NO_ARG_ARRAY
49
50/* Define WORD_MACHINE if addresses and such have
51 * to be corrected before they can be used as byte counts. */
52
53/* #define WORD_MACHINE */
54
55/* Now define a symbol for the cpu type, if your compiler
56 does not define it automatically:
57 Ones defined so far include vax, m68000, ns16000, pyramid,
58 orion, tahoe, APOLLO and many others */
59
60/* __alpha defined automatically */
61
62
63/* Use type EMACS_INT rather than a union, to represent Lisp_Object */
64/* This is desirable for most machines. */
65
66#define NO_UNION_TYPE
67
68/* Define the type to use. */
69#define EMACS_INT long
70#define EMACS_UINT unsigned long
71
72/* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend
73 the 24-bit bit field into an int. In other words, if bit fields
74 are always unsigned.
75
76 If you use NO_UNION_TYPE, this flag does not matter. */
77
78#define EXPLICIT_SIGN_EXTEND
79
80/* Data type of load average, as read out of kmem. */
81
82#define LOAD_AVE_TYPE long
83
84/* Convert that into an integer that is 100 for a load average of 1.0 */
85
86#define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / FSCALE)
87
88/* Define CANNOT_DUMP on machines where unexec does not work.
89 Then the function dump-emacs will not be defined
90 and temacs will do (load "loadup") automatically unless told otherwise. */
91
92/* #define CANNOT_DUMP */
93
94/* Define VIRT_ADDR_VARIES if the virtual addresses of
95 pure and impure space as loaded can vary, and even their
96 relative order cannot be relied on.
97
98 Otherwise Emacs assumes that text space precedes data space,
99 numerically. */
100
101/* #define VIRT_ADDR_VARIES */
102
103/* Define C_ALLOCA if this machine does not support a true alloca
104 and the one written in C should be used instead.
105 Define HAVE_ALLOCA to say that the system provides a properly
106 working alloca function and it should be used.
107 Define neither one if an assembler-language alloca
108 in the file alloca.s should be used. */
109
110#define HAVE_ALLOCA
111
112/* GNU malloc and the relocating allocator do not work together
113 with X. */
114
115#define SYSTEM_MALLOC
116
117/* Define NO_REMAP if memory segmentation makes it not work well
118 to change the boundary between the text section and data section
119 when Emacs is dumped. If you define this, the preloaded Lisp
120 code will not be sharable; but that's better than failing completely. */
121
122#define NO_REMAP
123
124/* Some really obscure 4.2-based systems (like Sequent DYNIX)
125 * do not support asynchronous I/O (using SIGIO) on sockets,
126 * even though it works fine on tty's. If you have one of
127 * these systems, define the following, and then use it in
128 * config.h (or elsewhere) to decide when (not) to use SIGIO.
129 *
130 * You'd think this would go in an operating-system description file,
131 * but since it only occurs on some, but not all, BSD systems, the
132 * reasonable place to select for it is in the machine description
133 * file.
134 */
135
136/* #define NO_SOCK_SIGIO */
137
138
139#define HAVE_X11R4
140#define HAVE_X11R5
141
142
143/* Describe layout of the address space in an executing process. */
144
145#define TEXT_START 0x120000000
146#define DATA_START 0x140000000
147
148/* This is necessary for mem-limits.h, so that start_of_data gives
149 the correct value */
150
151#define DATA_SEG_BITS 0x140000000
152
153
154#define ORDINARY_LINK
155
156#define LIBS_DEBUG
157#define START_FILES pre-crt0.o
158
159
160/* The program to be used for unexec. */
161
162#define UNEXEC unexalpha.o
163
164
165#define PNTR_COMPARISON_TYPE unsigned long
166
167/* On the 64 bit architecture, we can use 56 bits for addresses */
168
169#define VALBITS 56
170
171
172/* This definition of MARKBIT is necessary because of the comparison of
173 ARRAY_MARK_FLAG and MARKBIT in an #if in lisp.h, which cpp doesn't like. */
174
175#define MARKBIT 0x8000000000000000L
176
177
178/* Define XINT and XUINT so that they can take arguments of type int */
179
180#define XINT(a) (((long)(a) << LONGBITS-VALBITS) >> LONGBITS-VALBITS)
181#define XUINT(a) ((long)(a) & VALMASK)
182
183/* Define XPNTR to avoid or'ing with DATA_SEG_BITS */
184
185#define XPNTR(a) XUINT (a)
186
187
188/* Similarly, for XSETINT */
189
190#define XSETINT(a, b) ((a) = (long)((a) & ~VALMASK) | (long)((b) & VALMASK))
191
192
193/* Make PURESIZE twice as large, as pointers are 64 bit */
194
195#ifdef MULTI_FRAME
196#define PURESIZE 460000
197#else
198#define PURESIZE 400000
199#endif
200
201
diff --git a/src/unexalpha.c b/src/unexalpha.c
new file mode 100644
index 00000000000..6260288d0bc
--- /dev/null
+++ b/src/unexalpha.c
@@ -0,0 +1,440 @@
1/* Unexec for DEC alpha. schoepf@sc.ZIB-Berlin.DE (Rainer Schoepf).
2
3 Copyright (C) 1994 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22#include <config.h>
23#include <sys/types.h>
24#include <sys/file.h>
25#include <sys/stat.h>
26#include <sys/mman.h>
27#include <stdio.h>
28#include <varargs.h>
29#include <filehdr.h>
30#include <aouthdr.h>
31#include <scnhdr.h>
32#include <syms.h>
33
34static void fatal_unexec ();
35static void mark_x ();
36
37#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
38 errno = EEOF; \
39 if (read (_fd, _buffer, _size) != _size) \
40 fatal_unexec (_error_message, _error_arg);
41
42#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
43 if (write (_fd, _buffer, _size) != _size) \
44 fatal_unexec (_error_message, _error_arg);
45
46#define SEEK(_fd, _position, _error_message, _error_arg) \
47 errno = EEOF; \
48 if (lseek (_fd, _position, L_SET) != _position) \
49 fatal_unexec (_error_message, _error_arg);
50
51extern int errno;
52extern char *strerror ();
53
54void *sbrk();
55
56#define EEOF -1
57
58static struct scnhdr *text_section;
59static struct scnhdr *init_section;
60static struct scnhdr *finit_section;
61static struct scnhdr *rdata_section;
62static struct scnhdr *data_section;
63static struct scnhdr *pdata_section;
64static struct scnhdr *xdata_section;
65static struct scnhdr *got_section;
66static struct scnhdr *lit8_section;
67static struct scnhdr *lit4_section;
68static struct scnhdr *sdata_section;
69static struct scnhdr *sbss_section;
70static struct scnhdr *bss_section;
71
72static unsigned int Brk;
73
74struct headers {
75 struct filehdr fhdr;
76 struct aouthdr aout;
77 struct scnhdr section[_MIPS_NSCNS_MAX];
78};
79
80
81
82/* Define name of label for entry point for the dumped executable. */
83
84#ifndef DEFAULT_ENTRY_ADDRESS
85#define DEFAULT_ENTRY_ADDRESS __start
86#endif
87
88unexec (new_name, a_name, data_start, bss_start, entry_address)
89 char *new_name, *a_name;
90 unsigned long data_start, bss_start, entry_address;
91{
92 int new, old;
93 char * oldptr;
94 struct headers ohdr, nhdr;
95 struct stat stat;
96 long pagesize, brk;
97 long newsyms, symrel;
98 int nread;
99 int i;
100 long vaddr, scnptr;
101#define BUFSIZE 8192
102 char buffer[BUFSIZE];
103
104 if ((old = open (a_name, O_RDONLY)) < 0)
105 fatal_unexec ("opening %s", a_name);
106
107 new = creat (new_name, 0666);
108 if (new < 0) fatal_unexec ("creating %s", new_name);
109
110 if ((fstat (old, &stat) == -1))
111 fatal_unexec ("fstat %s", a_name);
112
113 oldptr = (char *)mmap (0, stat.st_size, PROT_READ, MAP_FILE|MAP_SHARED, old, 0);
114
115 if (oldptr == (char *)-1)
116 fatal_unexec ("mmap %s", a_name);
117
118 close (old);
119
120 /* This is a copy of the a.out header of the original executable */
121
122 ohdr = (*(struct headers *)oldptr);
123
124 /* This is where we build the new header from the in-memory copy */
125
126 nhdr = *((struct headers *)TEXT_START);
127
128 /* First do some consistency checks */
129
130 if (nhdr.fhdr.f_magic != ALPHAMAGIC
131 && nhdr.fhdr.f_magic != ALPHAUMAGIC)
132 {
133 fprintf (stderr, "unexec: input file magic number is %x, not %x or %x.\n",
134 nhdr.fhdr.f_magic, ALPHAMAGIC, ALPHAUMAGIC);
135 exit (1);
136 }
137
138 if (nhdr.fhdr.f_opthdr != sizeof (nhdr.aout))
139 {
140 fprintf (stderr, "unexec: input a.out header is %d bytes, not %d.\n",
141 nhdr.fhdr.f_opthdr, sizeof (nhdr.aout));
142 exit (1);
143 }
144 if (nhdr.aout.magic != ZMAGIC)
145 {
146 fprintf (stderr, "unexec: input file a.out magic number is %o, not %o.\n",
147 nhdr.aout.magic, ZMAGIC);
148 exit (1);
149 }
150
151
152 /* Now check the existence of certain header section and grab
153 their addresses. */
154
155#define CHECK_SCNHDR(ptr, name, flags) \
156 ptr = NULL; \
157 for (i = 0; i < nhdr.fhdr.f_nscns && !ptr; i++) \
158 if (strcmp (nhdr.section[i].s_name, name) == 0) \
159 { \
160 if (nhdr.section[i].s_flags != flags) \
161 fprintf (stderr, "unexec: %x flags (%x expected) in %s section.\n", \
162 nhdr.section[i].s_flags, flags, name); \
163 ptr = nhdr.section + i; \
164 } \
165
166 CHECK_SCNHDR (text_section, _TEXT, STYP_TEXT);
167 CHECK_SCNHDR (init_section, _INIT, STYP_INIT);
168#ifdef _FINI
169 CHECK_SCNHDR (finit_section, _FINI, STYP_FINI);
170#endif /* _FINI */
171 CHECK_SCNHDR (rdata_section, _RDATA, STYP_RDATA);
172#ifdef _PDATA
173 CHECK_SCNHDR (pdata_section, _PDATA, STYP_PDATA);
174#endif _PDATA
175#ifdef _GOT
176 CHECK_SCNHDR (got_section, _GOT, STYP_GOT);
177#endif _GOT
178 CHECK_SCNHDR (data_section, _DATA, STYP_DATA);
179#ifdef _XDATA
180 CHECK_SCNHDR (xdata_section, _XDATA, STYP_XDATA);
181#endif /* _XDATA */
182#ifdef _LIT8
183 CHECK_SCNHDR (lit8_section, _LIT8, STYP_LIT8);
184 CHECK_SCNHDR (lit4_section, _LIT4, STYP_LIT4);
185#endif /* _LIT8 */
186 CHECK_SCNHDR (sdata_section, _SDATA, STYP_SDATA);
187 CHECK_SCNHDR (sbss_section, _SBSS, STYP_SBSS);
188 CHECK_SCNHDR (bss_section, _BSS, STYP_BSS);
189#if 0 /* Apparently this error check goes off on irix 3.3,
190 but it doesn't indicate a real problem. */
191 if (i != nhdr.fhdr.f_nscns)
192 fprintf (stderr, "unexec: %d sections found instead of %d.\n",
193 i, nhdr.fhdr.f_nscns);
194#endif
195
196
197 pagesize = getpagesize ();
198 brk = (((long) (sbrk (0))) + pagesize - 1) & (-pagesize);
199
200 /* Remember the current break */
201
202 Brk = brk;
203
204 nhdr.aout.dsize = brk - DATA_START;
205 nhdr.aout.bsize = 0;
206 if (entry_address == 0)
207 {
208 extern DEFAULT_ENTRY_ADDRESS ();
209 nhdr.aout.entry = (unsigned long)DEFAULT_ENTRY_ADDRESS;
210 }
211 else
212 nhdr.aout.entry = entry_address;
213
214 nhdr.aout.bss_start = nhdr.aout.data_start + nhdr.aout.dsize;
215 rdata_section->s_size = data_start - DATA_START;
216
217 /* Adjust start and virtual addresses of rdata_section, too. */
218 rdata_section->s_vaddr = DATA_START;
219 rdata_section->s_paddr = DATA_START;
220 rdata_section->s_scnptr = text_section->s_scnptr + nhdr.aout.tsize;
221
222 data_section->s_vaddr = data_start;
223 data_section->s_paddr = data_start;
224 data_section->s_size = brk - data_start;
225 data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size;
226 vaddr = data_section->s_vaddr + data_section->s_size;
227 scnptr = data_section->s_scnptr + data_section->s_size;
228 if (lit8_section != NULL)
229 {
230 lit8_section->s_vaddr = vaddr;
231 lit8_section->s_paddr = vaddr;
232 lit8_section->s_size = 0;
233 lit8_section->s_scnptr = scnptr;
234 }
235 if (lit4_section != NULL)
236 {
237 lit4_section->s_vaddr = vaddr;
238 lit4_section->s_paddr = vaddr;
239 lit4_section->s_size = 0;
240 lit4_section->s_scnptr = scnptr;
241 }
242 if (sdata_section != NULL)
243 {
244 sdata_section->s_vaddr = vaddr;
245 sdata_section->s_paddr = vaddr;
246 sdata_section->s_size = 0;
247 sdata_section->s_scnptr = scnptr;
248 }
249#ifdef _XDATA
250 if (xdata_section != NULL)
251 {
252 xdata_section->s_vaddr = vaddr;
253 xdata_section->s_paddr = vaddr;
254 xdata_section->s_size = 0;
255 xdata_section->s_scnptr = scnptr;
256 }
257#endif
258#ifdef _GOT
259 if (got_section != NULL)
260 {
261 got_section->s_vaddr = vaddr;
262 got_section->s_paddr = vaddr;
263 got_section->s_size = 0;
264 got_section->s_scnptr = scnptr;
265 }
266#endif /*_GOT */
267 if (sbss_section != NULL)
268 {
269 sbss_section->s_vaddr = vaddr;
270 sbss_section->s_paddr = vaddr;
271 sbss_section->s_size = 0;
272 sbss_section->s_scnptr = scnptr;
273 }
274 if (bss_section != NULL)
275 {
276 bss_section->s_vaddr = vaddr;
277 bss_section->s_paddr = vaddr;
278 bss_section->s_size = 0;
279 bss_section->s_scnptr = scnptr;
280 }
281
282 WRITE (new, (char *)TEXT_START, nhdr.aout.tsize,
283 "writing text section to %s", new_name);
284 WRITE (new, (char *)DATA_START, nhdr.aout.dsize,
285 "writing data section to %s", new_name);
286
287
288 /*
289 * Construct new symbol table header
290 */
291
292 bcopy (oldptr + nhdr.fhdr.f_symptr, buffer, cbHDRR);
293
294#define symhdr ((pHDRR)buffer)
295 newsyms = nhdr.aout.tsize + nhdr.aout.dsize;
296 symrel = newsyms - nhdr.fhdr.f_symptr;
297 nhdr.fhdr.f_symptr = newsyms;
298 symhdr->cbLineOffset += symrel;
299 symhdr->cbDnOffset += symrel;
300 symhdr->cbPdOffset += symrel;
301 symhdr->cbSymOffset += symrel;
302 symhdr->cbOptOffset += symrel;
303 symhdr->cbAuxOffset += symrel;
304 symhdr->cbSsOffset += symrel;
305 symhdr->cbSsExtOffset += symrel;
306 symhdr->cbFdOffset += symrel;
307 symhdr->cbRfdOffset += symrel;
308 symhdr->cbExtOffset += symrel;
309
310 WRITE (new, buffer, cbHDRR, "writing symbol table header of %s", new_name);
311
312 /*
313 * Copy the symbol table and line numbers
314 */
315 WRITE (new, oldptr + ohdr.fhdr.f_symptr + cbHDRR,
316 stat.st_size - ohdr.fhdr.f_symptr - cbHDRR,
317 "writing symbol table of %s", new_name);
318
319#if 0
320
321/* Not needed for now */
322
323 update_dynamic_symbols (oldptr, new, newsyms,
324 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->issExtMax,
325 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbExtOffset,
326 ((pHDRR) (oldptr + ohdr.fhdr.f_symptr))->cbSsExtOffset);
327
328#endif
329
330#undef symhdr
331
332 SEEK (new, 0, "seeking to start of header in %s", new_name);
333 WRITE (new, &nhdr, sizeof (nhdr),
334 "writing header of %s", new_name);
335
336 close (old);
337 close (new);
338 mark_x (new_name);
339}
340
341
342#if 0
343
344/* Not needed for now */
345
346/* The following function updates the values of some symbols
347 that are used by the dynamic loader:
348
349 _edata
350 _end
351
352*/
353
354
355update_dynamic_symbols (old, new, newsyms, nsyms, symoff, stroff)
356char *old; /* Pointer to old executable */
357int new; /* File descriptor for new executable */
358long newsyms; /* Offset of Symbol table in new executable */
359int nsyms; /* Number of symbol table entries */
360long symoff; /* Offset of External Symbols in old file */
361long stroff; /* Offset of string table in old file */
362{
363 long i;
364 int found = 0;
365 EXTR n_end, n_edata;
366
367 /* We go through the symbol table entries until we have found the two
368 symbols. */
369
370 /* cbEXTR is the size of an external symbol table entry */
371
372 for (i = 0; i < nsyms && found < 2; i += cbEXTR)
373 {
374 register pEXTR x = (pEXTR) (old + symoff + i);
375 char *s;
376
377 s = old + stroff + x->asym.iss; /* name of the symbol */
378
379 if (!strcmp(s,"_edata"))
380 {
381 found++;
382 bcopy (x, &n_edata, cbEXTR);
383 n_edata.asym.value = Brk;
384 SEEK (new, newsyms + cbHDRR + i,
385 "seeking to symbol _edata in %s", new_name);
386 WRITE (new, n_edata, cbEXTR,
387 "writing symbol table entry for _edata into %s", new_name);
388 }
389 else if (!strcmp(s,"_end"))
390 {
391 found++;
392 bcopy (x, &n_end, cbEXTR);
393 n_end.asym.value = Brk;
394 SEEK (new, newsyms + cbHDRR + i,
395 "seeking to symbol _end in %s", new_name);
396 WRITE (new, n_end, cbEXTR,
397 "writing symbol table entry for _end into %s", new_name);
398 }
399 }
400
401}
402
403#endif
404
405
406/*
407 * mark_x
408 *
409 * After successfully building the new a.out, mark it executable
410 */
411
412static void
413mark_x (name)
414 char *name;
415{
416 struct stat sbuf;
417 int um = umask (777);
418 umask (um);
419 if (stat (name, &sbuf) < 0)
420 fatal_unexec ("getting protection on %s", name);
421 sbuf.st_mode |= 0111 & ~um;
422 if (chmod (name, sbuf.st_mode) < 0)
423 fatal_unexec ("setting protection on %s", name);
424}
425
426static void
427fatal_unexec (s, va_alist)
428 va_dcl
429{
430 va_list ap;
431 if (errno == EEOF)
432 fputs ("unexec: unexpected end of file, ", stderr);
433 else
434 fprintf (stderr, "unexec: %s, ", strerror (errno));
435 va_start (ap);
436 _doprnt (s, ap, stderr);
437 fputs (".\n", stderr);
438 exit (1);
439}
440