Module Name:    src
Committed By:   dsl
Date:           Mon Aug 17 19:44:32 UTC 2009

Modified Files:
        src/sys/arch/arm/arm32: kobj_machdep.c

Log Message:
Add support for R_ARM_PC24 relocations and fix R_ARM_ABS32.
Changes from PR/40309, but structure changed so there is a common error printf.
Compiles ok, but my quick kernel build failed to find module_init_md().


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 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.2 src/sys/arch/arm/arm32/kobj_machdep.c:1.3
--- src/sys/arch/arm/arm32/kobj_machdep.c:1.2	Mon Apr 28 20:23:13 2008
+++ src/sys/arch/arm/arm32/kobj_machdep.c	Mon Aug 17 19:44:32 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.2 2008/04/28 20:23:13 martin Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.3 2009/08/17 19:44:32 dsl 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.2 2008/04/28 20:23:13 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.3 2009/08/17 19:44:32 dsl Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -91,44 +91,64 @@
 
 	switch (rtype) {
 	case R_ARM_NONE:	/* none */
-		break;
+		return 0;
 
 	case R_ARM_ABS32:
 		addr = kobj_sym_lookup(ko, symidx);
 		if (addr == 0)
-			return -1;
-		if (*where != addr)
-			*where = addr;
-
-		break;
+			break;
+		*where = addr + addend;
+		return 0;
 
 	case R_ARM_COPY:	/* none */
-		/*
-		 * There shouldn't be copy relocations in kernel
-		 * objects.
-		 */
-		printf("kobj_reloc: unexpected R_COPY relocation\n");
-		return -1;
+		/* There shouldn't be copy relocations in kernel objects. */
+		break;
 
 	case R_ARM_JUMP_SLOT:
 		addr = kobj_sym_lookup(ko, symidx);
-		if (addr) {
-			*where = addr;
-			return 0;
-		}
-		return -1;
+		if (addr == 0)
+			break;
+		*where = addr;
+		return 0;
 
 	case R_ARM_RELATIVE:	/* A + B */
 		addr = relocbase + addend;
 		if (*where != addr)
 			*where = addr;
-		break;
+		return 0;
+
+	case R_ARM_PC24:
+		if (local)
+			return 0;
+
+		/* Remove the instruction from the 24 bit offset */
+		addend &= 0x00ffffff;
+
+		/* Sign extend if necessary */
+		if (addend & 0x00800000)
+			addend |= 0xff000000;
+
+		addr = kobj_sym_lookup(ko, symidx);
+		if (addr == 0)
+			break;
+
+		addend += ((uint32_t *)addr - (uint32_t *)where);
+
+		if ((addend & 0xff800000) != 0x00000000 &&
+		    (addend & 0xff800000) != 0xff800000) {
+			printf ("Relocation %x too far @ %p\n", addend, where);
+			return -1;
+		}
+		*where = (*where & 0xff000000) | (addend & 0x00ffffff);
+		return 0;
 
 	default:
-		printf("kobj_reloc: unexpected relocation type %d\n", rtype);
-		return -1;
+		break;
 	}
-	return 0;
+
+	printf("kobj_reloc: unexpected/invalid relocation type %d @ %p symidx %u\n",
+	    rtype, where, symidx);
+	return -1;
 }
 
 int

Reply via email to