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