Beispiel #1
0
void dump_header(dictionary_header_t *header)
{
	printk("EvangelionBIOS dictionary:\n");
	printk("  version:     %d\n", header->version);
	printk("  cellsize:    %d\n", header->cellsize);
	printk("  endianess:   %s\n", header->endianess?"big":"little");
	printk("  compression: %s\n", header->compression?"yes":"no");
	printk("  relocation:  %s\n", header->relocation?"yes":"no");
	printk("  checksum:    %08x\n", target_long(header->checksum));
	printk("  length:      %08x\n", target_long(header->length));
	printk("  last:        %0" FMT_CELL_x "\n", target_cell(header->last));
}
Beispiel #2
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;
}
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
}