]> git.karo-electronics.de Git - linux-beck.git/commitdiff
powerpc: Handle new ELFv2 module relocations
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 18 Mar 2014 09:29:27 +0000 (19:59 +1030)
committerAnton Blanchard <anton@samba.org>
Wed, 23 Apr 2014 00:05:29 +0000 (10:05 +1000)
The new ELF ABI tends to use R_PPC64_REL16_LO and R_PPC64_REL16_HA
relocations (PC-relative), so implement them.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
arch/powerpc/include/uapi/asm/elf.h
arch/powerpc/kernel/module_64.c

index 0341109e439513b84d5ff7a3076d81fb90701719..59dad113897b0b65f6c616df175a596d901dab77 100644 (file)
@@ -295,8 +295,13 @@ do {                                                                       \
 #define R_PPC64_TLSLD          108
 #define R_PPC64_TOCSAVE                109
 
+#define R_PPC64_REL16          249
+#define R_PPC64_REL16_LO       250
+#define R_PPC64_REL16_HI       251
+#define R_PPC64_REL16_HA       252
+
 /* Keep this the last entry.  */
-#define R_PPC64_NUM            110
+#define R_PPC64_NUM            253
 
 /* There's actually a third entry here, but it's unused */
 struct ppc64_opd_entry
index f6544d7071d6b2a086bab27960f10f4cda65d99a..34ba326ccc307a9fab2e3559d766b7523552a5f4 100644 (file)
@@ -491,6 +491,23 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
                         */
                        break;
 
+               case R_PPC64_REL16_HA:
+                       /* Subtract location pointer */
+                       value -= (unsigned long)location;
+                       value = ((value + 0x8000) >> 16);
+                       *((uint16_t *) location)
+                               = (*((uint16_t *) location) & ~0xffff)
+                               | (value & 0xffff);
+                       break;
+
+               case R_PPC64_REL16_LO:
+                       /* Subtract location pointer */
+                       value -= (unsigned long)location;
+                       *((uint16_t *) location)
+                               = (*((uint16_t *) location) & ~0xffff)
+                               | (value & 0xffff);
+                       break;
+
                default:
                        printk("%s: Unknown ADD relocation: %lu\n",
                               me->name,