|
|
1.1 ! root 1: /* Unexec for Xenix. ! 2: Note that the GNU project considers support for Xenix 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 Xenix 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: ! 113: /* ! 114: On 80386 Xenix, segmentation screws prevent us from modifying the text ! 115: segment at all. We basically just plug a new value for "data segment ! 116: size" into the countless headers and copy the other records straight ! 117: through. The data segment is ORG'ed at the xs_rbase value of the data ! 118: segment's xseg record (always @ 0x1880000, thanks to the "sophisticated ! 119: memory management hardware" of the chip) and extends to sbrk(0), exactly. ! 120: This code is afraid to malloc (should it be?), and alloca has to be the ! 121: wimpy, malloc-based version; consequently, data is usually copied in ! 122: smallish chunks. ! 123: ! 124: [email protected] ! 125: */ ! 126: ! 127: #include "config.h" ! 128: #include <sys/types.h> ! 129: #include <fcntl.h> ! 130: #include <sys/file.h> ! 131: #include <sys/stat.h> ! 132: #include <stdio.h> ! 133: #include <varargs.h> ! 134: #include <a.out.h> ! 135: ! 136: static void fatal_unexec (); ! 137: ! 138: #define READ(_fd, _buffer, _size, _error_message, _error_arg) \ ! 139: errno = EEOF; \ ! 140: if (read(_fd, _buffer, _size) != _size) \ ! 141: fatal_unexec(_error_message, _error_arg); ! 142: ! 143: #define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \ ! 144: if (write(_fd, _buffer, _size) != _size) \ ! 145: fatal_unexec(_error_message, _error_arg); ! 146: ! 147: #define SEEK(_fd, _position, _error_message, _error_arg) \ ! 148: errno = EEOF; \ ! 149: if (lseek(_fd, _position, L_SET) != _position) \ ! 150: fatal_unexec(_error_message, _error_arg); ! 151: ! 152: extern int errno; ! 153: extern int sys_nerr; ! 154: extern char *sys_errlist[]; ! 155: #define EEOF -1 ! 156: ! 157: #ifndef L_SET ! 158: #define L_SET 0 ! 159: #endif ! 160: ! 161: /* Should check the magic number of the old executable; ! 162: not yet written. */ ! 163: check_exec (x) ! 164: struct xexec *x; ! 165: { ! 166: } ! 167: ! 168: ! 169: unexec (new_name, a_name, data_start, bss_start, entry_address) ! 170: char *new_name, *a_name; ! 171: unsigned data_start, bss_start, entry_address; ! 172: { ! 173: char *sbrk (), *datalim = sbrk (0), *data_org; ! 174: long segpos, textseen, textpos, textlen, datapos, datadiff, datalen; ! 175: ! 176: struct xexec u_xexec, /* a.out header */ ! 177: *u_xexecp = &u_xexec; ! 178: struct xext u_xext, /* extended header */ ! 179: *u_xextp = &u_xext; ! 180: struct xseg u_xseg, /* segment table entry */ ! 181: *u_xsegp = &u_xseg; ! 182: int i, nsegs, isdata = 0, infd, outfd; ! 183: ! 184: infd = open (a_name, O_RDONLY, 0); ! 185: if (infd < 0) fatal_unexec ("opening %s", a_name); ! 186: ! 187: outfd = creat (new_name, 0666); ! 188: if (outfd < 0) fatal_unexec ("creating %s", new_name); ! 189: ! 190: READ (infd, u_xexecp, sizeof (struct xexec), ! 191: "error reading %s", a_name); ! 192: check_exec (u_xexecp); ! 193: READ (infd, u_xextp, sizeof (struct xext), ! 194: "error reading %s", a_name); ! 195: segpos = u_xextp->xe_segpos; ! 196: nsegs = u_xextp->xe_segsize / sizeof (struct xseg); ! 197: SEEK (infd, segpos, "seek error on %s", a_name); ! 198: for (i = 0; i < nsegs; i ++) ! 199: { ! 200: READ (infd, u_xsegp, sizeof (struct xseg), ! 201: "error reading %s", a_name); ! 202: switch (u_xsegp->xs_type) ! 203: { ! 204: case XS_TTEXT: ! 205: { ! 206: if (i == 0) ! 207: { ! 208: textpos = u_xsegp->xs_filpos; ! 209: textlen = u_xsegp->xs_psize; ! 210: break; ! 211: } ! 212: fatal_unexec ("invalid text segment in %s", a_name); ! 213: } ! 214: case XS_TDATA: ! 215: { ! 216: if (i == 1) ! 217: { ! 218: datapos = u_xsegp->xs_filpos; ! 219: datalen = datalim - (data_org = (char *)(u_xsegp->xs_rbase)); ! 220: datadiff = datalen - u_xsegp->xs_psize; ! 221: break; ! 222: } ! 223: fatal_unexec ("invalid data segment in %s", a_name); ! 224: } ! 225: default: ! 226: { ! 227: if (i > 1) break; ! 228: fatal_unexec ("invalid segment record in %s", a_name); ! 229: } ! 230: } ! 231: } ! 232: u_xexecp->x_data = datalen; ! 233: u_xexecp->x_bss = 0; ! 234: WRITE (outfd, u_xexecp, sizeof (struct xexec), ! 235: "error writing %s", new_name); ! 236: WRITE (outfd, u_xextp, sizeof (struct xext), ! 237: "error writing %s", new_name); ! 238: SEEK (infd, segpos, "seek error on %s", a_name); ! 239: SEEK (outfd, segpos, "seek error on %s", new_name); ! 240: ! 241: /* Copy the text segment record verbatim. */ ! 242: ! 243: copyrec (infd, outfd, sizeof (struct xseg), a_name, new_name); ! 244: ! 245: /* Read, modify, write the data segment record. */ ! 246: ! 247: READ (infd, u_xsegp, sizeof (struct xseg), ! 248: "error reading %s", a_name); ! 249: u_xsegp->xs_psize = u_xsegp->xs_vsize = datalen; ! 250: u_xsegp->xs_attr &= (~XS_AITER & ~XS_ABSS); ! 251: WRITE (outfd, u_xsegp, sizeof (struct xseg), ! 252: "error writing %s", new_name); ! 253: ! 254: /* Now copy any additional segment records, adjusting their ! 255: file position field */ ! 256: ! 257: for (i = 2; i < nsegs; i++) ! 258: { ! 259: READ (infd, u_xsegp, sizeof (struct xseg), ! 260: "error reading %s", a_name); ! 261: u_xsegp->xs_filpos += datadiff; ! 262: WRITE (outfd, u_xsegp, sizeof (struct xseg), ! 263: "error writing %s", new_name); ! 264: } ! 265: ! 266: SEEK (infd, textpos, "seek error on %s", a_name); ! 267: SEEK (outfd, textpos, "seek error on %s", new_name); ! 268: copyrec (infd, outfd, textlen, a_name, new_name); ! 269: ! 270: SEEK (outfd, datapos, "seek error on %s", new_name); ! 271: WRITE (outfd, data_org, datalen, ! 272: "write error on %s", new_name); ! 273: ! 274: for (i = 2, segpos += (2 * sizeof (struct xseg)); ! 275: i < nsegs; ! 276: i++, segpos += sizeof (struct xseg)) ! 277: { ! 278: SEEK (infd, segpos, "seek error on %s", a_name); ! 279: READ (infd, u_xsegp, sizeof (struct xseg), ! 280: "read error on %s", a_name); ! 281: SEEK (infd, u_xsegp->xs_filpos, "seek error on %s", a_name); ! 282: /* We should be at eof in the output file here, but we must seek ! 283: because the xs_filpos and xs_psize fields in symbol table ! 284: segments are inconsistent. */ ! 285: SEEK (outfd, u_xsegp->xs_filpos + datadiff, "seek error on %s", new_name); ! 286: copyrec (infd, outfd, u_xsegp->xs_psize, a_name, new_name); ! 287: } ! 288: close (infd); ! 289: close (outfd); ! 290: mark_x (new_name); ! 291: return 0; ! 292: } ! 293: ! 294: copyrec (infd, outfd, len, in_name, out_name) ! 295: int infd, outfd, len; ! 296: char *in_name, *out_name; ! 297: { ! 298: char buf[BUFSIZ]; ! 299: int chunk; ! 300: ! 301: while (len) ! 302: { ! 303: chunk = BUFSIZ; ! 304: if (chunk > len) ! 305: chunk = len; ! 306: READ (infd, buf, chunk, "error reading %s", in_name); ! 307: WRITE (outfd, buf, chunk, "error writing %s", out_name); ! 308: len -= chunk; ! 309: } ! 310: } ! 311: ! 312: /* ! 313: * mark_x ! 314: * ! 315: * After succesfully building the new a.out, mark it executable ! 316: */ ! 317: static ! 318: mark_x (name) ! 319: char *name; ! 320: { ! 321: struct stat sbuf; ! 322: int um = umask (777); ! 323: umask (um); ! 324: if (stat (name, &sbuf) < 0) ! 325: fatal_unexec ("getting protection on %s", name); ! 326: sbuf.st_mode |= 0111 & ~um; ! 327: if (chmod (name, sbuf.st_mode) < 0) ! 328: fatal_unexec ("setting protection on %s", name); ! 329: } ! 330: ! 331: static void ! 332: fatal_unexec (s, va_alist) ! 333: va_dcl ! 334: { ! 335: va_list ap; ! 336: if (errno == EEOF) ! 337: fputs ("unexec: unexpected end of file, ", stderr); ! 338: else if (errno < sys_nerr) ! 339: fprintf (stderr, "unexec: %s, ", sys_errlist[errno]); ! 340: else ! 341: fprintf (stderr, "unexec: error code %d, ", errno); ! 342: va_start (ap); ! 343: _doprnt (s, ap, stderr); ! 344: fputs (".\n", stderr); ! 345: exit (1); ! 346: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.