Annotation of coherent/b/conf/patch/setfile.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <errno.h>
                      3: #include <coff.h>
                      4: #include <fcntl.h>
                      5: #include <sys/types.h>
                      6: #include "patch.h"
                      7: 
                      8: extern char *symbols;          /* String of symbol names.  */
                      9: extern int peek;               /* Are we just looking?  */
                     10: 
                     11: /*
                     12:  * Modify the contents of the file namep to match the array of patch
                     13:  * structures pl[].  The argument, n, is the number of entries in pl[]
                     14:  * that should be processed.
                     15:  */
                     16: void
                     17: setfile(namep, n, pl)
                     18:        char *namep;
                     19:        int n;
                     20:        struct plist pl[];
                     21: {
                     22:        int i;
                     23:        int fd;
                     24:        fsize_t seek;           /* Final seek address for each pl[] entry.  */
                     25:        SYMENT  *sym;           /* Holder SYMENTs while looping.  */
                     26:        static FILEHDR mainhdr; /* Main COFF file header.  */
                     27:        static AOUTHDR opthdr;  /* COFF Optional header (for executables).  */
                     28:        static SCNHDR sh;       /* Section header.  */
                     29: 
                     30:        long    text_size;      /* Size of text section in bytes.  */
                     31:        vaddr_t text_addr;      /* Virtual memory base address for text.  */
                     32:        short   text_scnum;     /* Section number of text section.  */
                     33:        fsize_t text_base;      /* File offset of start of text section.  */
                     34: 
                     35:        long    data_size;      /* Size of data section in bytes.  */
                     36:        vaddr_t data_addr;      /* Virtual memory base address for data.  */
                     37:        short   data_scnum;     /* Section number of data section.  */
                     38:        fsize_t data_base;      /* File offset of start of data section.  */
                     39: 
                     40:        char *symname;          /* Name of the currently patched LHS.  */
                     41: 
                     42:        /* Open the file to be patched.  */
                     43:        if (peek) {
                     44:                if ((fd=open(namep, O_RDONLY)) < 0) {
                     45:                        fprintf(stderr, "Cannot open %s for reading.\n", namep);
                     46:                        exit(1);
                     47:                }
                     48:        } else {
                     49:                if ((fd=open(namep, O_RDWR)) < 0) {
                     50:                        fprintf(stderr, "Cannot open %s.\n", namep);
                     51:                        exit(1);
                     52:                }
                     53:        }
                     54: 
                     55:        lseek(fd, 0L, 0);
                     56: 
                     57:        /* Read filehdr.  */
                     58:        if (-1 == read(fd, &mainhdr, sizeof(FILEHDR))) {
                     59:                perror(namep);
                     60:                fprintf(stderr, "Cannot read executable header.\n");
                     61:                exit(1);
                     62:        }
                     63: 
                     64:        /* Check for valid magic and length of optional header.  */
                     65:        if (!ISCOFF(mainhdr.f_magic) || (mainhdr.f_opthdr < sizeof(opthdr))) {
                     66:                fprintf(stderr, "Bad magic in %s.\n", namep);
                     67:                exit(1);
                     68:        }
                     69: 
                     70:        /* Read the optional header.  */
                     71:        if (-1 == read(fd, &opthdr, sizeof(AOUTHDR))) {
                     72:                perror(namep);
                     73:                fprintf(stderr, "Cannot read optional header.\n");
                     74:                exit(1);
                     75:        }
                     76:        
                     77: 
                     78:        /* Fill in the parameters we can get from the opthdr.  */
                     79:        text_size = opthdr.tsize;
                     80:        text_addr = opthdr.text_start;
                     81: 
                     82:        data_size = opthdr.dsize;
                     83:        data_addr = opthdr.data_start;
                     84: 
                     85:        /* Read section headers for offsets.  */
                     86:        text_scnum = -1;        /* Mark as not found.  */
                     87:        data_scnum = -1;        /* Mark as not found.  */
                     88:        for (i = 1; i <= mainhdr.f_nscns; ++i) {
                     89:                if (-1 == read(fd, &sh, sizeof(SCNHDR))) {
                     90:                        perror(namep);
                     91:                        fprintf(stderr, "Cannot read section header.\n");
                     92:                        exit(1);
                     93:                }
                     94: 
                     95:                if (STYP_TEXT == sh.s_flags) {
                     96:                        text_scnum = i;
                     97:                        text_base = sh.s_scnptr;
                     98:                } else if (STYP_DATA == sh.s_flags) {
                     99:                        data_scnum = i;
                    100:                        data_base = sh.s_scnptr;
                    101:                } /* else ignore this section header.  */
                    102:        }
                    103: 
                    104:        /* Did we find both sections?  */
                    105:        if (-1 == text_scnum) {
                    106:                fprintf(stderr, "No text section in %s.\n", namep);
                    107:        }
                    108: 
                    109:        if (-1 == data_scnum) {
                    110:                fprintf(stderr, "No data section in %s.\n", namep);
                    111:        }
                    112: 
                    113:        /* Range check all the patch addresses.  */
                    114:        for (i = 0; i < n; i += 1) {
                    115:                sym = pl[i].p_lvnp;
                    116:                if (sym->n_scnum == text_scnum) {
                    117:                        if ((sym->n_value < text_addr) ||
                    118:                            (sym->n_value > text_addr + text_size) ) {
                    119: 
                    120:                            fprintf(stderr, "Symbol out of range for text section.\n");
                    121:                            fprintf(stderr, "%s: %x\n",
                    122:                                   &(symbols[sym->n_offset - sizeof(long)]),
                    123:                                   sym->n_value);
                    124:                            exit(1);
                    125:                        }
                    126:                } else if (sym->n_scnum == data_scnum) {
                    127:                        if ((sym->n_value < data_addr) ||
                    128:                            (sym->n_value > data_addr + data_size) ) {
                    129: 
                    130:                            fprintf(stderr, "Symbol out of range for data section.\n");
                    131:                            fprintf(stderr, "%s: %x\n",
                    132:                                   &(symbols[sym->n_offset - sizeof(long)]),
                    133:                                   sym->n_value);
                    134:                            exit(1);
                    135:                        }
                    136:                } else {
                    137:                        fprintf(stderr,
                    138:                                "Illegal section number %d for symbol %s.\n",
                    139:                                sym->n_scnum,
                    140:                                &(symbols[(sym->n_offset) - sizeof(long)]));
                    141:                        fprintf(stderr, "Was there really a mem fault?\n");
                    142:                        exit(1);
                    143:                }
                    144: 
                    145:        }
                    146: 
                    147:        /* Walk through pl[] seeking and patching.  */
                    148:        for (i = 0; i < n; i += 1) {
                    149:                seek = pl[i].p_lval;
                    150:                sym = pl[i].p_lvnp;
                    151:                /*
                    152:                 * Adjust the file offset for the symbol based on which
                    153:                 * segement it resides in.
                    154:                 */
                    155:                if (sym->n_scnum == text_scnum) {
                    156:                        seek = (seek - text_addr) + text_base;
                    157:                } else if (sym->n_scnum == data_scnum) {
                    158:                        seek = (seek - data_addr) + data_base;
                    159:                } else {
                    160:                        fprintf(stderr, "Unreachable code is setfile().\n");
                    161:                        exit(1);
                    162:                }
                    163: 
                    164:                lseek(fd, seek, 0);
                    165: 
                    166:                symname = &(symbols[pl[i].p_lvnp->n_offset - sizeof(long)]);
                    167:                if (patch(fd, &pl[i], namep, symname) < 0) {
                    168:                        fprintf(stderr, "Write error in %s\n", namep);
                    169:                }
                    170:        }
                    171: 
                    172:        close(fd);
                    173: }

unix.superglobalmegacorp.com

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