Module Name:    src
Committed By:   skrll
Date:           Sat Feb  1 08:05:51 UTC 2014

Modified Files:
        src/sys/arch/hppa/hppa: kobj_machdep.c

Log Message:
Deal with unaligned DIR32 relocs as found in debug information.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/hppa/hppa/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/hppa/hppa/kobj_machdep.c
diff -u src/sys/arch/hppa/hppa/kobj_machdep.c:1.13 src/sys/arch/hppa/hppa/kobj_machdep.c:1.14
--- src/sys/arch/hppa/hppa/kobj_machdep.c:1.13	Sat Nov 16 17:18:42 2013
+++ src/sys/arch/hppa/hppa/kobj_machdep.c	Sat Feb  1 08:05:51 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.13 2013/11/16 17:18:42 skrll Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.14 2014/02/01 08:05:51 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.13 2013/11/16 17:18:42 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.14 2014/02/01 08:05:51 skrll Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -97,6 +97,35 @@ RR(unsigned int x, unsigned int constant
         return R(x + RND(constant)) + (constant - RND(constant));
 }
 
+/*
+ * It is possible for the compiler to emit relocations for unaligned data.
+ * We handle this situation with these inlines.
+ */
+#define	RELOC_ALIGNED_P(x) \
+	(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
+
+static inline Elf_Addr
+load_ptr(void *where)
+{
+	if (__predict_true(RELOC_ALIGNED_P(where)))
+		return *(Elf_Addr *)where;
+	else {
+		Elf_Addr res;
+
+		(void)memcpy(&res, where, sizeof(res));
+		return res;
+	}
+}
+
+static inline void
+store_ptr(void *where, Elf_Addr val)
+{
+	if (__predict_true(RELOC_ALIGNED_P(where)))
+		*(Elf_Addr *)where = val;
+	else
+		(void)memcpy(where, &val, sizeof(val));
+}
+
 int
 kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
     bool isrela, bool local)
@@ -185,7 +214,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	case R_TYPE(PCREL32):
 	case R_TYPE(PLABEL32):
 	case R_TYPE(SEGREL32):
-		*where = value;
+		store_ptr(where, value);
 		break;
 
 	case R_TYPE(DIR14R):

Reply via email to