示例#1
0
ucell load_dictionary(const char *data, ucell len)
{
	u32 checksum=0;
	const char *checksum_walk;
	ucell *walk, *reloc_table;
	dictionary_header_t *header=(dictionary_header_t *)data;

	/* assertions */
	if (len <= (sizeof(dictionary_header_t)) || strncmp(DICTID, data, 8))
		return 0;
#ifdef CONFIG_DEBUG_DICTIONARY
	dump_header(header);
#endif

	checksum_walk=data;
	while (checksum_walk<data+len) {
		checksum+=read_long(checksum_walk);
		checksum_walk+=sizeof(u32);
	}

	if(checksum) {
		printk("Checksum invalid (%08x)!\n", checksum);
		return 0;
	}

	data += sizeof(dictionary_header_t);

	dicthead = target_long(header->length);

	memcpy(dict, data, dicthead);
	reloc_table=(ucell *)(data+dicthead);

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("\nmoving dictionary (%x bytes) to %x\n",
			(ucell)dicthead, (ucell)dict);
	printk("\ndynamic relocation...");
#endif

	for (walk = (ucell *) dict; walk < (ucell *) (dict + dicthead);
	     walk++) {
		int pos, bit, l;
		l=(walk-(ucell *)dict);
		pos=l/BITS;
		bit=l&~(-BITS);
                if (reloc_table[pos] & target_ucell((ucell)1ULL << bit)) {
			// printk("%lx, pos %x, bit %d\n",*walk, pos, bit);
			write_ucell(walk, read_ucell(walk)+pointer2cell(dict));
		}
	}

#ifdef CONFIG_DEBUG_DICTIONARY
	printk(" done.\n");
#endif

	last = (ucell *)(dict + target_ucell(header->last));

	return -1;
}
示例#2
0
void init_trampoline(ucell *tramp)
{
    tramp[0] = DOCOL;
    tramp[1] = 0;
    tramp[2] = target_ucell(pointer2cell(tramp) + 3 * sizeof(ucell));
    tramp[3] = 0;
}
示例#3
0
static void execute(void)
{                               /* EXECUTE */
    ucell address = POP();
    dbg_interp_printk("execute: %x\n", address);

    PUSHR(PC);
    trampoline[1] = target_ucell(address);
    PC = pointer2cell(trampoline);
}
示例#4
0
/*
 * Compare two dictionaries constructed at different addresses. When
 * the cells don't match, a need for relocation is detected and the
 * corresponding bit in reloc_table bitmap is set.
 */
