|
|
1.1 root 1: /* Unexec for MIPS (including IRIS4D).
2: Note that the GNU project considers support for MIPS operation
3: a peripheral activity which should not be allowed to divert effort
4: from development of the GNU system. Changes in this code will be
5: installed when users send them in, but aside from that
6: we don't plan to think about it, or about whether other Emacs
7: maintenance might break it.
8:
9: Copyright (C) 1988 Free Software Foundation, Inc.
10:
11: NO WARRANTY
12:
13: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
14: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
15: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
16: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
17: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
18: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
20: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
21: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
22: CORRECTION.
23:
24: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
25: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
26: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
27: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
28: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
29: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
30: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
31: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
32: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
33: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
34:
35: GENERAL PUBLIC LICENSE TO COPY
36:
37: 1. You may copy and distribute verbatim copies of this source file
38: as you receive it, in any medium, provided that you conspicuously and
39: appropriately publish on each copy a valid copyright notice "Copyright
40: (C) 1987 Free Software Foundation, Inc."; and include following the
41: copyright notice a verbatim copy of the above disclaimer of warranty
42: and of this License. You may charge a distribution fee for the
43: physical act of transferring a copy.
44:
45: 2. You may modify your copy or copies of this source file or
46: any portion of it, and copy and distribute such modifications under
47: the terms of Paragraph 1 above, provided that you also do the following:
48:
49: a) cause the modified files to carry prominent notices stating
50: that you changed the files and the date of any change; and
51:
52: b) cause the whole of any work that you distribute or publish,
53: that in whole or in part contains or is a derivative of this
54: program or any part thereof, to be licensed at no charge to all
55: third parties on terms identical to those contained in this
56: License Agreement (except that you may choose to grant more extensive
57: warranty protection to some or all third parties, at your option).
58:
59: c) You may charge a distribution fee for the physical act of
60: transferring a copy, and you may at your option offer warranty
61: protection in exchange for a fee.
62:
63: Mere aggregation of another unrelated program with this program (or its
64: derivative) on a volume of a storage or distribution medium does not bring
65: the other program under the scope of these terms.
66:
67: 3. You may copy and distribute this program (or a portion or derivative
68: of it, under Paragraph 2) in object code or executable form under the terms
69: of Paragraphs 1 and 2 above provided that you also do one of the following:
70:
71: a) accompany it with the complete corresponding machine-readable
72: source code, which must be distributed under the terms of
73: Paragraphs 1 and 2 above; or,
74:
75: b) accompany it with a written offer, valid for at least three
76: years, to give any third party free (except for a nominal
77: shipping charge) a complete machine-readable copy of the
78: corresponding source code, to be distributed under the terms of
79: Paragraphs 1 and 2 above; or,
80:
81: c) accompany it with the information you received as to where the
82: corresponding source code may be obtained. (This alternative is
83: allowed only for noncommercial distribution and only if you
84: received the program in object code or executable form alone.)
85:
86: For an executable file, complete source code means all the source code for
87: all modules it contains; but, as a special exception, it need not include
88: source code for modules which are standard libraries that accompany the
89: operating system on which the executable file runs.
90:
91: 4. You may not copy, sublicense, distribute or transfer this program
92: except as expressly provided under this License Agreement. Any attempt
93: otherwise to copy, sublicense, distribute or transfer this program is void and
94: your rights to use the program under this License agreement shall be
95: automatically terminated. However, parties who have received computer
96: software programs from you with this License Agreement will not have
97: their licenses terminated so long as such parties remain in full compliance.
98:
99: 5. If you wish to incorporate parts of this program into other free
100: programs whose distribution conditions are different, write to the Free
101: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
102: worked out a simple rule that can be stated here, but we will often permit
103: this. We will be guided by the two goals of preserving the free status of
104: all derivatives of our free software and of promoting the sharing and reuse of
105: software.
106:
107:
108: In other words, you are welcome to use, share and improve this program.
109: You are forbidden to forbid anyone else to use, share and improve
110: what you give them. Help stamp out software-hoarding! */
111:
112: #include "config.h"
113: #include <sys/types.h>
114: #include <sys/file.h>
115: #include <sys/stat.h>
116: #include <stdio.h>
117: #include <varargs.h>
118: #include <filehdr.h>
119: #include <aouthdr.h>
120: #include <scnhdr.h>
121: #include <sym.h>
122:
123: #ifdef IRIS_4D
124: #include "getpagesize.h"
125: #include <fcntl.h>
126: #endif
127:
128: static void fatal_unexec ();
129:
130: #define READ(_fd, _buffer, _size, _error_message, _error_arg) \
131: errno = EEOF; \
132: if (read(_fd, _buffer, _size) != _size) \
133: fatal_unexec(_error_message, _error_arg);
134:
135: #define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
136: if (write(_fd, _buffer, _size) != _size) \
137: fatal_unexec(_error_message, _error_arg);
138:
139: #define SEEK(_fd, _position, _error_message, _error_arg) \
140: errno = EEOF; \
141: if (lseek(_fd, _position, L_SET) != _position) \
142: fatal_unexec(_error_message, _error_arg);
143:
144: extern int errno;
145: extern int sys_nerr;
146: extern char *sys_errlist[];
147: #define EEOF -1
148:
149: static struct scnhdr *text_section;
150: static struct scnhdr *init_section;
151: static struct scnhdr *finit_section;
152: static struct scnhdr *rdata_section;
153: static struct scnhdr *data_section;
154: static struct scnhdr *lit8_section;
155: static struct scnhdr *lit4_section;
156: static struct scnhdr *sdata_section;
157: static struct scnhdr *sbss_section;
158: static struct scnhdr *bss_section;
159:
160: struct headers {
161: struct filehdr fhdr;
162: struct aouthdr aout;
163: struct scnhdr section[10];
164: };
165:
166: /* Define name of label for entry point for the dumped executable. */
167:
168: #ifndef DEFAULT_ENTRY_ADDRESS
169: #define DEFAULT_ENTRY_ADDRESS __start
170: #endif
171:
172: unexec (new_name, a_name, data_start, bss_start, entry_address)
173: char *new_name, *a_name;
174: unsigned data_start, bss_start, entry_address;
175: {
176: int new, old;
177: int pagesize, brk;
178: int newsyms, symrel;
179: int nread;
180: struct headers hdr;
181: int i;
182: int vaddr, scnptr;
183: #define BUFSIZE 8192
184: char buffer[BUFSIZE];
185:
186: old = open (a_name, O_RDONLY, 0);
187: if (old < 0) fatal_unexec ("opening %s", a_name);
188:
189: new = creat (new_name, 0666);
190: if (new < 0) fatal_unexec ("creating %s", new_name);
191:
192: hdr = *((struct headers *)TEXT_START);
193: if (hdr.fhdr.f_magic != MIPSELMAGIC
194: && hdr.fhdr.f_magic != MIPSEBMAGIC)
195: {
196: fprintf(stderr, "unexec: input file magic number is %x, not %x or %x.\n",
197: hdr.fhdr.f_magic, MIPSELMAGIC, MIPSEBMAGIC);
198: exit(1);
199: }
200: if (hdr.fhdr.f_opthdr != sizeof(hdr.aout))
201: {
202: fprintf(stderr, "unexec: input a.out header is %d bytes, not %d.\n",
203: hdr.fhdr.f_opthdr, sizeof(hdr.aout));
204: exit(1);
205: }
206: if (hdr.aout.magic != ZMAGIC)
207: {
208: fprintf(stderr, "unexec: input file a.out magic number is %o, not %o.\n",
209: hdr.aout.magic, ZMAGIC);
210: exit(1);
211: }
212:
213: #define CHECK_SCNHDR(ptr, name, flags) \
214: if (strcmp(hdr.section[i].s_name, name) == 0) { \
215: if (hdr.section[i].s_flags != flags) { \
216: fprintf(stderr, "unexec: %x flags where %x expected in %s section.\n", \
217: hdr.section[i].s_flags, flags, name); \
218: } \
219: ptr = hdr.section + i; \
220: i += 1; \
221: } \
222: else { \
223: ptr = NULL; \
224: }
225:
226: i = 0;
227: CHECK_SCNHDR(text_section, _TEXT, STYP_TEXT);
228: CHECK_SCNHDR(init_section, _INIT, STYP_INIT);
229: CHECK_SCNHDR(rdata_section, _RDATA, STYP_RDATA);
230: CHECK_SCNHDR(data_section, _DATA, STYP_DATA);
231: #ifdef _LIT8
232: CHECK_SCNHDR(lit8_section, _LIT8, STYP_LIT8);
233: CHECK_SCNHDR(lit4_section, _LIT4, STYP_LIT4);
234: #endif /* _LIT8 */
235: CHECK_SCNHDR(sdata_section, _SDATA, STYP_SDATA);
236: CHECK_SCNHDR(sbss_section, _SBSS, STYP_SBSS);
237: CHECK_SCNHDR(bss_section, _BSS, STYP_BSS);
238: if (i != hdr.fhdr.f_nscns)
239: fprintf(stderr, "unexec: %d sections found instead of %d.\n",
240: i, hdr.fhdr.f_nscns);
241:
242: pagesize = getpagesize();
243: brk = (sbrk(0) + pagesize - 1) & (-pagesize);
244: hdr.aout.dsize = brk - DATA_START;
245: hdr.aout.bsize = 0;
246: if (entry_address == 0)
247: {
248: extern DEFAULT_ENTRY_ADDRESS();
249: hdr.aout.entry = (unsigned)DEFAULT_ENTRY_ADDRESS;
250: }
251: else
252: hdr.aout.entry = entry_address;
253:
254: hdr.aout.bss_start = hdr.aout.data_start + hdr.aout.dsize;
255: rdata_section->s_size = data_start - DATA_START;
256: data_section->s_vaddr = data_start;
257: data_section->s_paddr = data_start;
258: data_section->s_size = brk - DATA_START;
259: data_section->s_scnptr = rdata_section->s_scnptr + rdata_section->s_size;
260: vaddr = data_section->s_vaddr + data_section->s_size;
261: scnptr = data_section->s_scnptr + data_section->s_size;
262: if (lit8_section != NULL)
263: {
264: lit8_section->s_vaddr = vaddr;
265: lit8_section->s_paddr = vaddr;
266: lit8_section->s_size = 0;
267: lit8_section->s_scnptr = scnptr;
268: }
269: if (lit4_section != NULL)
270: {
271: lit4_section->s_vaddr = vaddr;
272: lit4_section->s_paddr = vaddr;
273: lit4_section->s_size = 0;
274: lit4_section->s_scnptr = scnptr;
275: }
276: if (sdata_section != NULL)
277: {
278: sdata_section->s_vaddr = vaddr;
279: sdata_section->s_paddr = vaddr;
280: sdata_section->s_size = 0;
281: sdata_section->s_scnptr = scnptr;
282: }
283: if (sbss_section != NULL)
284: {
285: sbss_section->s_vaddr = vaddr;
286: sbss_section->s_paddr = vaddr;
287: sbss_section->s_size = 0;
288: sbss_section->s_scnptr = scnptr;
289: }
290: if (bss_section != NULL)
291: {
292: bss_section->s_vaddr = vaddr;
293: bss_section->s_paddr = vaddr;
294: bss_section->s_size = 0;
295: bss_section->s_scnptr = scnptr;
296: }
297:
298: WRITE(new, TEXT_START, hdr.aout.tsize,
299: "writing text section to %s", new_name);
300: WRITE(new, DATA_START, hdr.aout.dsize,
301: "writing text section to %s", new_name);
302:
303: SEEK(old, hdr.fhdr.f_symptr, "seeking to start of symbols in %s", a_name);
304: errno = EEOF;
305: nread = read(old, buffer, BUFSIZE);
306: if (nread < sizeof(HDRR)) fatal_unexec("reading symbols from %s", a_name);
307: #define symhdr ((pHDRR)buffer)
308: newsyms = hdr.aout.tsize + hdr.aout.dsize;
309: symrel = newsyms - hdr.fhdr.f_symptr;
310: hdr.fhdr.f_symptr = newsyms;
311: symhdr->cbLineOffset += symrel;
312: symhdr->cbDnOffset += symrel;
313: symhdr->cbPdOffset += symrel;
314: symhdr->cbSymOffset += symrel;
315: symhdr->cbOptOffset += symrel;
316: symhdr->cbAuxOffset += symrel;
317: symhdr->cbSsOffset += symrel;
318: symhdr->cbSsExtOffset += symrel;
319: symhdr->cbFdOffset += symrel;
320: symhdr->cbRfdOffset += symrel;
321: symhdr->cbExtOffset += symrel;
322: #undef symhdr
323: do
324: {
325: if (write(new, buffer, nread) != nread)
326: fatal_unexec("writing symbols to %s", new_name);
327: nread = read(old, buffer, BUFSIZE);
328: if (nread < 0) fatal_unexec("reading symbols from %s", a_name);
329: #undef BUFSIZE
330: } while (nread != 0);
331:
332: SEEK(new, 0, "seeking to start of header in %s", new_name);
333: WRITE(new, &hdr, sizeof(hdr),
334: "writing header of %s", new_name);
335:
336: close(old);
337: close(new);
338: mark_x(new_name);
339: }
340:
341: /*
342: * mark_x
343: *
344: * After succesfully building the new a.out, mark it executable
345: */
346:
347: static
348: mark_x (name)
349: char *name;
350: {
351: struct stat sbuf;
352: int um = umask (777);
353: umask (um);
354: if (stat (name, &sbuf) < 0)
355: fatal_unexec ("getting protection on %s", name);
356: sbuf.st_mode |= 0111 & ~um;
357: if (chmod (name, sbuf.st_mode) < 0)
358: fatal_unexec ("setting protection on %s", name);
359: }
360:
361: static void
362: fatal_unexec (s, va_alist)
363: va_dcl
364: {
365: va_list ap;
366: if (errno == EEOF)
367: fputs ("unexec: unexpected end of file, ", stderr);
368: else if (errno < sys_nerr)
369: fprintf (stderr, "unexec: %s, ", sys_errlist[errno]);
370: else
371: fprintf (stderr, "unexec: error code %d, ", errno);
372: va_start (ap);
373: _doprnt (s, ap, stderr);
374: fputs (".\n", stderr);
375: exit (1);
376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.