--- /tmp/module.c 2009-11-03 20:30:56.000000000 +0100 +++ git/arch/arm/kernel/module.c 2009-11-03 20:34:33.000000000 +0100 @@ -83,6 +83,7 @@ unsigned long loc; Elf32_Sym *sym; s32 offset; + s32 addend; offset = ELF32_R_SYM(rel->r_info); if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { @@ -132,6 +133,22 @@ *(u32 *)loc |= offset & 0x00ffffff; break; + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + offset = sym->st_value; + + addend = ((*(u32 *)loc >> 4) & 0xf000) | (*(u32 *)loc &0xfff); + addend = (addend ^ 0x8000) - 0x8000; + offset += addend; + + if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) + offset >>= 16; + + *(u32 *)loc &= 0xfff0f000; + *(u32 *)loc |= offset & 0xfff; + *(u32 *)loc |= (offset & 0xf000) << 4; + break; + default: printk(KERN_ERR "%s: unknown relocation: %u\n", module->name, ELF32_R_TYPE(rel->r_info));