aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2014-03-18 05:29:27 -0400
committerAnton Blanchard <anton@samba.org>2014-04-22 20:05:29 -0400
commit0906584a0a4b689f6e80307f699247621321670a (patch)
treec9ec428bd8f41c604160d937e294cfd4c287cb38
parent4edebbeae3085e71f75584b6582495459e2e6cb2 (diff)
powerpc: Handle new ELFv2 module relocations
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>
-rw-r--r--arch/powerpc/include/uapi/asm/elf.h7
-rw-r--r--arch/powerpc/kernel/module_64.c17
2 files changed, 23 insertions, 1 deletions
diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h
index 0341109e4395..59dad113897b 100644
--- a/arch/powerpc/include/uapi/asm/elf.h
+++ b/arch/powerpc/include/uapi/asm/elf.h
@@ -295,8 +295,13 @@ do { \
295#define R_PPC64_TLSLD 108 295#define R_PPC64_TLSLD 108
296#define R_PPC64_TOCSAVE 109 296#define R_PPC64_TOCSAVE 109
297 297
298#define R_PPC64_REL16 249
299#define R_PPC64_REL16_LO 250
300#define R_PPC64_REL16_HI 251
301#define R_PPC64_REL16_HA 252
302
298/* Keep this the last entry. */ 303/* Keep this the last entry. */
299#define R_PPC64_NUM 110 304#define R_PPC64_NUM 253
300 305
301/* There's actually a third entry here, but it's unused */ 306/* There's actually a third entry here, but it's unused */
302struct ppc64_opd_entry 307struct ppc64_opd_entry
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index f6544d7071d6..34ba326ccc30 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -491,6 +491,23 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
491 */ 491 */
492 break; 492 break;
493 493
494 case R_PPC64_REL16_HA:
495 /* Subtract location pointer */
496 value -= (unsigned long)location;
497 value = ((value + 0x8000) >> 16);
498 *((uint16_t *) location)
499 = (*((uint16_t *) location) & ~0xffff)
500 | (value & 0xffff);
501 break;
502
503 case R_PPC64_REL16_LO:
504 /* Subtract location pointer */
505 value -= (unsigned long)location;
506 *((uint16_t *) location)
507 = (*((uint16_t *) location) & ~0xffff)
508 | (value & 0xffff);
509 break;
510
494 default: 511 default:
495 printk("%s: Unknown ADD relocation: %lu\n", 512 printk("%s: Unknown ADD relocation: %lu\n",
496 me->name, 513 me->name,