Annotation of qemu/roms/openbios/kernel/dict.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * tag: dict management
                      3:  *
                      4:  * Copyright (C) 2003-2005 Stefan Reinauer, Patrick Mauritz
                      5:  *
                      6:  * See the file "COPYING" for further information about
                      7:  * the copyright and warranty status of this work.
                      8:  */
                      9: 
                     10: #include "config.h"
                     11: #include "kernel/kernel.h"
                     12: #include "dict.h"
                     13: #ifdef BOOTSTRAP
                     14: #include <string.h>
                     15: #else
                     16: #include "libc/string.h"
                     17: #endif
                     18: #include "cross.h"
                     19: 
                     20: 
                     21: unsigned char *dict = NULL;
                     22: ucell *last;
                     23: cell dicthead = 0;
                     24: cell dictlimit = 0;
                     25: 
                     26: /* lfa2nfa
                     27:  * converts a link field address to a name field address,
                     28:  * i.e find pointer to a given words name
                     29:  */
                     30: 
                     31: ucell lfa2nfa(ucell ilfa)
                     32: {
                     33:        /* get offset from dictionary start */
                     34:        ilfa = ilfa - (ucell)pointer2cell(dict);
                     35:        ilfa--;                         /* skip status        */
                     36:        while (dict[--ilfa] == 0);      /* skip all pad bytes */
                     37:        ilfa -= (dict[ilfa] - 128);
                     38:        return ilfa + (ucell)pointer2cell(dict);
                     39: }
                     40: 
                     41: /* lfa2cfa
                     42:  * converts a link field address to a code field address.
                     43:  * in this forth implementation this is just a fixed offset
                     44:  */
                     45: 
                     46: static xt_t lfa2cfa(ucell ilfa)
                     47: {
                     48:        return (xt_t)(ilfa + sizeof(cell));
                     49: }
                     50: 
                     51: 
                     52: /* fstrlen - returns length of a forth string. */
                     53: 
                     54: ucell fstrlen(ucell fstr)
                     55: {
                     56:        fstr -= pointer2cell(dict)+1;
                     57:        //fstr -= pointer2cell(dict); FIXME
                     58:        while (dict[++fstr] < 128)
                     59:                ;
                     60:        return dict[fstr] - 128;
                     61: }
                     62: 
                     63: /* to_lower - convert a character to lowecase */
                     64: 
                     65: static int to_lower(int c)
                     66: {
                     67:        return ((c >= 'A') && (c <= 'Z')) ? (c - 'A' + 'a') : c;
                     68: }
                     69: 
                     70: /* fstrcmp - compare null terminated string with forth string. */
                     71: 
                     72: static int fstrcmp(const char *s1, ucell fstr)
                     73: {
                     74:        char *s2 = (char*)cell2pointer(fstr);
                     75:        while (*s1) {
                     76:                if ( to_lower(*(s1++)) != to_lower(*(s2++)) )
                     77:                        return -1;
                     78:        }
                     79:        return 0;
                     80: }
                     81: 
                     82: /* fstrncpy - copy a forth string to a destination (with NULL termination) */
                     83: 
                     84: void fstrncpy(char *dest, ucell src, unsigned int maxlen)
                     85: {
                     86:        int len = fstrlen(src);
                     87: 
                     88:        if (fstrlen(src) >= maxlen) len = maxlen - 1;
                     89:        memcpy(dest, cell2pointer(src), len);
                     90:        *(dest + len) = '\0';
                     91: } 
                     92: 
                     93: 
                     94: /* findword
                     95:  * looks up a given word in the dictionary. This function
                     96:  * is used by the c based interpreter and to find the "initialize"
                     97:  * word.
                     98:  */
                     99: 
                    100: xt_t findword(const char *s1)
                    101: {
                    102:        ucell tmplfa, len;
                    103: 
                    104:        if (!last)
                    105:                return 0;
                    106: 
                    107:        tmplfa = read_ucell(last);
                    108: 
                    109:        len = strlen(s1);
                    110: 
                    111:        while (tmplfa) {
                    112:                ucell nfa = lfa2nfa(tmplfa);
                    113: 
                    114:                if (len == fstrlen(nfa) && !fstrcmp(s1, nfa)) {
                    115:                        return lfa2cfa(tmplfa);
                    116:                }
                    117: 
                    118:                tmplfa = read_ucell(cell2pointer(tmplfa));
                    119:        }
                    120: 
                    121:        return 0;
                    122: }
                    123: 
                    124: 
                    125: /* findsemis_wordlist
                    126:  * Given a DOCOL xt and a wordlist, find the address of the semis
                    127:  * word at the end of the word definition. We do this by finding
                    128:  * the word before this in the dictionary, then counting back one
                    129:  * from the NFA.
                    130:  */
                    131: 
                    132: static ucell findsemis_wordlist(ucell xt, ucell wordlist)
                    133: {
                    134:        ucell tmplfa, nextlfa, nextcfa;
                    135: 
                    136:        if (!wordlist)
                    137:                return 0;
                    138: 
                    139:        tmplfa = read_ucell(cell2pointer(wordlist));
                    140:        nextcfa = lfa2cfa(tmplfa);
                    141: 
                    142:        /* Catch the special case where the lfa of the word we
                    143:         * want is the last word in the dictionary; in that case
                    144:         * the end of the word is given by "here" - 1 */
                    145:        if (nextcfa == xt)
                    146:                return pointer2cell(dict) + dicthead - sizeof(cell);
                    147: 
                    148:        while (tmplfa) {
                    149: 
                    150:                /* Peek ahead and see if the next CFA in the list is the
                    151:                 * one we are searching for */ 
                    152:                nextlfa = read_ucell(cell2pointer(tmplfa)); 
                    153:                nextcfa = lfa2cfa(nextlfa);
                    154: 
                    155:                /* If so, count back 1 cell from the current NFA */
                    156:                if (nextcfa == xt)
                    157:                        return lfa2nfa(tmplfa) - sizeof(cell);
                    158: 
                    159:                tmplfa = nextlfa;
                    160:        }
                    161: 
                    162:        return 0;
                    163: }
                    164: 
                    165: 
                    166: /* findsemis
                    167:  * Given a DOCOL xt, find the address of the semis word at the end
                    168:  * of the word definition by searching all vocabularies */
                    169: 
                    170: ucell findsemis(ucell xt)
                    171: {
                    172:        ucell usesvocab = findword("vocabularies?") + sizeof(cell);
                    173:        unsigned int i;
                    174: 
                    175:        if (read_ucell(cell2pointer(usesvocab))) {
                    176:                /* Vocabularies are in use, so search each one in turn */
                    177:                ucell numvocabs = findword("#order") + sizeof(cell);
                    178: 
                    179:                for (i = 0; i < read_ucell(cell2pointer(numvocabs)); i++) {
                    180:                        ucell vocabs = findword("vocabularies") + 2 * sizeof(cell);
                    181:                        ucell semis = findsemis_wordlist(xt, read_cell(cell2pointer(vocabs + (i * sizeof(cell)))));     
                    182: 
                    183:                        /* If we get a non-zero result, we found the xt in this vocab */
                    184:                        if (semis)
                    185:                                return semis;
                    186:                }
                    187:        } else { 
                    188:                /* Vocabularies not in use */
                    189:                return findsemis_wordlist(xt, read_ucell(last));
                    190:        }
                    191: 
                    192:        return 0;
                    193: }
                    194: 
                    195: 
                    196: /* findxtfromcell_wordlist
                    197:  * Given a cell and a wordlist, determine the CFA of the word containing
                    198:  * the cell or 0 if we are unable to return a suitable CFA
                    199:  */
                    200: 
                    201: ucell findxtfromcell_wordlist(ucell incell, ucell wordlist)
                    202: {
                    203:        ucell tmplfa;
                    204: 
                    205:        if (!wordlist)
                    206:                return 0;
                    207: 
                    208:        tmplfa = read_ucell(cell2pointer(wordlist));
                    209:        while (tmplfa) {
                    210:                if (tmplfa < incell)
                    211:                        return lfa2cfa(tmplfa);
                    212: 
                    213:                tmplfa = read_ucell(cell2pointer(tmplfa));
                    214:        }       
                    215: 
                    216:        return 0;
                    217: } 
                    218: 
                    219: 
                    220: /* findxtfromcell
                    221:  * Given a cell, determine the CFA of the word containing
                    222:  * the cell by searching all vocabularies 
                    223:  */
                    224: 
                    225: ucell findxtfromcell(ucell incell)
                    226: {
                    227:        ucell usesvocab = findword("vocabularies?") + sizeof(cell);
                    228:        unsigned int i;
                    229: 
                    230:        if (read_ucell(cell2pointer(usesvocab))) {
                    231:                /* Vocabularies are in use, so search each one in turn */
                    232:                ucell numvocabs = findword("#order") + sizeof(cell);
                    233: 
                    234:                for (i = 0; i < read_ucell(cell2pointer(numvocabs)); i++) {
                    235:                        ucell vocabs = findword("vocabularies") + 2 * sizeof(cell);
                    236:                        ucell semis = findxtfromcell_wordlist(incell, read_cell(cell2pointer(vocabs + (i * sizeof(cell)))));    
                    237: 
                    238:                        /* If we get a non-zero result, we found the xt in this vocab */
                    239:                        if (semis)
                    240:                                return semis;
                    241:                }
                    242:        } else { 
                    243:                /* Vocabularies not in use */
                    244:                return findxtfromcell_wordlist(incell, read_ucell(last));
                    245:        }
                    246: 
                    247:        return 0;
                    248: }
                    249: 
                    250: void dump_header(dictionary_header_t *header)
                    251: {
                    252:        printk("OpenBIOS dictionary:\n");
                    253:        printk("  version:     %d\n", header->version);
                    254:        printk("  cellsize:    %d\n", header->cellsize);
                    255:        printk("  endianess:   %s\n", header->endianess?"big":"little");
                    256:        printk("  compression: %s\n", header->compression?"yes":"no");
                    257:        printk("  relocation:  %s\n", header->relocation?"yes":"no");
                    258:        printk("  checksum:    %08x\n", target_long(header->checksum));
                    259:        printk("  length:      %08x\n", target_long(header->length));
                    260:        printk("  last:        %0" FMT_CELL_x "\n", target_cell(header->last));
                    261: }
                    262: 
                    263: ucell load_dictionary(const char *data, ucell len)
                    264: {
                    265:        u32 checksum=0;
                    266:        const char *checksum_walk;
                    267:        ucell *walk, *reloc_table;
                    268:        dictionary_header_t *header=(dictionary_header_t *)data;
                    269: 
                    270:        /* assertions */
                    271:        if (len <= (sizeof(dictionary_header_t)) || strncmp(DICTID, data, 8))
                    272:                return 0;
                    273: #ifdef CONFIG_DEBUG_DICTIONARY
                    274:        dump_header(header);
                    275: #endif
                    276: 
                    277:        checksum_walk=data;
                    278:        while (checksum_walk<data+len) {
                    279:                checksum+=read_long(checksum_walk);
                    280:                checksum_walk+=sizeof(u32);
                    281:        }
                    282: 
                    283:        if(checksum) {
                    284:                printk("Checksum invalid (%08x)!\n", checksum);
                    285:                return 0;
                    286:        }
                    287: 
                    288:        data += sizeof(dictionary_header_t);
                    289: 
                    290:        dicthead = target_long(header->length);
                    291: 
                    292:        memcpy(dict, data, dicthead);
                    293:        reloc_table=(ucell *)(data+dicthead);
                    294: 
                    295: #ifdef CONFIG_DEBUG_DICTIONARY
                    296:        printk("\nmoving dictionary (%x bytes) to %x\n",
                    297:                        (ucell)dicthead, (ucell)dict);
                    298:        printk("\ndynamic relocation...");
                    299: #endif
                    300: 
                    301:        for (walk = (ucell *) dict; walk < (ucell *) (dict + dicthead);
                    302:             walk++) {
                    303:                int pos, bit, l;
                    304:                l=(walk-(ucell *)dict);
                    305:                pos=l/BITS;
                    306:                bit=l&~(-BITS);
                    307:                 if (reloc_table[pos] & target_ucell((ucell)1ULL << bit)) {
                    308:                        // printk("%lx, pos %x, bit %d\n",*walk, pos, bit);
                    309:                        write_ucell(walk, read_ucell(walk)+pointer2cell(dict));
                    310:                }
                    311:        }
                    312: 
                    313: #ifdef CONFIG_DEBUG_DICTIONARY
                    314:        printk(" done.\n");
                    315: #endif
                    316: 
                    317:        last = (ucell *)(dict + target_ucell(header->last));
                    318: 
                    319:        return -1;
                    320: }

unix.superglobalmegacorp.com

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