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)); }
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 }