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 */

Defined functions

adjust_lnnoptrs defined in line 674; used 1 times
copy_sym defined in line 585; used 1 times
copy_text_and_data defined in line 507; used 1 times
make_hdr defined in line 245; used 1 times
mark_x defined in line 631; used 1 times
report_error defined in line 170; used 1 times
  • in line 69
report_error_1 defined in line 185; used 3 times
unexec defined in line 205; used 1 times

Defined variables

bias defined in line 93; used 4 times
block_copy_start defined in line 90; used 6 times
f_hdr defined in line 91; used 17 times
f_ohdr defined in line 92; used 28 times
hdr defined in line 136; used 40 times
lnnoptr defined in line 94; used 4 times
ohdr defined in line 136; used 14 times
pagemask defined in line 143; used 11 times
text_scnptr defined in line 97; used 2 times

Defined macros

ADDR_CORRECT defined in line 165; used 7 times
CLSIZE defined in line 152; used 2 times
ERROR0 defined in line 181; used 1 times
ERROR1 defined in line 182; used 2 times
ERROR2 defined in line 183; used 1 times
MY_ID defined in line 111; used 2 times
NEWMAGIC defined in line 137; used 2 times
N_BADMAG defined in line 131; used 1 times
N_SYMOFF defined in line 116; used 2 times
N_TXTOFF defined in line 115; used 4 times
PERROR defined in line 69; used 19 times
SYMS_START defined in line 104; used 2 times
a_bss defined in line 126; used 2 times
a_data defined in line 125; used 2 times
a_drsize defined in line 129; used 1 times
a_entry defined in line 130; used 1 times
a_magic defined in line 123; used 5 times
a_syms defined in line 127; used 3 times
a_text defined in line 124; used 3 times
a_trsize defined in line 128; used 1 times
getpagesize defined in line 155; used 2 times
Last modified: 1986-03-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2098
Valid CSS Valid XHTML 1.0 Strict