static void relocation_table(unsigned char * dict_one, unsigned char *dict_two, int length)
{
	ucell *d1=(ucell *)dict_one, *d2=(ucell *)dict_two;
	ucell *reloc_table;
	int pos, bit;
	int l=(length+(sizeof(cell)-1))/sizeof(ucell), i;

	/* prepare relocation table */
	relocation_length=(length+BITS-1)/BITS;
	reloc_table = malloc(relocation_length*sizeof(cell));
	memset(reloc_table,0,relocation_length*sizeof(cell));

	for (i=0; i<l; i++) {

		pos=i/BITS;
		bit=i&~(-BITS);

		if(d1[i]==d2[i]) {
                        reloc_table[pos] &= target_ucell(~((ucell)1ULL << bit));

			// This check might bring false positives in data.
			//if(d1[i] >= pointer2cell(dict_one) &&
			//		d1[i] <= pointer2cell(dict_one+length))
			//	printk("\nWARNING: inconsistent relocation (%x:%x)!\n", d1[i], d2[i]);
		} else {
			/* This is a pointer, it needs relocation, d2==dict */
                        reloc_table[pos] |= target_ucell((ucell)1ULL << bit);
			d2[i] = target_ucell(target_ucell(d2[i]) - pointer2cell(d2));
		}
	}

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("dict1 %lx dict2 %lx dict %lx\n",dict_one, dict_two, dict);
	for (i=0; i< relocation_length ; i++)
		printk("reloc %d %lx\n",i+1, reloc_table[i]);
#endif
	relocation_address=reloc_table;
}
示例#5
0
int enterforth(xt_t xt)
{
    ucell *_cfa = (ucell*)cell2pointer(xt);
    cell tmp;

    if (read_ucell(_cfa) != DOCOL) {
        trampoline[1] = target_ucell(xt);
        _cfa = trampoline;
    }

    if (rstackcnt < 0) {
        rstackcnt = 0;
    }

    tmp = rstackcnt;
    interruptforth = FORTH_INTSTAT_CLR;

    PUSHR(PC);
    PC = pointer2cell(_cfa);

    while (rstackcnt > tmp && !(interruptforth & FORTH_INTSTAT_STOP)) {
        if (debug_xt_list->next == NULL) {
            while (rstackcnt > tmp && !interruptforth) {
                dbg_interp_printk("enterforth: NEXT\n");
                next();
            }
        } else {
            while (rstackcnt > tmp && !interruptforth) {
                dbg_interp_printk("enterforth: NEXT_DBG\n");
                next_dbg();
            }
        }

        /* Always clear the debug mode change flag */
        interruptforth = interruptforth & (~FORTH_INTSTAT_DBG);
    }

#if 0
    /* return true if we took an exception. The caller should normally
     * handle exceptions by returning immediately since the throw
     * is supposed to abort the execution of this C-code too.
     */

    if (rstackcnt != tmp) {
        printk("EXCEPTION DETECTED!\n");
    }
#endif
    return rstackcnt != tmp;
}
示例#6
0
static int build_dictionary(void)
{
	ucell lfa = 0;
	unsigned int i;

	/* we need a temporary place for latest outside the dictionary */
	latest = &lfa;

	/* starting a new dictionary: clear dicthead */
	dicthead = 0;

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("building dictionary, %d primitives.\nbuilt words:",
	       sizeof(wordnames) / sizeof(void *));
#endif

	for (i = 0; i < sizeof(wordnames) / sizeof(void *); i++) {
		if (strlen(wordnames[i]) != 0) {
			fcreate((char *) wordnames[i], i);
#ifdef CONFIG_DEBUG_DICTIONARY
			printk(" %s", wordnames[i]);
#endif
		}
	}
#ifdef CONFIG_DEBUG_DICTIONARY
	printk(".\n");
#endif

	/* get last/latest and state */
	state = buildvariable("state", 0);
	last = buildvariable("forth-last", 0);
	latest = buildvariable("latest", 0);

	*latest = target_ucell(pointer2cell(latest)-2*sizeof(cell));

	base=buildvariable("base", 10);

	buildconstant("/c", sizeof(u8));
	buildconstant("/w", sizeof(u16));
	buildconstant("/l", sizeof(u32));
	buildconstant("/n", sizeof(ucell));
	buildconstant("/x", sizeof(u64));

	reveal();
        if (verbose) {
                printk("Dictionary initialization finished.\n");
        }
	return 0;
}
示例#7
0
static void fcreate(const char *word, ucell cfaval)
{
	if (strlen(word) == 0) {
		printk("WARNING: tried to create unnamed word.\n");
		return;
	}

	writestring(word);
	/* get us at least 1 byte for flags */
	writebyte(0);
	paddict(sizeof(cell));
	/* set flags high bit. */
	dict[dicthead - 1] = 128;
	/* lfa and cfa */
	writecell(read_ucell(latest));
	*latest = target_ucell(pointer2cell(dict) + dicthead - sizeof(cell));
	writecell(cfaval);
}
示例#8
0
static void write_dictionary(const char *filename)
{
	FILE *f;
	unsigned char *write_data, *walk_data;
	int  write_len;
	dictionary_header_t *header;
	u32 checksum=0;

	/*
	 * get memory for dictionary
	 */

	write_len  = sizeof(dictionary_header_t)+dicthead+relocation_length*sizeof(cell);
	write_data = malloc(write_len);
	if(!write_data) {
		printk("panic: can't allocate memory for output dictionary (%d"
			" bytes\n", write_len);
		exit(1);
	}
	memset(write_data, 0, write_len);

	/*
	 * prepare dictionary header
	 */

	header = (dictionary_header_t *)write_data;
	*header = (dictionary_header_t){
		.signature	= DICTID,
		.version	= 2,
		.cellsize	= sizeof(ucell),
#ifdef CONFIG_BIG_ENDIAN
		.endianess	= -1,
#else
		.endianess	= 0,
#endif
		.checksum	= 0,
		.compression	= 0,
		.relocation	= -1,
                .length         = target_ulong((uint32_t)dicthead),
                .last           = target_ucell((ucell)((unsigned long)last
                                                       - (unsigned long)dict)),
	};

	/*
	 * prepare dictionary data
	 */

	walk_data=write_data+sizeof(dictionary_header_t);
	memcpy (walk_data, dict, dicthead);

	/*
	 * prepare relocation data.
	 * relocation_address is zero when writing a dictionary core.
	 */

	if (relocation_address) {
#ifdef CONFIG_DEBUG_DICTIONARY
		printk("writing %d reloc cells \n",relocation_length);
#endif
		walk_data += dicthead;
		memcpy(walk_data, relocation_address,
				relocation_length*sizeof(cell));
		/* free relocation information */
		free(relocation_address);
		relocation_address=NULL;
	} else {
		header->relocation=0;
	}

	/*
	 * Calculate Checksum
	 */

	walk_data=write_data;
	while (walk_data<write_data+write_len) {
		checksum+=read_long(walk_data);
		walk_data+=sizeof(u32);
	}
	checksum=(u32)-checksum;

	header->checksum=target_long(checksum);

        if (verbose) {
                dump_header(header);
        }

	f = fopen(filename, "w");
	if (!f) {
		printk("panic: can't write to dictionary '%s'.\n", filename);
		exit(1);
	}

	fwrite(write_data, write_len, 1, f);

	free(write_data);
	fclose(f);

#ifdef CONFIG_DEBUG_DICTIONARY
	printk("wrote dictionary to file %s.\n", filename);
#endif
}

