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

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

unix.superglobalmegacorp.com

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