|
|
1.1 ! root 1: /* Copyright (C) 1985 Free Software Foundation, Inc. ! 2: ! 3: This file is part of GNU Emacs. ! 4: ! 5: GNU Emacs is distributed in the hope that it will be useful, ! 6: but WITHOUT ANY WARRANTY. No author or distributor ! 7: accepts responsibility to anyone for the consequences of using it ! 8: or for whether it serves any particular purpose or works at all, ! 9: unless he says so in writing. Refer to the GNU Emacs General Public ! 10: License for full details. ! 11: ! 12: Everyone is granted permission to copy, modify and redistribute ! 13: GNU Emacs, but only under the conditions described in the ! 14: GNU Emacs General Public License. A copy of this license is ! 15: supposed to have been given to you along with GNU Emacs so you ! 16: can know your rights and responsibilities. It should be in a ! 17: file named COPYING. Among other things, the copyright notice ! 18: and this notice must be preserved on all copies. */ ! 19: ! 20: ! 21: /* ! 22: * unexec.c - Convert a running program into an a.out file. ! 23: * ! 24: * Author: Spencer W. Thomas ! 25: * Computer Science Dept. ! 26: * University of Utah ! 27: * Date: Tue Mar 2 1982 ! 28: * Modified heavily since then. ! 29: * ! 30: * Synopsis: ! 31: * unexec (new_name, a_name, data_start, bss_start, entry_address) ! 32: * char *new_name, *a_name; ! 33: * unsigned data_start, bss_start, entry_address; ! 34: * ! 35: * Takes a snapshot of the program and makes an a.out format file in the ! 36: * file named by the string argument new_name. ! 37: * If a_name is non-NULL, the symbol table will be taken from the given file. ! 38: * ! 39: * The boundaries within the a.out file may be adjusted with the data_start ! 40: * and bss_start arguments. Either or both may be given as 0 for defaults. ! 41: * ! 42: * Data_start gives the boundary between the text segment and the data ! 43: * segment of the program. The text segment can contain shared, read-only ! 44: * program code and literal data, while the data segment is always unshared ! 45: * and unprotected. Data_start gives the lowest unprotected address. Since ! 46: * the granularity of write-protection is on 1k page boundaries on the VAX, a ! 47: * given data_start value which is not on a page boundary is rounded down to ! 48: * the beginning of the page it is on. The default when 0 is given leaves the ! 49: * number of protected pages the same as it was before. ! 50: * ! 51: * Bss_start indicates how much of the data segment is to be saved in the ! 52: * a.out file and restored when the program is executed. It gives the lowest ! 53: * unsaved address, and is rounded up to a page boundary. The default when 0 ! 54: * is given assumes that the entire data segment is to be stored, including ! 55: * the previous data and bss as well as any additional storage allocated with ! 56: * break (2). ! 57: * ! 58: * The new file is set up to start at entry_address. ! 59: * ! 60: * If you make improvements I'd like to get them too. ! 61: * harpo!utah-cs!thomas, thomas@Utah-20 ! 62: * ! 63: */ ! 64: ! 65: #ifndef emacs ! 66: #define PERROR(arg) perror (arg); return -1 ! 67: #else ! 68: #include "config.h" ! 69: #define PERROR(file) report_error (file, new) ! 70: #endif ! 71: ! 72: #ifndef CANNOT_DUMP /* all rest of file! */ ! 73: ! 74: #include <sys/param.h> ! 75: #ifndef makedev /* Try to detect types.h already loaded */ ! 76: #include <sys/types.h> ! 77: #endif ! 78: #include <stdio.h> ! 79: #include <sys/stat.h> ! 80: #include <errno.h> ! 81: ! 82: extern char *start_of_text (); /* Start of text */ ! 83: extern char *start_of_data (); /* Start of initialized data */ ! 84: ! 85: #ifdef COFF ! 86: #include <filehdr.h> ! 87: #include <aouthdr.h> ! 88: #include <scnhdr.h> ! 89: #include <syms.h> ! 90: static long block_copy_start; /* Old executable start point */ ! 91: static struct filehdr f_hdr; /* File header */ ! 92: static struct aouthdr f_ohdr; /* Optional file header (a.out) */ ! 93: long bias; /* Bias to add for growth */ ! 94: long lnnoptr; /* Pointer to line-number info within file */ ! 95: #define SYMS_START block_copy_start ! 96: ! 97: static int text_scnptr; ! 98: ! 99: #else /* not COFF */ ! 100: ! 101: extern char *sbrk (); ! 102: ! 103: #include <a.out.h> ! 104: #define SYMS_START ((long) N_SYMOFF (ohdr)) ! 105: ! 106: #ifdef HPUX ! 107: #ifdef hp9000s200 ! 108: #define MY_ID HP9000S200_ID ! 109: #else ! 110: #include <model.h> ! 111: #define MY_ID MYSYS ! 112: #endif /* not hp9000s200 */ ! 113: static MAGIC OLDMAGIC = {MY_ID, SHARE_MAGIC}; ! 114: static MAGIC NEWMAGIC = {MY_ID, DEMAND_MAGIC}; ! 115: #define N_TXTOFF(x) TEXT_OFFSET(x) ! 116: #define N_SYMOFF(x) LESYM_OFFSET(x) ! 117: static struct exec hdr, ohdr; ! 118: ! 119: #else /* not HPUX */ ! 120: ! 121: #ifdef USG ! 122: static struct bhdr hdr, ohdr; ! 123: #define a_magic fmagic ! 124: #define a_text tsize ! 125: #define a_data dsize ! 126: #define a_bss bsize ! 127: #define a_syms ssize ! 128: #define a_trsize rtsize ! 129: #define a_drsize rdsize ! 130: #define a_entry entry ! 131: #define N_BADMAG(x) \ ! 132: (((x).fmagic)!=OMAGIC && ((x).fmagic)!=NMAGIC &&\ ! 133: ((x).fmagic)!=FMAGIC && ((x).fmagic)!=IMAGIC) ! 134: #define NEWMAGIC FMAGIC ! 135: #else /* not USG */ ! 136: static struct exec hdr, ohdr; ! 137: #define NEWMAGIC ZMAGIC ! 138: #endif /* not USG */ ! 139: #endif /* not HPUX */ ! 140: ! 141: #endif /* not COFF */ ! 142: ! 143: static int pagemask; ! 144: ! 145: #if defined (BSD4_1) || defined (USG) ! 146: #ifdef EXEC_PAGESIZE ! 147: #define getpagesize() EXEC_PAGESIZE ! 148: #else ! 149: #ifdef NBPG ! 150: #define getpagesize() NBPG * CLSIZE ! 151: #ifndef CLSIZE ! 152: #define CLSIZE 1 ! 153: #endif /* no CLSIZE */ ! 154: #else /* no NBPG */ ! 155: #define getpagesize() NBPC ! 156: #endif /* no NBPG */ ! 157: #endif /* no EXEC_PAGESIZE */ ! 158: #endif /* BSD4_1 or USG */ ! 159: ! 160: /* Correct an int which is the bit pattern of a pointer to a byte ! 161: into an int which is the number of a byte. ! 162: This is a no-op on ordinary machines, but not on all. */ ! 163: ! 164: #ifndef ADDR_CORRECT /* Let m-*.h files override this definition */ ! 165: #define ADDR_CORRECT(x) ((char *)(x) - (char*)0) ! 166: #endif ! 167: ! 168: #ifdef emacs ! 169: ! 170: static ! 171: report_error (file, fd) ! 172: char *file; ! 173: int fd; ! 174: { ! 175: if (fd) ! 176: close (fd); ! 177: error ("Failure operating on %s", file); ! 178: } ! 179: #endif /* emacs */ ! 180: ! 181: #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 ! 182: #define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1 ! 183: #define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1 ! 184: ! 185: static ! 186: report_error_1 (fd, msg, a1, a2) ! 187: int fd; ! 188: char *msg; ! 189: int a1, a2; ! 190: { ! 191: close (fd); ! 192: #ifdef emacs ! 193: error (msg, a1, a2); ! 194: #else ! 195: fprintf (stderr, msg, a1, a2); ! 196: fprintf (stderr, "\n"); ! 197: #endif ! 198: } ! 199: ! 200: /* **************************************************************** ! 201: * unexec ! 202: * ! 203: * driving logic. ! 204: */ ! 205: unexec (new_name, a_name, data_start, bss_start, entry_address) ! 206: char *new_name, *a_name; ! 207: unsigned data_start, bss_start, entry_address; ! 208: { ! 209: int new, a_out = -1; ! 210: ! 211: if (a_name && (a_out = open (a_name, 0)) < 0) ! 212: { ! 213: PERROR (a_name); ! 214: } ! 215: if ((new = creat (new_name, 0666)) < 0) ! 216: { ! 217: PERROR (new_name); ! 218: } ! 219: if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0 ! 220: || copy_text_and_data (new) < 0 ! 221: || copy_sym (new, a_out, a_name, new_name) < 0 ! 222: #ifdef COFF ! 223: || adjust_lnnoptrs (new, a_out, new_name) < 0 ! 224: #endif ! 225: ) ! 226: { ! 227: close (new); ! 228: /* unlink (new_name); /* Failed, unlink new a.out */ ! 229: return -1; ! 230: } ! 231: ! 232: close (new); ! 233: if (a_out >= 0) ! 234: close (a_out); ! 235: mark_x (new_name); ! 236: return 0; ! 237: } ! 238: ! 239: /* **************************************************************** ! 240: * make_hdr ! 241: * ! 242: * Make the header in the new a.out from the header in core. ! 243: * Modify the text and data sizes. ! 244: */ ! 245: static int ! 246: make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) ! 247: int new, a_out; ! 248: unsigned data_start, bss_start, entry_address; ! 249: char *a_name; ! 250: char *new_name; ! 251: { ! 252: int tem; ! 253: #ifdef COFF ! 254: auto struct scnhdr f_thdr; /* Text section header */ ! 255: auto struct scnhdr f_dhdr; /* Data section header */ ! 256: auto struct scnhdr f_bhdr; /* Bss section header */ ! 257: auto struct scnhdr scntemp; /* Temporary section header */ ! 258: register int scns; ! 259: ! 260: /* Salvage as much info from the existing file as possible */ ! 261: if (a_out >= 0) ! 262: { ! 263: if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) ! 264: { ! 265: PERROR (a_name); ! 266: } ! 267: block_copy_start += sizeof (f_hdr); ! 268: if (f_hdr.f_opthdr > 0) ! 269: { ! 270: if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) ! 271: { ! 272: PERROR (a_name); ! 273: } ! 274: block_copy_start += sizeof (f_ohdr); ! 275: } ! 276: /* Loop through section headers, copying them in */ ! 277: for (scns = f_hdr.f_nscns; scns > 0; scns--) { ! 278: if (read (a_out, &scntemp, sizeof (scntemp)) != sizeof (scntemp)) ! 279: { ! 280: PERROR (a_name); ! 281: } ! 282: block_copy_start += sizeof (scntemp); ! 283: if (scntemp.s_scnptr > 0L) ! 284: { ! 285: block_copy_start += scntemp.s_size; ! 286: } ! 287: if (strcmp (scntemp.s_name, ".text") == 0) ! 288: { ! 289: f_thdr = scntemp; ! 290: } ! 291: else if (strcmp (scntemp.s_name, ".data") == 0) ! 292: { ! 293: f_dhdr = scntemp; ! 294: } ! 295: else if (strcmp (scntemp.s_name, ".bss") == 0) ! 296: { ! 297: f_bhdr = scntemp; ! 298: } ! 299: } ! 300: } ! 301: else ! 302: { ! 303: ERROR0 ("can't build a COFF file from scratch yet"); ! 304: } ! 305: ! 306: pagemask = getpagesize () - 1; ! 307: ! 308: #ifdef NO_REMAP ! 309: data_start = (int) start_of_data (); ! 310: #else /* not NO_REMAP */ ! 311: if (!data_start) ! 312: data_start = (int) start_of_data (); ! 313: #endif /* not NO_REMAP */ ! 314: data_start = ADDR_CORRECT (data_start); ! 315: data_start = data_start & ~pagemask; /* down to a page boundary */ ! 316: ! 317: f_hdr.f_flags |= (F_RELFLG | F_EXEC); ! 318: #ifdef EXEC_MAGIC ! 319: f_ohdr.magic = EXEC_MAGIC; ! 320: #endif ! 321: f_ohdr.text_start = (long) start_of_text (); ! 322: f_ohdr.tsize = data_start - f_ohdr.text_start; ! 323: f_ohdr.data_start = data_start; ! 324: f_ohdr.dsize = (long) sbrk (0) - f_ohdr.data_start; ! 325: f_ohdr.bsize = 0; ! 326: f_thdr.s_size = f_ohdr.tsize; ! 327: f_thdr.s_scnptr = sizeof (f_hdr) + sizeof (f_ohdr); ! 328: f_thdr.s_scnptr += (f_hdr.f_nscns) * (sizeof (f_thdr)); ! 329: lnnoptr = f_thdr.s_lnnoptr; ! 330: #ifdef UMAX ! 331: /* Umax is bsd using coff; it has restrictions on alignment ! 332: of the sections in the file itself. */ ! 333: f_thdr.s_scnptr = (f_thdr.s_scnptr + pagemask) & ~pagemask; /* round up */ ! 334: #endif /* UMAX */ ! 335: text_scnptr = f_thdr.s_scnptr; ! 336: f_dhdr.s_paddr = f_ohdr.data_start; ! 337: f_dhdr.s_vaddr = f_ohdr.data_start; ! 338: f_dhdr.s_size = f_ohdr.dsize; ! 339: f_dhdr.s_scnptr = f_thdr.s_scnptr + f_thdr.s_size; ! 340: #ifdef UMAX ! 341: f_dhdr.s_scnptr &= ~pagemask; /* round down to page boundary */ ! 342: #endif /* UMAX */ ! 343: f_bhdr.s_paddr = f_ohdr.data_start + f_ohdr.dsize; ! 344: f_bhdr.s_vaddr = f_ohdr.data_start + f_ohdr.dsize; ! 345: f_bhdr.s_size = f_ohdr.bsize; ! 346: f_bhdr.s_scnptr = 0L; ! 347: bias = f_dhdr.s_scnptr + f_dhdr.s_size - block_copy_start; ! 348: ! 349: if (f_hdr.f_symptr > 0L) ! 350: { ! 351: f_hdr.f_symptr += bias; ! 352: } ! 353: ! 354: if (f_thdr.s_lnnoptr > 0L) ! 355: { ! 356: f_thdr.s_lnnoptr += bias; ! 357: } ! 358: ! 359: if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) ! 360: { ! 361: PERROR (new_name); ! 362: } ! 363: ! 364: if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) ! 365: { ! 366: PERROR (new_name); ! 367: } ! 368: ! 369: if (write (new, &f_thdr, sizeof (f_thdr)) != sizeof (f_thdr)) ! 370: { ! 371: PERROR (new_name); ! 372: } ! 373: ! 374: if (write (new, &f_dhdr, sizeof (f_dhdr)) != sizeof (f_dhdr)) ! 375: { ! 376: PERROR (new_name); ! 377: } ! 378: ! 379: if (write (new, &f_bhdr, sizeof (f_bhdr)) != sizeof (f_bhdr)) ! 380: { ! 381: PERROR (new_name); ! 382: } ! 383: return (0); ! 384: ! 385: #else /* if not COFF */ ! 386: ! 387: /* Get symbol table info from header of a.out file if given one. */ ! 388: if (a_out >= 0) ! 389: { ! 390: if (read (a_out, &ohdr, sizeof hdr) != sizeof hdr) ! 391: { ! 392: PERROR (a_name); ! 393: } ! 394: ! 395: if N_BADMAG (ohdr) ! 396: { ! 397: ERROR1 ("invalid magic number in %s", a_name); ! 398: } ! 399: #ifdef celerity ! 400: hdr.a_scovrfl = ohdr.a_scovrfl; ! 401: #endif ! 402: #ifdef HPUX ! 403: hdr.a_lesyms = ohdr.a_lesyms; ! 404: hdr.a_sltsize = ohdr.a_sltsize; ! 405: hdr.a_dnttsize = ohdr.a_dnttsize; ! 406: hdr.a_vtsize = ohdr.a_vtsize; ! 407: #else /* not HPUX */ ! 408: hdr.a_syms = ohdr.a_syms; ! 409: #endif /* not HPUX */ ! 410: } ! 411: else ! 412: { ! 413: #ifdef celerity ! 414: hdr.a_scovrfl = 0; ! 415: #endif ! 416: #ifdef HPUX ! 417: hdr.a_lesyms = 0; ! 418: hdr.a_sltsize = 0; ! 419: hdr.a_dnttsize = 0; ! 420: hdr.a_vtsize = 0; ! 421: #else /* not HPUX */ ! 422: hdr.a_syms = 0; /* No a.out, so no symbol info. */ ! 423: #endif /* not HPUX */ ! 424: } ! 425: ! 426: /* Construct header from user structure. */ ! 427: #ifdef HPUX ! 428: /* (((MAGIC) ohdr.a_magic) == ((MAGIC) OLDMAGIC)) This does not work */ ! 429: hdr.a_magic = ((ohdr.a_magic.file_type == OLDMAGIC.file_type) ? ! 430: NEWMAGIC : ohdr.a_magic); ! 431: #else /* not HPUX */ ! 432: /* hdr.a_magic = NEWMAGIC; */ ! 433: hdr.a_magic = ohdr.a_magic; ! 434: #endif /* not HPUX */ ! 435: ! 436: #ifdef sun3 ! 437: hdr.a_machtype = ohdr.a_machtype; ! 438: #endif /* sun3 */ ! 439: hdr.a_trsize = 0; ! 440: hdr.a_drsize = 0; ! 441: hdr.a_entry = entry_address; ! 442: ! 443: pagemask = getpagesize () - 1; ! 444: ! 445: /* Adjust data/bss boundary. */ ! 446: if (bss_start != 0) ! 447: { ! 448: bss_start = (ADDR_CORRECT (bss_start) + pagemask) & ~pagemask; /* (Up) to page bdry. */ ! 449: if (bss_start > ADDR_CORRECT (sbrk (0))) ! 450: { ! 451: ERROR1 ("unexec: Specified bss_start (%u) is past end of program", ! 452: bss_start); ! 453: } ! 454: } ! 455: else ! 456: { ! 457: bss_start = ADDR_CORRECT (sbrk (0)); ! 458: bss_start = (bss_start + pagemask) & ~pagemask; ! 459: } ! 460: ! 461: /* Adjust text/data boundary. */ ! 462: #ifdef NO_REMAP ! 463: data_start = (int) start_of_data (); ! 464: #else /* not NO_REMAP */ ! 465: if (!data_start) ! 466: data_start = (int) start_of_data (); ! 467: #endif /* not NO_REMAP */ ! 468: data_start = ADDR_CORRECT (data_start); ! 469: ! 470: #ifdef sun ! 471: data_start = data_start & ~(SEGSIZ - 1); /* (Down) to segment boundary. */ ! 472: #else ! 473: data_start = data_start & ~pagemask; /* (Down) to page boundary. */ ! 474: #endif ! 475: ! 476: if (data_start > bss_start) /* Can't have negative data size. */ ! 477: { ! 478: ERROR2 ("unexec: data_start (%u) can't be greater than bss_start (%u)", ! 479: data_start, bss_start); ! 480: } ! 481: ! 482: tem = ADDR_CORRECT (sbrk (0)); ! 483: hdr.a_bss = tem - bss_start; ! 484: if (tem < bss_start) /* Note a_bss is unsigned on some systems */ ! 485: hdr.a_bss = 0; ! 486: hdr.a_data = bss_start - data_start; ! 487: #if defined(sequent) ! 488: hdr.a_text = data_start - (long) start_of_text () + sizeof(hdr) + N_ADDRADJ(ohdr); ! 489: #else ! 490: hdr.a_text = data_start - (long) start_of_text (); ! 491: #endif /* not sequent */ ! 492: ! 493: if (write (new, &hdr, sizeof hdr) != sizeof hdr) ! 494: { ! 495: PERROR (new_name); ! 496: } ! 497: return 0; ! 498: ! 499: #endif /* not COFF */ ! 500: } ! 501: ! 502: /* **************************************************************** ! 503: * copy_text_and_data ! 504: * ! 505: * Copy the text and data segments from memory to the new a.out ! 506: */ ! 507: static int ! 508: copy_text_and_data (new) ! 509: int new; ! 510: { ! 511: register int nwrite, ret; ! 512: register char *end; ! 513: int i; ! 514: register char *ptr; ! 515: char buf[80]; ! 516: extern int errno; ! 517: ! 518: #ifdef COFF ! 519: lseek (new, (long) text_scnptr, 0); ! 520: ptr = (char *) f_ohdr.text_start; ! 521: end = ptr + f_ohdr.tsize + f_ohdr.dsize; ! 522: while (ptr < end) ! 523: { ! 524: nwrite = 128; ! 525: if (nwrite > end - ptr) nwrite = end - ptr; ! 526: ret = write (new, ptr, nwrite); ! 527: if (nwrite != ret) ! 528: { ! 529: sprintf (buf, ! 530: "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", ! 531: ptr, new, nwrite, ret, errno); ! 532: PERROR (buf); ! 533: } ! 534: ptr += nwrite; ! 535: } ! 536: return (0); ! 537: ! 538: #else /* if not COFF */ ! 539: ! 540: #if defined(sun3) || defined(sequent) ! 541: lseek (new, (long) (N_TXTOFF (hdr) + sizeof (hdr)), 0); ! 542: #else ! 543: lseek (new, (long) N_TXTOFF (hdr), 0); ! 544: #endif ! 545: ! 546: ptr = start_of_text (); ! 547: end = ptr + hdr.a_text + hdr.a_data; ! 548: #if defined(sequent) ! 549: end -= (sizeof(hdr) + N_ADDRADJ(hdr)); ! 550: #endif ! 551: for (i = 0; ptr < end;) ! 552: { ! 553: nwrite = 128; ! 554: if (nwrite > end - ptr) nwrite = end - ptr; ! 555: ret = write (new, ptr, nwrite); ! 556: if (ret == -1 && errno == EFAULT) ! 557: { ! 558: /* BZS - again, see above about N_TXTOFF on a SUN */ ! 559: #if defined(sun3) || defined(sequent) ! 560: lseek (new, (long) (N_TXTOFF (hdr) + i + nwrite + sizeof (hdr)), 0); ! 561: #else ! 562: lseek (new, (long) (N_TXTOFF (hdr) + i + nwrite), 0); ! 563: #endif ! 564: } ! 565: else if (nwrite != ret) ! 566: { ! 567: sprintf (buf, ! 568: "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d", ! 569: ptr, new, nwrite, ret, errno); ! 570: PERROR (buf); ! 571: } ! 572: i += nwrite; ! 573: ptr += nwrite; ! 574: } ! 575: ! 576: return 0; ! 577: #endif /* not COFF */ ! 578: } ! 579: ! 580: /* **************************************************************** ! 581: * copy_sym ! 582: * ! 583: * Copy the relocation information and symbol table from the a.out to the new ! 584: */ ! 585: static int ! 586: copy_sym (new, a_out, a_name, new_name) ! 587: int new, a_out; ! 588: char *a_name, *new_name; ! 589: { ! 590: char page[1024]; ! 591: int n; ! 592: ! 593: if (a_out < 0) ! 594: return 0; ! 595: ! 596: #ifdef COFF ! 597: if (SYMS_START == 0L) ! 598: return 0; ! 599: #endif /* COFF */ ! 600: ! 601: #ifdef sun3 ! 602: /* BZS - I might be covering a sin with this */ ! 603: lseek (new, N_SYMOFF (hdr), 0); ! 604: #else ! 605: #ifdef COFF ! 606: if (lnnoptr) /* if there is line number info */ ! 607: lseek (a_out, lnnoptr, 0); /* start copying from there */ ! 608: else ! 609: #endif /* COFF */ ! 610: lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */ ! 611: #endif ! 612: while ((n = read (a_out, page, sizeof page)) > 0) ! 613: { ! 614: if (write (new, page, n) != n) ! 615: { ! 616: PERROR (new_name); ! 617: } ! 618: } ! 619: if (n < 0) ! 620: { ! 621: PERROR (a_name); ! 622: } ! 623: return 0; ! 624: } ! 625: ! 626: /* **************************************************************** ! 627: * mark_x ! 628: * ! 629: * After succesfully building the new a.out, mark it executable ! 630: */ ! 631: static ! 632: mark_x (name) ! 633: char *name; ! 634: { ! 635: struct stat sbuf; ! 636: int um; ! 637: int new = 0; /* for PERROR */ ! 638: ! 639: um = umask (777); ! 640: umask (um); ! 641: if (stat (name, &sbuf) == -1) ! 642: { ! 643: PERROR (name); ! 644: } ! 645: sbuf.st_mode |= 0111 & ~um; ! 646: if (chmod (name, sbuf.st_mode) == -1) ! 647: PERROR (name); ! 648: } ! 649: ! 650: /* ! 651: * If the COFF file contains a symbol table and a line number section, ! 652: * then any auxiliary entries that have values for x_lnnoptr must ! 653: * be adjusted by the amount that the line number section has moved ! 654: * in the file (bias computed in make_hdr). The #@$%&* designers of ! 655: * the auxiliary entry structures used the absolute file offsets for ! 656: * the line number entry rather than an offset from the start of the ! 657: * line number section! ! 658: * ! 659: * When I figure out how to scan through the symbol table and pick out ! 660: * the auxiliary entries that need adjustment, this routine will ! 661: * be fixed. As it is now, all such entries are wrong and sdb ! 662: * will complain. Fred Fish, UniSoft Systems Inc. ! 663: */ ! 664: ! 665: #ifdef COFF ! 666: ! 667: /* This function is probably very slow. Instead of reopening the new ! 668: file for input and output it should copy from the old to the new ! 669: using the two descriptors already open (WRITEDESC and READDESC). ! 670: Instead of reading one small structure at a time it should use ! 671: a reasonable size buffer. But I don't have time to work on such ! 672: things, so I am installing it as submitted to me. -- RMS. */ ! 673: ! 674: adjust_lnnoptrs (writedesc, readdesc, new_name) ! 675: int writedesc; ! 676: int readdesc; ! 677: char *new_name; ! 678: { ! 679: register int nsyms; ! 680: register int new; ! 681: struct syment symentry; ! 682: struct auxent auxentry; ! 683: ! 684: if (!lnnoptr || !f_hdr.f_symptr) ! 685: return 0; ! 686: ! 687: if ((new = open (new_name, 2)) < 0) ! 688: { ! 689: PERROR (new_name); ! 690: return -1; ! 691: } ! 692: ! 693: lseek (new, f_hdr.f_symptr, 0); ! 694: for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++) ! 695: { ! 696: read (new, &symentry, SYMESZ); ! 697: if (symentry.n_numaux) ! 698: { ! 699: read (new, &auxentry, AUXESZ); ! 700: nsyms++; ! 701: if (ISFCN (symentry.n_type)) { ! 702: auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias; ! 703: lseek (new, -AUXESZ, 1); ! 704: write (new, &auxentry, AUXESZ); ! 705: } ! 706: } ! 707: } ! 708: close (new); ! 709: } ! 710: ! 711: #endif /* COFF */ ! 712: ! 713: #endif /* not CANNOT_DUMP */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.