--- zzzz-none-000/linux-2.6.28.10/arch/arm/kernel/module.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/arch/arm/kernel/module.c 2012-07-10 08:42:59.000000000 +0000 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ #endif #ifdef CONFIG_MMU -void *module_alloc(unsigned long size) +void *module_alloc(unsigned long size, char *name __attribute__ ((unused)), enum _module_alloc_type_ type __attribute__ ((unused))) { struct vm_struct *area; @@ -50,7 +51,7 @@ return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); } #else /* CONFIG_MMU */ -void *module_alloc(unsigned long size) +void *module_alloc(unsigned long size, char *name __attribute__ ((unused)), enum _module_alloc_type_ type __attribute__ ((unused))) { return size == 0 ? NULL : vmalloc(size); } @@ -105,13 +106,34 @@ switch (ELF32_R_TYPE(rel->r_info)) { case R_ARM_ABS32: - *(u32 *)loc += sym->st_value; + if(loc & 0x3) { + /*--- supress unaligned trap-handling ---*/ + u32 tmp = extract_unaligned_dword((u32 *)loc); + set_unaligned_dword((u32 *)loc, tmp + sym->st_value); + } else { + *(u32 *)loc += sym->st_value; + } + break; + + case R_ARM_REL32: /*--- neu für GCC 4.4.1 ---*/ + offset = *(u32 *)loc + sym->st_value - loc; + if(loc & 0x3) { + /*--- supress unaligned trap-handling ---*/ + set_unaligned_dword((u32 *)loc, offset & 0xFFFFFFFF); + } else { + *(u32 *)loc = offset & 0xFFFFFFFF; + } break; case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: - offset = (*(u32 *)loc & 0x00ffffff) << 2; + if(loc & 0x3) { + /*--- supress unaligned trap-handling ---*/ + offset = (extract_unaligned_dword((u32 *)loc) & 0x00ffffff) << 2; + } else { + offset = (*(u32 *)loc & 0x00ffffff) << 2; + } if (offset & 0x02000000) offset -= 0x04000000; @@ -128,8 +150,16 @@ offset >>= 2; - *(u32 *)loc &= 0xff000000; - *(u32 *)loc |= offset & 0x00ffffff; + if(loc & 0x3) { + /*--- supress unaligned trap-handling ---*/ + u32 tmp = extract_unaligned_dword((u32 *)loc); + tmp &= 0xff000000; + tmp |= offset & 0x00ffffff; + set_unaligned_dword((u32 *)loc, tmp); + } else { + *(u32 *)loc &= 0xff000000; + *(u32 *)loc |= offset & 0x00ffffff; + } break; default: