Annotation of GNUtools/emacs/src/unexelf.c, revision 1.1.1.1

1.1       root        1: /* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
                      2: 
                      3:     This program is free software; you can redistribute it and/or modify
                      4:     it under the terms of the GNU General Public License as published by
                      5:     the Free Software Foundation; either version 1, or (at your option)
                      6:     any later version.
                      7: 
                      8:     This program is distributed in the hope that it will be useful,
                      9:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     10:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     11:     GNU General Public License for more details.
                     12: 
                     13:     You should have received a copy of the GNU General Public License
                     14:     along with this program; if not, write to the Free Software
                     15:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     16: 
                     17: In other words, you are welcome to use, share and improve this program.
                     18: You are forbidden to forbid anyone else to use, share and improve
                     19: what you give them.   Help stamp out software-hoarding!  */
                     20: 
                     21: 
                     22: /*
                     23:  * unexec.c - Convert a running program into an a.out file.
                     24:  *
                     25:  * Author:     Spencer W. Thomas
                     26:  *             Computer Science Dept.
                     27:  *             University of Utah
                     28:  * Date:       Tue Mar  2 1982
                     29:  * Modified heavily since then.
                     30:  *
                     31:  * Synopsis:
                     32:  *     unexec (new_name, a_name, data_start, bss_start, entry_address)
                     33:  *     char *new_name, *a_name;
                     34:  *     unsigned data_start, bss_start, entry_address;
                     35:  *
                     36:  * Takes a snapshot of the program and makes an a.out format file in the
                     37:  * file named by the string argument new_name.
                     38:  * If a_name is non-NULL, the symbol table will be taken from the given file.
                     39:  * On some machines, an existing a_name file is required.
                     40:  *
                     41:  * The boundaries within the a.out file may be adjusted with the data_start
                     42:  * and bss_start arguments.  Either or both may be given as 0 for defaults.
                     43:  *
                     44:  * Data_start gives the boundary between the text segment and the data
                     45:  * segment of the program.  The text segment can contain shared, read-only
                     46:  * program code and literal data, while the data segment is always unshared
                     47:  * and unprotected.  Data_start gives the lowest unprotected address.
                     48:  * The value you specify may be rounded down to a suitable boundary
                     49:  * as required by the machine you are using.
                     50:  *
                     51:  * Specifying zero for data_start means the boundary between text and data
                     52:  * should not be the same as when the program was loaded.
                     53:  * If NO_REMAP is defined, the argument data_start is ignored and the
                     54:  * segment boundaries are never changed.
                     55:  *
                     56:  * Bss_start indicates how much of the data segment is to be saved in the
                     57:  * a.out file and restored when the program is executed.  It gives the lowest
                     58:  * unsaved address, and is rounded up to a page boundary.  The default when 0
                     59:  * is given assumes that the entire data segment is to be stored, including
                     60:  * the previous data and bss as well as any additional storage allocated with
                     61:  * break (2).
                     62:  *
                     63:  * The new file is set up to start at entry_address.
                     64:  *
                     65:  * If you make improvements I'd like to get them too.
                     66:  * harpo!utah-cs!thomas, thomas@Utah-20
                     67:  *
                     68:  */
                     69: 
                     70: /* Even more heavily modified by [email protected] of Dell Computer Co.
                     71:  * ELF support added.
                     72:  *
                     73:  * Basic theory: the data space of the running process needs to be
                     74:  * dumped to the output file.  Normally we would just enlarge the size
                     75:  * of .data, scooting everything down.  But we can't do that in ELF,
                     76:  * because there is often something between the .data space and the
                     77:  * .bss space.
                     78:  *
                     79:  * In the temacs dump below, notice that the Global Offset Table
                     80:  * (.got) and the Dynamic link data (.dynamic) come between .data1 and
                     81:  * .bss.  It does not work to overlap .data with these fields.
                     82:  *
                     83:  * The solution is to create a new .data segment.  This segment is
                     84:  * filled with data from the current process.  Since the contents of
                     85:  * various sections refer to sections by index, the new .data segment
                     86:  * is made the last in the table to avoid changing any existing index.
                     87: 
                     88:  * This is an example of how the section headers are changed.  "Addr"
                     89:  * is a process virtual address.  "Offset" is a file offset.
                     90: 
                     91: raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
                     92: 
                     93: temacs:
                     94: 
                     95:            **** SECTION HEADER TABLE ****
                     96: [No]    Type    Flags   Addr         Offset       Size          Name
                     97:         Link    Info    Adralgn      Entsize
                     98: 
                     99: [1]     1       2       0x80480d4    0xd4         0x13          .interp
                    100:         0       0       0x1          0            
                    101: 
                    102: [2]     5       2       0x80480e8    0xe8         0x388         .hash
                    103:         3       0       0x4          0x4          
                    104: 
                    105: [3]     11      2       0x8048470    0x470        0x7f0         .dynsym
                    106:         4       1       0x4          0x10         
                    107: 
                    108: [4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
                    109:         0       0       0x1          0            
                    110: 
                    111: [5]     9       2       0x8049010    0x1010       0x338         .rel.plt
                    112:         3       7       0x4          0x8          
                    113: 
                    114: [6]     1       6       0x8049348    0x1348       0x3           .init
                    115:         0       0       0x4          0            
                    116: 
                    117: [7]     1       6       0x804934c    0x134c       0x680         .plt
                    118:         0       0       0x4          0x4          
                    119: 
                    120: [8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
                    121:         0       0       0x4          0            
                    122: 
                    123: [9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
                    124:         0       0       0x4          0            
                    125: 
                    126: [10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
                    127:         0       0       0x4          0            
                    128: 
                    129: [11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
                    130:         0       0       0x4          0            
                    131: 
                    132: [12]    1       3       0x8088330    0x3f330      0x20afc       .data
                    133:         0       0       0x4          0            
                    134: 
                    135: [13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
                    136:         0       0       0x4          0            
                    137: 
                    138: [14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
                    139:         0       0       0x4          0x4          
                    140: 
                    141: [15]    6       3       0x80a9874    0x60874      0x80          .dynamic
                    142:         4       0       0x4          0x8          
                    143: 
                    144: [16]    8       3       0x80a98f4    0x608f4      0x449c        .bss
                    145:         0       0       0x4          0            
                    146: 
                    147: [17]    2       0       0            0x608f4      0x9b90        .symtab
                    148:         18      371     0x4          0x10         
                    149: 
                    150: [18]    3       0       0            0x6a484      0x8526        .strtab
                    151:         0       0       0x1          0            
                    152: 
                    153: [19]    3       0       0            0x729aa      0x93          .shstrtab
                    154:         0       0       0x1          0            
                    155: 
                    156: [20]    1       0       0            0x72a3d      0x68b7        .comment
                    157:         0       0       0x1          0            
                    158: 
                    159: raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
                    160: 
                    161: xemacs:
                    162: 
                    163:            **** SECTION HEADER TABLE ****
                    164: [No]    Type    Flags   Addr         Offset       Size          Name
                    165:         Link    Info    Adralgn      Entsize
                    166: 
                    167: [1]     1       2       0x80480d4    0xd4         0x13          .interp
                    168:         0       0       0x1          0            
                    169: 
                    170: [2]     5       2       0x80480e8    0xe8         0x388         .hash
                    171:         3       0       0x4          0x4          
                    172: 
                    173: [3]     11      2       0x8048470    0x470        0x7f0         .dynsym
                    174:         4       1       0x4          0x10         
                    175: 
                    176: [4]     3       2       0x8048c60    0xc60        0x3ad         .dynstr
                    177:         0       0       0x1          0            
                    178: 
                    179: [5]     9       2       0x8049010    0x1010       0x338         .rel.plt
                    180:         3       7       0x4          0x8          
                    181: 
                    182: [6]     1       6       0x8049348    0x1348       0x3           .init
                    183:         0       0       0x4          0            
                    184: 
                    185: [7]     1       6       0x804934c    0x134c       0x680         .plt
                    186:         0       0       0x4          0x4          
                    187: 
                    188: [8]     1       6       0x80499cc    0x19cc       0x3c56f       .text
                    189:         0       0       0x4          0            
                    190: 
                    191: [9]     1       6       0x8085f3c    0x3df3c      0x3           .fini
                    192:         0       0       0x4          0            
                    193: 
                    194: [10]    1       2       0x8085f40    0x3df40      0x69c         .rodata
                    195:         0       0       0x4          0            
                    196: 
                    197: [11]    1       2       0x80865dc    0x3e5dc      0xd51         .rodata1
                    198:         0       0       0x4          0            
                    199: 
                    200: [12]    1       3       0x8088330    0x3f330      0x20afc       .data
                    201:         0       0       0x4          0            
                    202: 
                    203: [13]    1       3       0x80a8e2c    0x5fe2c      0x89d         .data1
                    204:         0       0       0x4          0            
                    205: 
                    206: [14]    1       3       0x80a96cc    0x606cc      0x1a8         .got
                    207:         0       0       0x4          0x4          
                    208: 
                    209: [15]    6       3       0x80a9874    0x60874      0x80          .dynamic
                    210:         4       0       0x4          0x8          
                    211: 
                    212: [16]    8       3       0x80c6800    0x7d800      0             .bss
                    213:         0       0       0x4          0            
                    214: 
                    215: [17]    2       0       0            0x7d800      0x9b90        .symtab
                    216:         18      371     0x4          0x10         
                    217: 
                    218: [18]    3       0       0            0x87390      0x8526        .strtab
                    219:         0       0       0x1          0            
                    220: 
                    221: [19]    3       0       0            0x8f8b6      0x93          .shstrtab
                    222:         0       0       0x1          0            
                    223: 
                    224: [20]    1       0       0            0x8f949      0x68b7        .comment
                    225:         0       0       0x1          0            
                    226: 
                    227: [21]    1       3       0x80a98f4    0x608f4      0x1cf0c       .data
                    228:         0       0       0x4          0            
                    229: 
                    230:  * This is an example of how the file header is changed.  "Shoff" is
                    231:  * the section header offset within the file.  Since that table is
                    232:  * after the new .data section, it is moved.  "Shnum" is the number of
                    233:  * sections, which we increment.
                    234:  *
                    235:  * "Phoff" is the file offset to the program header.  "Phentsize" and
                    236:  * "Shentsz" are the program and section header entries sizes respectively.
                    237:  * These can be larger than the apparent struct sizes.
                    238: 
                    239: raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
                    240: 
                    241: temacs:
                    242: 
                    243:                     **** ELF HEADER ****
                    244: Class        Data       Type         Machine     Version
                    245: Entry        Phoff      Shoff        Flags       Ehsize
                    246: Phentsize    Phnum      Shentsz      Shnum       Shstrndx
                    247: 
                    248: 1            1          2            3           1
                    249: 0x80499cc    0x34       0x792f4      0           0x34
                    250: 0x20         5          0x28         21          19
                    251: 
                    252: raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
                    253: 
                    254: xemacs:
                    255: 
                    256:                     **** ELF HEADER ****
                    257: Class        Data       Type         Machine     Version
                    258: Entry        Phoff      Shoff        Flags       Ehsize
                    259: Phentsize    Phnum      Shentsz      Shnum       Shstrndx
                    260: 
                    261: 1            1          2            3           1
                    262: 0x80499cc    0x34       0x96200      0           0x34
                    263: 0x20         5          0x28         22          19
                    264: 
                    265:  * These are the program headers.  "Offset" is the file offset to the
                    266:  * segment.  "Vaddr" is the memory load address.  "Filesz" is the
                    267:  * segment size as it appears in the file, and "Memsz" is the size in
                    268:  * memory.  Below, the third segment is the code and the fourth is the
                    269:  * data: the difference between Filesz and Memsz is .bss
                    270: 
                    271: raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
                    272: 
                    273: temacs:
                    274:  ***** PROGRAM EXECUTION HEADER *****
                    275: Type        Offset      Vaddr       Paddr
                    276: Filesz      Memsz       Flags       Align
                    277: 
                    278: 6           0x34        0x8048034   0           
                    279: 0xa0        0xa0        5           0           
                    280: 
                    281: 3           0xd4        0           0           
                    282: 0x13        0           4           0           
                    283: 
                    284: 1           0x34        0x8048034   0           
                    285: 0x3f2f9     0x3f2f9     5           0x1000      
                    286: 
                    287: 1           0x3f330     0x8088330   0           
                    288: 0x215c4     0x25a60     7           0x1000      
                    289: 
                    290: 2           0x60874     0x80a9874   0           
                    291: 0x80        0           7           0           
                    292: 
                    293: raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
                    294: 
                    295: xemacs:
                    296:  ***** PROGRAM EXECUTION HEADER *****
                    297: Type        Offset      Vaddr       Paddr
                    298: Filesz      Memsz       Flags       Align
                    299: 
                    300: 6           0x34        0x8048034   0           
                    301: 0xa0        0xa0        5           0           
                    302: 
                    303: 3           0xd4        0           0           
                    304: 0x13        0           4           0           
                    305: 
                    306: 1           0x34        0x8048034   0           
                    307: 0x3f2f9     0x3f2f9     5           0x1000      
                    308: 
                    309: 1           0x3f330     0x8088330   0           
                    310: 0x3e4d0     0x3e4d0     7           0x1000      
                    311: 
                    312: 2           0x60874     0x80a9874   0           
                    313: 0x80        0           7           0           
                    314: 
                    315: 
                    316:  */
                    317: 
                    318: #include <sys/types.h>
                    319: #include <stdio.h>
                    320: #include <sys/stat.h>
                    321: #include <memory.h>
                    322: #include <string.h>
                    323: #include <errno.h>
                    324: #include <unistd.h>
                    325: #include <fcntl.h>
                    326: #include <elf.h>
                    327: #include <sys/mman.h>
                    328: 
                    329: #ifndef emacs
                    330: #define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1)
                    331: #else
                    332: extern void fatal(char *, ...);
                    333: #endif
                    334: 
                    335: /* Get the address of a particular section or program header entry,
                    336:  * accounting for the size of the entries.
                    337:  */
                    338: 
                    339: #define OLD_SECTION_H(n) \
                    340:      (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
                    341: #define NEW_SECTION_H(n) \
                    342:      (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
                    343: #define OLD_PROGRAM_H(n) \
                    344:      (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
                    345: #define NEW_PROGRAM_H(n) \
                    346:      (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
                    347: 
                    348: typedef unsigned char byte;
                    349: 
                    350: /* Round X up to a multiple of Y.  */
                    351: 
                    352: int
                    353: round_up (x, y)
                    354:      int x, y;
                    355: {
                    356:   int rem = x % y;
                    357:   if (rem == 0)
                    358:     return x;
                    359:   return x - rem + y;
                    360: }
                    361: 
                    362: /* ****************************************************************
                    363:  * unexec
                    364:  *
                    365:  * driving logic.
                    366:  *
                    367:  * In ELF, this works by replacing the old .bss section with a new
                    368:  * .data section, and inserting an empty .bss immediately afterwards.
                    369:  *
                    370:  */
                    371: void
                    372: unexec (new_name, old_name, data_start, bss_start, entry_address)
                    373:      char *new_name, *old_name;
                    374:      unsigned data_start, bss_start, entry_address;
                    375: {
                    376:   extern unsigned int bss_end;
                    377:   int new_file, old_file, new_file_size;
                    378: 
                    379:   /* Pointers to the base of the image of the two files. */
                    380:   caddr_t old_base, new_base;
                    381: 
                    382:   /* Pointers to the file, program and section headers for the old and new
                    383:    * files.
                    384:    */
                    385:   Elf32_Ehdr *old_file_h, *new_file_h;
                    386:   Elf32_Phdr *old_program_h, *new_program_h;
                    387:   Elf32_Shdr *old_section_h, *new_section_h;
                    388: 
                    389:   /* Point to the section name table in the old file */
                    390:   char *old_section_names;
                    391: 
                    392:   Elf32_Addr old_bss_addr, new_bss_addr;
                    393:   Elf32_Word old_bss_size, new_data2_size;
                    394:   Elf32_Off  new_data2_offset;
                    395:   Elf32_Addr new_data2_addr;
                    396: 
                    397:   int n, old_bss_index, old_data_index, new_data2_index;
                    398:   struct stat stat_buf;
                    399: 
                    400:   /* Open the old file & map it into the address space. */
                    401: 
                    402:   old_file = open (old_name, O_RDONLY);
                    403: 
                    404:   if (old_file < 0)
                    405:     fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
                    406: 
                    407:   if (fstat (old_file, &stat_buf) == -1)
                    408:     fatal ("Can't fstat(%s): errno %d\n", old_name, errno);
                    409: 
                    410:   old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
                    411: 
                    412:   if (old_base == (caddr_t) -1)
                    413:     fatal ("Can't mmap(%s): errno %d\n", old_name, errno);
                    414: 
                    415: #ifdef DEBUG
                    416:   fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size,
                    417:           old_base);
                    418: #endif
                    419: 
                    420:   /* Get pointers to headers & section names */
                    421: 
                    422:   old_file_h = (Elf32_Ehdr *) old_base;
                    423:   old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
                    424:   old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
                    425:   old_section_names = (char *) old_base
                    426:     + OLD_SECTION_H(old_file_h->e_shstrndx).sh_offset;
                    427: 
                    428:   /* Find the old .bss section.  Figure out parameters of the new
                    429:    * data2 and bss sections.
                    430:    */
                    431: 
                    432:   for (old_bss_index = 1; old_bss_index < old_file_h->e_shnum; old_bss_index++)
                    433:     {
                    434: #ifdef DEBUG
                    435:       fprintf (stderr, "Looking for .bss - found %s\n",
                    436:               old_section_names + OLD_SECTION_H(old_bss_index).sh_name);
                    437: #endif
                    438:       if (!strcmp (old_section_names + OLD_SECTION_H(old_bss_index).sh_name,
                    439:                   ".bss"))
                    440:        break;
                    441:     }
                    442:   if (old_bss_index == old_file_h->e_shnum)
                    443:     fatal ("Can't find .bss in %s.\n", old_name, 0);
                    444: 
                    445:   old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr;
                    446:   old_bss_size = OLD_SECTION_H(old_bss_index).sh_size;
                    447: #if defined(emacs) || !defined(DEBUG)
                    448:   bss_end = (unsigned int) sbrk (0);
                    449:   new_bss_addr = (Elf32_Addr) bss_end;
                    450: #else
                    451:   new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
                    452: #endif
                    453:   new_data2_addr = old_bss_addr;
                    454:   new_data2_size = new_bss_addr - old_bss_addr;
                    455:   new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset;
                    456: 
                    457: #ifdef DEBUG
                    458:   fprintf (stderr, "old_bss_index %d\n", old_bss_index);
                    459:   fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
                    460:   fprintf (stderr, "old_bss_size %x\n", old_bss_size);
                    461:   fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
                    462:   fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
                    463:   fprintf (stderr, "new_data2_size %x\n", new_data2_size);
                    464:   fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
                    465: #endif
                    466: 
                    467:   if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
                    468:     fatal (".bss shrank when undumping???\n", 0, 0);
                    469: 
                    470:   /* Set the output file to the right size and mmap(2) it.  Set
                    471:    * pointers to various interesting objects.  stat_buf still has
                    472:    * old_file data.
                    473:    */
                    474: 
                    475:   new_file = open (new_name, O_RDWR | O_CREAT, 0666);
                    476:   if (new_file < 0)
                    477:     fatal ("Can't creat(%s): errno %d\n", new_name, errno);
                    478: 
                    479:   new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
                    480: 
                    481:   if (ftruncate (new_file, new_file_size))
                    482:     fatal ("Can't ftruncate(%s): errno %d\n", new_name, errno);
                    483: 
                    484:   new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
                    485:                   new_file, 0);
                    486: 
                    487:   if (new_base == (caddr_t) -1)
                    488:     fatal ("Can't mmap(%s): errno %d\n", new_name, errno);
                    489: 
                    490:   new_file_h = (Elf32_Ehdr *) new_base;
                    491:   new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
                    492:   new_section_h = (Elf32_Shdr *)
                    493:     ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
                    494: 
                    495:   /* Make our new file, program and section headers as copies of the
                    496:    * originals.
                    497:    */
                    498: 
                    499:   memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
                    500:   memcpy (new_program_h, old_program_h,
                    501:          old_file_h->e_phnum * old_file_h->e_phentsize);
                    502:   memcpy (new_section_h, old_section_h,
                    503:          old_file_h->e_shnum * old_file_h->e_shentsize);
                    504: 
                    505:   /* Fix up file header.  We'll add one section.  Section header is
                    506:    * further away now.
                    507:    */
                    508: 
                    509:   new_file_h->e_shoff += new_data2_size;
                    510:   new_file_h->e_shnum += 1;
                    511: 
                    512: #ifdef DEBUG
                    513:   fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
                    514:   fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
                    515:   fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
                    516:   fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
                    517: #endif
                    518: 
                    519:   /* Fix up a new program header.  Extend the writable data segment so
                    520:    * that the bss area is covered too. Find that segment by looking
                    521:    * for a segment that ends just before the .bss area.  Make sure
                    522:    * that no segments are above the new .data2.  Put a loop at the end
                    523:    * to adjust the offset and address of any segment that is above
                    524:    * data2, just in case we decide to allow this later.
                    525:    */
                    526: 
                    527:   for (n = new_file_h->e_phnum - 1; n >= 0; n--)
                    528:     {
                    529:       /* Compute maximum of all requirements for alignment of section.  */
                    530:       int alignment = (NEW_PROGRAM_H (n)).p_align;
                    531:       if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
                    532:        alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
                    533: 
                    534:       if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr)
                    535:        fatal ("Program segment above .bss in %s\n", old_name, 0);
                    536: 
                    537:       if (NEW_PROGRAM_H(n).p_type == PT_LOAD
                    538:          && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
                    539:                        + (NEW_PROGRAM_H (n)).p_filesz,
                    540:                        alignment)
                    541:              == round_up (old_bss_addr, alignment)))
                    542:        break;
                    543:     }
                    544:   if (n < 0)
                    545:     fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
                    546: 
                    547:   NEW_PROGRAM_H(n).p_filesz += new_data2_size;
                    548:   NEW_PROGRAM_H(n).p_memsz = NEW_PROGRAM_H(n).p_filesz;
                    549: 
                    550: #if 0 /* Maybe allow section after data2 - does this ever happen? */
                    551:   for (n = new_file_h->e_phnum - 1; n >= 0; n--)
                    552:     {
                    553:       if (NEW_PROGRAM_H(n).p_vaddr
                    554:          && NEW_PROGRAM_H(n).p_vaddr >= new_data2_addr)
                    555:        NEW_PROGRAM_H(n).p_vaddr += new_data2_size - old_bss_size;
                    556: 
                    557:       if (NEW_PROGRAM_H(n).p_offset >= new_data2_offset)
                    558:        NEW_PROGRAM_H(n).p_offset += new_data2_size;
                    559:     }
                    560: #endif
                    561: 
                    562:   /* Fix up section headers based on new .data2 section.  Any section
                    563:    * whose offset or virtual address is after the new .data2 section
                    564:    * gets its value adjusted.  .bss size becomes zero and new address
                    565:    * is set.  data2 section header gets added by copying the existing
                    566:    * .data header and modifying the offset, address and size.
                    567:    */
                    568: 
                    569:   for (n = 1; n < new_file_h->e_shnum; n++)
                    570:     {
                    571:       if (NEW_SECTION_H(n).sh_offset >= new_data2_offset)
                    572:        NEW_SECTION_H(n).sh_offset += new_data2_size;
                    573: 
                    574:       if (NEW_SECTION_H(n).sh_addr
                    575:          && NEW_SECTION_H(n).sh_addr >= new_data2_addr)
                    576:        NEW_SECTION_H(n).sh_addr += new_data2_size - old_bss_size;
                    577:     }
                    578: 
                    579:   new_data2_index = old_file_h->e_shnum;
                    580: 
                    581:   for (old_data_index = 1; old_data_index < old_file_h->e_shnum;
                    582:        old_data_index++)
                    583:     if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name,
                    584:                 ".data"))
                    585:       break;
                    586:   if (old_data_index == old_file_h->e_shnum)
                    587:     fatal ("Can't find .data in %s.\n", old_name, 0);
                    588: 
                    589:   memcpy (&NEW_SECTION_H(new_data2_index), &OLD_SECTION_H(old_data_index),
                    590:          new_file_h->e_shentsize);
                    591: 
                    592:   NEW_SECTION_H(new_data2_index).sh_addr = new_data2_addr;
                    593:   NEW_SECTION_H(new_data2_index).sh_offset = new_data2_offset;
                    594:   NEW_SECTION_H(new_data2_index).sh_size = new_data2_size;
                    595: 
                    596:   NEW_SECTION_H(old_bss_index).sh_size = 0;
                    597:   NEW_SECTION_H(old_bss_index).sh_addr = new_data2_addr + new_data2_size;
                    598: 
                    599:   /* Write out the sections. .data and .data1 (and data2, called
                    600:    * ".data" in the strings table) get copied from the current process
                    601:    * instead of the old file.
                    602:    */
                    603: 
                    604:   for (n = new_file_h->e_shnum - 1; n; n--)
                    605:     {
                    606:       caddr_t src;
                    607: 
                    608:       if (NEW_SECTION_H(n).sh_type == SHT_NULL
                    609:          || NEW_SECTION_H(n).sh_type == SHT_NOBITS)
                    610:        continue;
                    611: 
                    612:       if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data")
                    613:          || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name),
                    614:                      ".data1"))
                    615:        src = (caddr_t) NEW_SECTION_H(n).sh_addr;
                    616:       else
                    617:        src = old_base + OLD_SECTION_H(n).sh_offset;
                    618: 
                    619:       memcpy (NEW_SECTION_H(n).sh_offset + new_base, src,
                    620:              NEW_SECTION_H(n).sh_size);
                    621:     }
                    622: 
                    623:   /* Close the files and make the new file executable */
                    624: 
                    625:   if (close (old_file))
                    626:     fatal ("Can't close(%s): errno %d\n", old_name, errno);
                    627: 
                    628:   if (close (new_file))
                    629:     fatal ("Can't close(%s): errno %d\n", new_name, errno);
                    630: 
                    631:   if (stat (new_name, &stat_buf) == -1)
                    632:     fatal ("Can't stat(%s): errno %d\n", new_name, errno);
                    633: 
                    634:   n = umask (777);
                    635:   umask (n);
                    636:   stat_buf.st_mode |= 0111 & ~n;
                    637:   if (chmod (new_name, stat_buf.st_mode) == -1)
                    638:     fatal ("Can't chmod(%s): errno %d\n", new_name, errno);
                    639: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.