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

unix.superglobalmegacorp.com

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