[ARM] 5428/1: Module relocation update for R_ARM_V4BX
authorDaniel Silverstone <dsilvers@simtec.co.uk>
Fri, 20 Mar 2009 10:11:43 +0000 (11:11 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 21 Mar 2009 11:22:33 +0000 (11:22 +0000)
It would seem when building kernel modules with modern binutils
(required by modern GCC) for ARM v4T targets (specifically observed
with the Samsung 24xx SoC which is an 920T) R_ARM_V4BX relocations
are emitted for function epilogues.

This manifests at module load time with an "unknown relocation: 40"
error message.

The following patch adds the R_ARM_V4BX relocation to the ARM kernel
module loader. The relocation operation is taken from that within the
binutils bfd library.

Signed-off-by: Simtec Linux Team <linux@simtec.co.uk>
Signed-off-by: Vincent Sanders <vince@simtec.co.uk>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/elf.h
arch/arm/kernel/module.c

index a58378c343b9d3143f5e0116808b2bd1f690ba41..ce3b36e9df81afffb6be14412d59dcbfd49abc7d 100644 (file)
@@ -50,6 +50,7 @@ typedef struct user_fp elf_fpregset_t;
 #define R_ARM_ABS32    2
 #define R_ARM_CALL     28
 #define R_ARM_JUMP24   29
+#define R_ARM_V4BX     40
 
 /*
  * These are used to set parameters in the core dumps.
index dab48f27263f0e20c2e3bdbaf2f1c5ffaf1a1c1f..9f509fd00fda40fab3888c6f6865e843052aedfe 100644 (file)
@@ -132,6 +132,15 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
                        *(u32 *)loc |= offset & 0x00ffffff;
                        break;
 
+              case R_ARM_V4BX:
+                      /* Preserve Rm and the condition code. Alter
+                       * other bits to re-code instruction as
+                       * MOV PC,Rm.
+                       */
+                      *(u32 *)loc &= 0xf000000f;
+                      *(u32 *)loc |= 0x01a0f000;
+                      break;
+
                default:
                        printk(KERN_ERR "%s: unknown relocation: %u\n",
                               module->name, ELF32_R_TYPE(rel->r_info));