Annotation of coherent/b/conf/patch/setfile.c, revision 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.