Module Name: src Committed By: matt Date: Wed Aug 7 18:36:19 UTC 2013
Modified Files: src/sys/arch/arm/arm32: kobj_machdep.c Log Message: Add R_ARM_V4BX, R_ARM_MOVW_ABS_NC, R_ARM_MOVT_ABS Fix R_ARM_PC24 and match R_ARM_CALL and R_ARM_JUMP24 To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/arm32/kobj_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm32/kobj_machdep.c diff -u src/sys/arch/arm/arm32/kobj_machdep.c:1.3 src/sys/arch/arm/arm32/kobj_machdep.c:1.4 --- src/sys/arch/arm/arm32/kobj_machdep.c:1.3 Mon Aug 17 19:44:32 2009 +++ src/sys/arch/arm/arm32/kobj_machdep.c Wed Aug 7 18:36:19 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kobj_machdep.c,v 1.3 2009/08/17 19:44:32 dsl Exp $ */ +/* $NetBSD: kobj_machdep.c,v 1.4 2013/08/07 18:36:19 matt Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -52,7 +52,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.3 2009/08/17 19:44:32 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.4 2013/08/07 18:36:19 matt Exp $"); #define ELFSIZE ARCH_ELFSIZE @@ -91,6 +91,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas switch (rtype) { case R_ARM_NONE: /* none */ + case R_ARM_V4BX: /* none */ return 0; case R_ARM_ABS32: @@ -117,8 +118,21 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas *where = addr; return 0; + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + addr = kobj_sym_lookup(ko, symidx); + if (addr == 0) + break; + if (rtype == R_ARM_MOVT_ABS) + addr >>= 16; + *where = (*where & 0xfff0f000) + | ((addr << 4) & 0x000f0000) | (addr & 0x00000fff); + return 0; + + case R_ARM_CALL: + case R_ARM_JUMP24: case R_ARM_PC24: - if (local) + if (local && (*where & 0x00ffffff) != 0x00fffffe) return 0; /* Remove the instruction from the 24 bit offset */ @@ -128,18 +142,25 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas if (addend & 0x00800000) addend |= 0xff000000; + addend <<= 2; + addr = kobj_sym_lookup(ko, symidx); if (addr == 0) break; addend += ((uint32_t *)addr - (uint32_t *)where); - if ((addend & 0xff800000) != 0x00000000 && - (addend & 0xff800000) != 0xff800000) { + if (addend & 3) { + printf ("Relocation %x unaligned @ %p\n", addend, where); + return -1; + } + + if ((addend & 0xfe000000) != 0x00000000 && + (addend & 0xfe000000) != 0xfe000000) { printf ("Relocation %x too far @ %p\n", addend, where); return -1; } - *where = (*where & 0xff000000) | (addend & 0x00ffffff); + *where = (*where & 0xff000000) | ((addend >> 2) & 0x00ffffff); return 0; default: