Module Name: src Committed By: skrll Date: Tue Aug 27 06:39:43 UTC 2013
Modified Files: src/sys/arch/arm/arm32: kobj_machdep.c Log Message: Support R_ARM_REL32 and R_ARM_PREL31. ok matt. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 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.7 src/sys/arch/arm/arm32/kobj_machdep.c:1.8 --- src/sys/arch/arm/arm32/kobj_machdep.c:1.7 Fri Aug 9 07:12:42 2013 +++ src/sys/arch/arm/arm32/kobj_machdep.c Tue Aug 27 06:39:43 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: kobj_machdep.c,v 1.7 2013/08/09 07:12:42 matt Exp $ */ +/* $NetBSD: kobj_machdep.c,v 1.8 2013/08/27 06:39:43 skrll 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.7 2013/08/09 07:12:42 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.8 2013/08/27 06:39:43 skrll Exp $"); #define ELFSIZE ARCH_ELFSIZE @@ -118,7 +118,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas *where = addr; return 0; - case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVW_ABS_NC: /* (S + A) | T */ case R_ARM_MOVT_ABS: if ((*where & 0x0fb00000) != 0x03000000) break; @@ -131,9 +131,9 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas | ((addr << 4) & 0x000f0000) | (addr & 0x00000fff); return 0; - case R_ARM_CALL: + case R_ARM_CALL: /* ((S + A) | T) - P */ case R_ARM_JUMP24: - case R_ARM_PC24: + case R_ARM_PC24: /* Deprecated */ if (local && (*where & 0x00ffffff) != 0x00fffffe) return 0; @@ -165,6 +165,36 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas *where = (*where & 0xff000000) | ((addend >> 2) & 0x00ffffff); return 0; + case R_ARM_REL32: /* ((S + A) | T) - P */ + /* T = 0 for now */ + addr = kobj_sym_lookup(ko, symidx); + if (addr == 0) + break; + + addend += (uintptr_t)addr - (uintptr_t)where; + *where = addend; + return 0; + + case R_ARM_PREL31: /* ((S + A) | T) - P */ + /* 42 R_ARM_PREL31 4 sign_extend(P[30:0]) 31 - bit 2's complement */ + /* Sign extend if necessary */ + if (addend & 0x40000000) + addend |= 0xc0000000; + /* T = 0 for now */ + addr = kobj_sym_lookup(ko, symidx); + if (addr == 0) + break; + + addend += (uintptr_t)addr - (uintptr_t)where; + + if ((addend & 0x80000000) != 0x00000000 && + (addend & 0x80000000) != 0x80000000) { + printf ("Relocation %x too far @ %p\n", addend, where); + return -1; + } + + *where = (*where & 0x80000000) | (addend & 0x7fffffff); + default: break; }