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;
 	}

Reply via email to