Annotation of coherent/d/conf/tboot/coff.c, revision 1.1.1.1

1.1       root        1: /* coff.c -- rutines for manipulating coff executable files.  */
                      2: 
                      3: #include <coff.h>
                      4: #include "tboot.h"
                      5: 
                      6: /* Convert COFF to load table.
                      7:  * Used to generate loading instructions for use by tboot main().
                      8:  * Returns true on successful translation.
                      9:  */
                     10: 
                     11: int
                     12: coff2load(ip, table, data_seg)
                     13: struct inode *ip;              /* input: File to read.         */
                     14: struct load_segment table[];   /* output: How to read it.      */
                     15: uint16 *data_seg;              /* output: Where to point es.   */
                     16: {
                     17:        FILHDR  fh;     /* COFF file header.            */
                     18:        AOUTHDR oh;     /* COFF optional header.        */
                     19:        SCNHDR  sh;     /* COFF section header.         */
                     20: 
                     21:        int i, j;       /* Loop counters.  */
                     22:        fsize_t section_seek;   /* Seek counter for section headers.  */
                     23: 
                     24:        /* Read the file header.  */
                     25:        iread(ip, &fh, (fsize_t) 0, (uint16) sizeof (fh));
                     26: 
                     27: 
                     28:        /* Check for the 5000 possible failures...  */
                     29:        /* Is this really a i386 COFF file?  */
                     30:        if (I386MAGIC != fh.f_magic) {
                     31:                puts("COFF COFF!  File header bad magic.\r\n");
                     32:                puts("This is not an i386 COFF file.\r\n");
                     33:                return 0;
                     34:        }
                     35: 
                     36:        /* Is this an executable COFF file?  */
                     37:        if (!(fh.f_flags & F_EXEC)) {
                     38:                puts("Non-executable COFF file.\r\n");
                     39:                return 0;
                     40:        }
                     41: 
                     42:        /* Does it have the information we need to execute it?  */
                     43:        if (sizeof(oh) != fh.f_opthdr) {
                     44:                puts("COFF optional header is wrong size.\r\n");
                     45:                return 0;
                     46:        }
                     47: 
                     48:        /*
                     49:         * Pointless witticism:
                     50:         * (Actually, this helped us find a bug in ld.)
                     51:         */
                     52:        if (fh.f_timdat < 0x1000) {
                     53:                puts(
                     54:         "Wow!  An executable from the first few thousand seconds of time!\r\n"
                     55:                );
                     56:        }
                     57: 
                     58:        /* ASSERTION:  We know this to be an executable i386 COFF file.  */
                     59: 
                     60:        /* Read the optional header.  */
                     61:        /* This is the one with the data we really want.  */
                     62:        iread(ip, &oh, (fsize_t) sizeof(fh), (uint16) sizeof (oh));
                     63: 
                     64:        /* Validate the optional header.  */
                     65:        
                     66:        if (NORMAL_MAGIC != oh.magic) {
                     67:                puts("COFF COFF!  Optional header bad magic.\r\n");
                     68:                puts("This isn't a normal executable file.\r\n");
                     69:                return 0;
                     70:        }
                     71: 
                     72:        /* Read through the section headers,
                     73:         * looking for text and data segments, and
                     74:         * turning them into little toads.  Or something like that.
                     75:         */
                     76: 
                     77: #define TEXT table[0]
                     78: #define DATA table[1]
                     79: 
                     80:        /* Loop until we have both the sections we want, at most twice.  */
                     81:        for (TEXT.valid = 0, DATA.valid = 0, j = 0;
                     82:            !(TEXT.valid && DATA.valid) && j < 2;
                     83:            ++j) {
                     84: 
                     85:             for (section_seek = sizeof(FILHDR)+sizeof(AOUTHDR), i = 0;
                     86:             i < fh.f_nscns;    /* i < number of sections  */
                     87:             section_seek += SCNHSZ, ++i) {
                     88: 
                     89:                iread(ip, &sh, section_seek, SCNHSZ);
                     90:                switch ((int) sh.s_flags) {
                     91:                case STYP_TEXT:
                     92:                        TEXT.valid = 1;
                     93:                        TEXT.message = "\r\nLoading COHERENT.\r\n";
                     94:                        TEXT.load_toseg = sys_base;
                     95:                        TEXT.load_tooffset = 0;
                     96:                        TEXT.load_offset = sh.s_scnptr;
                     97:                        TEXT.load_length = sh.s_size;
                     98:                        break;
                     99: 
                    100:                case STYP_DATA:
                    101:                        /* The text header must already have been read to
                    102:                         * put meaningful numbers here.
                    103:                         */
                    104:                        if (TEXT.valid) {
                    105:                                DATA.valid = 1;
                    106:                                DATA.message = "\r\nLoading COHERENT data.\r\n";
                    107:                                /* Round up to next paragraph beyond end
                    108:                                 * of text.
                    109:                                 */
                    110:                                DATA.load_toseg = (sys_base +
                    111:                                        (TEXT.load_length + 15) / 16);
                    112:                                DATA.load_tooffset = 0;
                    113:                                DATA.load_offset = sh.s_scnptr;
                    114:                                DATA.load_length = sh.s_size;
                    115:                                *data_seg = (sys_base +
                    116:                                        (TEXT.load_length + 15) / 16);
                    117:                        }
                    118:                        break;
                    119:                case STYP_BSS:
                    120:                        break;
                    121:                default:
                    122:                        puts("Warning.  Unrecognized COFF section.\r\n");
                    123:                        break;
                    124:                } /* switch (sh.s_flags) */
                    125: 
                    126:             } /* for walk through headers  */
                    127: 
                    128:        } /* while haven't got both, at most twice  */
                    129:        
                    130:        if (!TEXT.valid) {
                    131:                puts("Failed to find COFF text section.\r\n");
                    132:                return 0;
                    133:        }
                    134: 
                    135:        if (!DATA.valid) {
                    136:                puts("Failed to find COFF data section.\r\n");
                    137:                return 0;
                    138:        }
                    139: 
                    140:        table[2].valid = 0;     /* Terminate the list.  */
                    141: 
                    142:        return 1;
                    143: }
                    144: 
                    145: 
                    146: /*
                    147:  * Symbol name.
                    148:  */
                    149: static char *
                    150: symName(sym, str_tab, work)
                    151: SYMENT *sym;
                    152: char *str_tab, *work;
                    153: {
                    154:        if (!sym->_n._n_n._n_zeroes)
                    155:                return (str_tab + sym->_n._n_n._n_offset - 4);
                    156: 
                    157:        memcpy(work, sym->_n._n_name, SYMNMLEN);
                    158:        work[SYMNMLEN] = '\0';
                    159:        return (work);
                    160: }
                    161: 
                    162: /*
                    163:  * Look up the value of a single data symbol in a coff file,
                    164:  * relative to the start of the data segment.
                    165:  *
                    166:  * We use the symbol "sdata" to find the start of the data segment--
                    167:  * this works for 386 COHERENT kernels but will not work in general.
                    168:  * It should really fetch the address of the start of the data segment
                    169:  * from the data section header.
                    170:  */
                    171: uint32
                    172: wrap_coffnlist(fn, symbol)
                    173: char *fn;      /* file name */
                    174: char *symbol;  /* symbol to look up */
                    175: {
                    176:        /* Something goes wrong with looking up symbol if
                    177:         * nlp is automatic rather than static, even with a huge stack.
                    178:         */
                    179:        static SYMENT nlp[2];
                    180:        uint32 retval;
                    181: 
                    182:        /* Start of the data segment.  */
                    183:        strcpy(nlp[0]._n._n_name, "sdata");
                    184:        nlp[0].n_type = -1;
                    185: 
                    186:        nlp[1]._n._n_n._n_zeroes = 0;
                    187:        nlp[1]._n._n_n._n_offset = sizeof(int32);
                    188:        nlp[1].n_type = -1;
                    189: 
                    190:        coffnlist(fn, nlp, symbol, 2);
                    191: 
                    192:        retval = ((uint32)nlp[1].n_value) - ((uint32)nlp[0].n_value);
                    193: 
                    194:        if (verbose_flag)
                    195:                printf("sdata=%lx  %s=%lx  retval=%lx\r\n",
                    196:                  nlp[0].n_value, symbol, nlp[1].n_value, retval);
                    197: 
                    198:        if (0L == nlp[1].n_value) {
                    199:                return(0L);
                    200:        } else {
                    201:                return retval;
                    202:        }
                    203:        puts("Unreachable code in wrap_coffnlist().\r\n");
                    204:        return(0L);
                    205: } /* wrap_coffnlist() */
                    206: 
                    207: int
                    208: coffnlist(fn, nlp, names, count)
                    209: char *fn;      /* file name */
                    210: SYMENT *nlp;   /* names to look up */
                    211: char *names;   /* long names */
                    212: int count;     /* size of passed table */
                    213: {
                    214:        FILHDR head;
                    215:        int fp;
                    216:        /* str_tab should be malloc'd. Blows up if file's sym table too big. */
                    217: #define STR_TAB_SIZE 5000
                    218:        char str_tab[STR_TAB_SIZE];
                    219:        long str_length;
                    220:        int aux, i;
                    221: 
                    222:        if (-1 == (fp = open(fn, 0))) {
                    223:                puts("coffnlist open failed\r\n");
                    224:                return 0;
                    225:        }
                    226: 
                    227:        if (FILHSZ != read(fp, &head, FILHSZ) || head.f_magic != I386MAGIC) {
                    228:                close (fp);
                    229:                printf("coffnlist header read (%d) failed\r\n", FILHSZ);
                    230:                return 0;
                    231:        }
                    232: 
                    233:        lseek(fp, head.f_symptr + (SYMESZ * head.f_nsyms), 0);
                    234: 
                    235:        if (sizeof(str_length) != read(fp, &str_length, sizeof(str_length)))
                    236:                str_length = 0;
                    237:        if (str_length) {
                    238:                uint16 len;
                    239: 
                    240:                len = str_length -= 4;
                    241:                if (len != str_length || len > STR_TAB_SIZE) {
                    242:                        close (fp);
                    243:                        printf("coffnlist str table overflow, len = %d\r\n",
                    244:                          len);
                    245:                        return 0;
                    246:                }
                    247: 
                    248:                if (len != read(fp, str_tab, len)) {
                    249:                        close (fp);
                    250:                        puts("coffnlist str read failed\r\n");
                    251:                        return 0;
                    252:                }
                    253:        }
                    254: 
                    255:        lseek(fp, head.f_symptr, 0);
                    256:        for (i = aux = 0; i < head.f_nsyms; i++) {
                    257:                SYMENT sym;     /* symbol read in */
                    258:                int taux, j;
                    259: 
                    260:                if (SYMESZ != read(fp, &sym, SYMESZ)) {
                    261:                        close (fp);
                    262:                        puts("coffnlist sym read failed\r\n");
                    263:                        return 0;
                    264:                }
                    265: 
                    266:                if (aux) {
                    267:                        aux--;
                    268:                        continue;
                    269:                }
                    270:                aux = sym.n_numaux;
                    271:                for (j = taux = 0; j < count; j++) {
                    272:                        static char n1[SYMNMLEN + 1], n2[SYMNMLEN + 1];
                    273:                        register SYMENT *np;
                    274: 
                    275:                        if (taux) {
                    276:                                taux--;
                    277:                                continue;
                    278:                        }
                    279:                        np = nlp + j;
                    280:                        taux = np->n_numaux;
                    281:                        if (np->n_type != -1 ||
                    282:                            strcmp(symName(np, names, n1),
                    283:                                   symName(&sym, str_tab, n2)))
                    284:                                continue;
                    285:                        np->n_value  = sym.n_value;
                    286:                        np->n_scnum  = sym.n_scnum;
                    287:                        np->n_type   = sym.n_type;
                    288:                        np->n_sclass = sym.n_sclass;
                    289:                        break;
                    290:                }
                    291:        }
                    292:        close (fp);
                    293:        return 1;
                    294: }
                    295: 
                    296: #ifdef TEST
                    297: #include <stdio.h>
                    298: 
                    299: main()
                    300: {
                    301:        int i;
                    302:        static SYMENT sym[3];
                    303:        static char ptr[]="rootdev";
                    304: 
                    305:        strcpy(sym[0]._n._n_name, "NCLIST");
                    306:        sym[0].n_type = -1;
                    307: 
                    308:        strcpy(sym[1]._n._n_name, "sdata");
                    309:        sym[1].n_type = -1;
                    310: 
                    311:        sym[2]._n._n_n._n_zeroes = 0;
                    312:        sym[2]._n._n_n._n_offset = sizeof(int32);
                    313:        sym[2].n_type = -1;
                    314: 
                    315:        coffnlist("/at386", sym, ptr, 3);
                    316: 
                    317:        for (i = 0; i < 3; ++i) {
                    318:                printf("sym[%d]._n._n_name: %s\n", i, sym[i]._n._n_name);
                    319:                printf("sym[%d].n_value: %lx\n\n", i, sym[i].n_value);
                    320:        }
                    321: 
                    322:        printf("\nrootdev as offset: %lx\n", 
                    323:                wrap_coffnlist("/at386", "rootdev"));
                    324: }
                    325: #endif

unix.superglobalmegacorp.com

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