Annotation of coherent/b/bin/ipcs/coffpatch.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * File:       coffpatch.c
                      3:  *
                      4:  * Purpose:    write into a coff file
                      5:  *
                      6:  * $Log:       coffpatch.c,v $
                      7:  * Revision 1.1  92/10/05  13:10:42  bin
                      8:  * Initial revision
                      9:  * 
                     10:  */
                     11: 
                     12: /*
                     13:  * ----------------------------------------------------------------------
                     14:  * Includes.
                     15:  */
                     16: #include <stdio.h>
                     17: #include <fcntl.h>
                     18: #include <errno.h>
                     19: #include <coff.h>
                     20: #include <sys/types.h>
                     21: 
                     22: /*
                     23:  * ----------------------------------------------------------------------
                     24:  * Definitions.
                     25:  *     Constants.
                     26:  *     Macros with argument lists.
                     27:  *     Typedefs.
                     28:  *     Enums.
                     29:  */
                     30: 
                     31: /*
                     32:  * ----------------------------------------------------------------------
                     33:  * Functions.
                     34:  *     Import Functions.
                     35:  *     Export Functions.
                     36:  *     Local Functions.
                     37:  */
                     38: int coffpatch();
                     39: 
                     40: /*
                     41:  * ----------------------------------------------------------------------
                     42:  * Global Data.
                     43:  *     Import Variables.
                     44:  *     Export Variables.
                     45:  *     Local Variables.
                     46:  */
                     47: extern char xflag;
                     48: 
                     49: /*
                     50:  * ----------------------------------------------------------------------
                     51:  * Code.
                     52:  *
                     53:  * Perform peeks/patches as formatted by coffp0() in asypatch.c
                     54:  *
                     55:  * Return nonzero if success; zero if failure.
                     56:  */
                     57: 
                     58: int
                     59: coffpatch(fname, sym, stbl, buf, len, do_read)
                     60: char *fname;
                     61: SYMENT *sym;
                     62: char *stbl, *buf;
                     63: int len, do_read;
                     64: {
                     65:        int     ret = 0;
                     66:        int     fd, err;
                     67:        int     rwct, i;
                     68:        static FILEHDR mainhdr;
                     69:        static AOUTHDR opthdr;
                     70:        static SCNHDR sh;
                     71:        long    seek, sought;
                     72: 
                     73:        long    text_size;      /* Size of text section in bytes.  */
                     74:        vaddr_t text_addr;      /* Virtual memory base address for text.  */
                     75:        short   text_scnum;     /* Section number of text section.  */
                     76:        fsize_t text_base;      /* File offset of start of text section.  */
                     77: 
                     78:        long    data_size;      /* Size of data section in bytes.  */
                     79:        vaddr_t data_addr;      /* Virtual memory base address for data.  */
                     80:        short   data_scnum;     /* Section number of data section.  */
                     81:        fsize_t data_base;      /* File offset of start of data section.  */
                     82: 
                     83:        /*
                     84:         * Open the file to be patched.
                     85:         */
                     86:        if ((fd=open(fname, O_RDONLY)) < 0) {
                     87:                err = errno;
                     88:                printf(stderr, "Cannot open %s\n", fname);
                     89:                printf("Error [%d] {%s}\n", err, sys_errlist[err]);
                     90:                exit(1);
                     91: /*             goto no_close_fd; */
                     92:        }
                     93:        lseek(fd, 0, 0);
                     94: 
                     95:        /*
                     96:         * Read filehdr.
                     97:         */
                     98:        if (-1 == read(fd, &mainhdr, sizeof(FILEHDR))) {
                     99:                perror(fname);
                    100:                fprintf(stderr, "Cannot read executable header.\n");
                    101:                goto close_fd;
                    102:        }
                    103: 
                    104:        /*
                    105:         * Check for valid magic and length of optional header.
                    106:         */
                    107:        if (mainhdr.f_magic != C_386_MAGIC || (mainhdr.f_opthdr < sizeof(opthdr))) {
                    108:                fprintf(stderr, "Bad magic (not COFF) in %s.\n", fname);
                    109:                goto close_fd;
                    110:        }
                    111: 
                    112:        /*
                    113:         *Read the optional header.
                    114:         */
                    115:        if (-1 == read(fd, &opthdr, sizeof(AOUTHDR))) {
                    116:                perror(fname);
                    117:                fprintf(stderr, "Cannot read optional header.\n");
                    118:                goto close_fd;
                    119:        }
                    120:        
                    121:        /*
                    122:         * Fill in the parameters we can get from the opthdr.
                    123:         */
                    124:        text_size = opthdr.tsize;
                    125:        text_addr = opthdr.text_start;
                    126: 
                    127:        data_size = opthdr.dsize;
                    128:        data_addr = opthdr.data_start;
                    129: 
                    130:        /*
                    131:         * Read section headers for offsets.
                    132:         */
                    133:        text_scnum = -1;        /* Mark as not found.  */
                    134:        data_scnum = -1;        /* Mark as not found.  */
                    135:        for (i = 1; i <= mainhdr.f_nscns; ++i) {
                    136:                if (-1 == read(fd, &sh, sizeof(SCNHDR))) {
                    137:                        perror(fname);
                    138:                        fprintf(stderr, "Cannot read section header.\n");
                    139:                        goto close_fd;
                    140:                }
                    141: 
                    142:                if (STYP_TEXT == sh.s_flags) {
                    143:                        text_scnum = i;
                    144:                        text_base = sh.s_scnptr;
                    145:                } else if (STYP_DATA == sh.s_flags) {
                    146:                        data_scnum = i;
                    147:                        data_base = sh.s_scnptr;
                    148:                } /* else ignore this section header.  */
                    149:        }
                    150: 
                    151:        /*
                    152:         * Did we find both sections?
                    153:         */
                    154:        if (-1 == text_scnum) {
                    155:                fprintf(stderr, "No text section in %s.\n", fname);
                    156:        }
                    157: 
                    158:        if (-1 == data_scnum) {
                    159:                fprintf(stderr, "No data section in %s.\n", fname);
                    160:        }
                    161: 
                    162:        /*
                    163:         * Range check the patch address.
                    164:         */
                    165:        if (sym->n_scnum == text_scnum) {
                    166:                if ((sym->n_value < text_addr) ||
                    167:                    (sym->n_value + len > text_addr + text_size) ) {
                    168: 
                    169:                    fprintf(stderr, "Symbol out of range for text section.\n");
                    170:                    fprintf(stderr, "%s: %x\n",
                    171:                        stbl + sym->n_offset - sizeof(long),
                    172:                           sym->n_value);
                    173:                    goto close_fd;
                    174:                }
                    175:        } else if (sym->n_scnum == data_scnum) {
                    176:                if ((sym->n_value < data_addr) ||
                    177:                    (sym->n_value + len > data_addr + data_size) ) {
                    178: 
                    179:                    fprintf(stderr, "Symbol out of range for data section.\n");
                    180:                    fprintf(stderr, "%s: %x\n",
                    181:                           stbl + sym->n_offset - sizeof(long),
                    182:                           sym->n_value);
                    183:                    goto close_fd;
                    184:                }
                    185:        } else {
                    186:                fprintf(stderr,
                    187:                        "Illegal section number %d for symbol %s.\n",
                    188:                        sym->n_scnum,
                    189:                           stbl + sym->n_offset - sizeof(long));
                    190:                goto close_fd;
                    191:        }
                    192: 
                    193:        /*
                    194:         * Seek and patch.
                    195:         */
                    196:        seek = sym->n_value;
                    197:        /*
                    198:         * Adjust the file offset for the symbol based on which
                    199:         * segment it resides in.
                    200:         */
                    201:        if (sym->n_scnum == text_scnum) {
                    202:                seek = (seek - text_addr) + text_base;
                    203:        } else if (sym->n_scnum == data_scnum) {
                    204:                seek = (seek - data_addr) + data_base;
                    205:        } else {
                    206:                fprintf(stderr, "Bad section number!!.\n");
                    207:                goto close_fd;
                    208:        }
                    209: 
                    210:        sought = lseek(fd, seek, 0);
                    211:        if (sought == -1) {
                    212:                fprintf(stderr, "asypatch: lseek to %x failed\n", seek);
                    213:        }
                    214: 
                    215: /*     if (xflag)
                    216:  *             printf("write(%d, [%x]=%x, %d)->%x\n",
                    217:  *               fd, buf, *(int*)buf, len, sought);
                    218:  */
                    219:        if (do_read) {
                    220:                if ((rwct = read(fd, buf, len)) != len) {
                    221:                        fprintf(stderr, "asypatch %s: read %d bytes of %d\n",
                    222:                          stbl, rwct, len);
                    223:                        goto close_fd;
                    224:                }
                    225:        } else {
                    226:                if ((rwct = write(fd, buf, len)) != len) {
                    227:                        fprintf(stderr, "asypatch %s: wrote %d bytes of %d\n",
                    228:                          stbl, rwct, len);
                    229:                        goto close_fd;
                    230:                }
                    231:        }
                    232:        ret = 1;
                    233: 
                    234: close_fd:
                    235:        close(fd);
                    236: no_close_fd:
                    237:        return ret;
                    238: }

unix.superglobalmegacorp.com

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