/*
 * Write dictionary as a list of ucell hex values to filename. Array
 * header and end lines are not generated.
 *
 * Cells with relocations are output using the expression
 * DICTIONARY_BASE + value.
 *
 * Define some helpful constants.
 */
static void write_dictionary_hex(const char *filename)
{
    FILE *f;
    ucell *walk;

    f = fopen(filename, "w");
    if (!f) {
        printk("panic: can't write to dictionary '%s'.\n", filename);
        exit(1);
    }

    for (walk = (ucell *)dict; walk < (ucell *)(dict + dicthead); walk++) {
        int pos, bit, l;
        ucell val;

        l = (walk - (ucell *)dict);
        pos = l / BITS;
        bit = l & ~(-BITS);

        val = read_ucell(walk);
        if (relocation_address[pos] & target_ucell((ucell)1ULL << bit)) {
            fprintf(f, "DICTIONARY_BASE + 0x%" FMT_CELL_x
                    ",\n", val);
        } else {
            fprintf(f, "0x%" FMT_CELL_x",\n", val);
        }
    }

    fprintf(f, "#define FORTH_DICTIONARY_LAST 0x%" FMT_CELL_x"\n",
            (ucell)((unsigned long)last - (unsigned long)dict));
    fprintf(f, "#define FORTH_DICTIONARY_END 0x%" FMT_CELL_x"\n",
            (ucell)dicthead);
    fclose(f);

#ifdef CONFIG_DEBUG_DICTIONARY
    printk("wrote dictionary to file %s.\n", filename);
#endif
}