Annotation of coherent/d/conf/old_tboot/coff.c, revision 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.