Hi everyone,
I'm trying to check the the forth dictionary is being loaded correctly on Sparc64, and I'm struggling to understand the dynamic relocation code from kernel/dict.c:
==== cut ====
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(1UL<<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
==== cut ====
Stepping through with the debugger, l appears to be a count of the number of words from the beginning of the dictionary, pos is set to either 0 or 1 depending upon whether the word offset is a multiple of the target word size and bit is a modulo of l, again based upon the word size.
It looks as if bit is being used to set up a shifting bit mask up to the word size in bits, and it is based upon the interaction of this and reloc_table[pos] which decides whether any code is moved.
Can anyone shed any light on exactly what this code does, and how it actually does it? The part that confuses me the most is that decisions are being made on which words to relocate, but these criteria are based upon some strange combination of arithmetic involving the current offset and the target word size.
Many thanks,
Mark.