Module Name:    src
Committed By:   maxv
Date:           Fri Nov  3 09:59:08 UTC 2017

Modified Files:
        src/sys/arch/alpha/alpha: kobj_machdep.c
        src/sys/arch/amd64/amd64: kobj_machdep.c
        src/sys/arch/arm/arm32: kobj_machdep.c
        src/sys/arch/hppa/hppa: kobj_machdep.c
        src/sys/arch/i386/i386: kobj_machdep.c
        src/sys/arch/m68k/m68k: kobj_machdep.c
        src/sys/arch/powerpc/powerpc: kobj_machdep.c
        src/sys/arch/riscv/riscv: kobj_machdep.c
        src/sys/arch/sh3/sh3: kobj_machdep.c
        src/sys/arch/sparc/sparc: kobj_machdep.c
        src/sys/arch/sparc64/sparc64: kobj_machdep.c
        src/sys/ddb: db_sym.c
        src/sys/kern: kern_ksyms.c subr_kobj.c
        src/sys/sys: kobj.h ksyms.h

Log Message:
Handle absolute relocations coming from the kernel: preserve SHN_ABS in
the kernel and module symbols, and when relocating a symbol that has
SHN_ABS, take its value as-is and don't return an error if it equals zero.

Sent on tech-kern@.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/alpha/alpha/kobj_machdep.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/amd64/amd64/kobj_machdep.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/arm32/kobj_machdep.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/hppa/hppa/kobj_machdep.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/i386/i386/kobj_machdep.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/m68k/m68k/kobj_machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/powerpc/kobj_machdep.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/riscv/riscv/kobj_machdep.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/sh3/sh3/kobj_machdep.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/sparc/sparc/kobj_machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/sparc64/sparc64/kobj_machdep.c
cvs rdiff -u -r1.64 -r1.65 src/sys/ddb/db_sym.c
cvs rdiff -u -r1.85 -r1.86 src/sys/kern/kern_ksyms.c
cvs rdiff -u -r1.62 -r1.63 src/sys/kern/subr_kobj.c
cvs rdiff -u -r1.16 -r1.17 src/sys/sys/kobj.h
cvs rdiff -u -r1.33 -r1.34 src/sys/sys/ksyms.h

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/alpha/alpha/kobj_machdep.c
diff -u src/sys/arch/alpha/alpha/kobj_machdep.c:1.2 src/sys/arch/alpha/alpha/kobj_machdep.c:1.3
--- src/sys/arch/alpha/alpha/kobj_machdep.c:1.2	Mon Apr 28 20:23:10 2008
+++ src/sys/arch/alpha/alpha/kobj_machdep.c	Fri Nov  3 09:59:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.2 2008/04/28 20:23:10 martin Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.3 2017/11/03 09:59:07 maxv 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:10 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.3 2017/11/03 09:59:07 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -72,6 +72,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	uintptr_t rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	if (isrela) {
 		rela = (const Elf_Rela *)data;
@@ -92,8 +93,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		break;
 
 	case R_ALPHA_REFQUAD:
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		addr += addend;
 		if (*where != addr)
@@ -101,8 +102,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		break;
 
 	case R_ALPHA_GLOB_DAT:
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		addr += addend;
 		if (*where != addr)
@@ -111,8 +112,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 	case R_ALPHA_JMP_SLOT:
 		/* No point in lazy binding for kernel modules. */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		if (*where != addr)
 			*where = addr;

Index: src/sys/arch/amd64/amd64/kobj_machdep.c
diff -u src/sys/arch/amd64/amd64/kobj_machdep.c:1.5 src/sys/arch/amd64/amd64/kobj_machdep.c:1.6
--- src/sys/arch/amd64/amd64/kobj_machdep.c:1.5	Mon Dec  8 08:41:36 2008
+++ src/sys/arch/amd64/amd64/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.5 2008/12/08 08:41:36 njoly Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.6 2017/11/03 09:59:08 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.5 2008/12/08 08:41:36 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.6 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -80,6 +80,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	uintptr_t rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	if (isrela) {
 		rela = (const Elf_Rela *)data;
@@ -110,16 +111,16 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		break;
 
 	case R_X86_64_64:		/* S + A */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		val = addr + addend;
 		*where = val;
 		break;
 
 	case R_X86_64_PC32:	/* S + A - P */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		where32 = (Elf32_Addr *)where;
 		val32 = (Elf32_Addr)(addr + addend - (Elf64_Addr)where);
@@ -128,8 +129,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 	case R_X86_64_32:	/* S + A */
 	case R_X86_64_32S:	/* S + A sign extend */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		val32 = (Elf32_Addr)(addr + addend);
 		where32 = (Elf32_Addr *)where;
@@ -138,8 +139,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 	case R_X86_64_GLOB_DAT:	/* S */
 	case R_X86_64_JUMP_SLOT:/* XXX need addend + offset */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		*where = addr;
 		break;

Index: src/sys/arch/arm/arm32/kobj_machdep.c
diff -u src/sys/arch/arm/arm32/kobj_machdep.c:1.11 src/sys/arch/arm/arm32/kobj_machdep.c:1.12
--- src/sys/arch/arm/arm32/kobj_machdep.c:1.11	Mon Jul 11 15:51:01 2016
+++ src/sys/arch/arm/arm32/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.11 2016/07/11 15:51:01 martin Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.12 2017/11/03 09:59:08 maxv 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.11 2016/07/11 15:51:01 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.12 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -78,6 +78,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Word rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	if (isrela) {
 		rela = (const Elf_Rela *)data;
@@ -99,8 +100,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		return 0;
 
 	case R_ARM_ABS32:
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			break;
 		*where = addr + addend;
 		return 0;
@@ -110,8 +111,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		break;
 
 	case R_ARM_JUMP_SLOT:
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			break;
 		*where = addr;
 		return 0;
@@ -126,8 +127,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	case R_ARM_MOVT_ABS:
 		if ((*where & 0x0fb00000) != 0x03000000)
 			break;
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			break;
 		if (rtype == R_ARM_MOVT_ABS)
 			addr >>= 16;
@@ -150,8 +151,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 		addend <<= 2;
 
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			break;
 
 		addend += (uintptr_t)addr - (uintptr_t)where;
@@ -171,8 +172,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 	case R_ARM_REL32:	/* ((S + A) | T) -  P */
 		/* T = 0 for now */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			break;
 
 		addend += (uintptr_t)addr - (uintptr_t)where;
@@ -184,8 +185,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		if (addend & 0x40000000)
 			addend |= 0xc0000000;
 		/* T = 0 for now */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			break;
 
 		addend += (uintptr_t)addr - (uintptr_t)where;

Index: src/sys/arch/hppa/hppa/kobj_machdep.c
diff -u src/sys/arch/hppa/hppa/kobj_machdep.c:1.14 src/sys/arch/hppa/hppa/kobj_machdep.c:1.15
--- src/sys/arch/hppa/hppa/kobj_machdep.c:1.14	Sat Feb  1 08:05:51 2014
+++ src/sys/arch/hppa/hppa/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.14 2014/02/01 08:05:51 skrll Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.15 2017/11/03 09:59:08 maxv 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.14 2014/02/01 08:05:51 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.15 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -155,52 +155,52 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 	case R_TYPE(DIR32):
 		/* symbol + addend */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value += addr;
 		break;
 
 	case R_TYPE(DIR21L):
 		/* LR(symbol, addend) */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value = LR(addr, value);
 		break;
 
 	case R_TYPE(DIR17R):
 	case R_TYPE(DIR14R):
 		/* RR(symbol, addend) */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value = RR(addr, value);
 		break;
 
 	case R_TYPE(PCREL32):
 	case R_TYPE(PCREL17F):
 		/* symbol - PC - 8 + addend */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value += addr - (Elf_Word)where - 8;
 		break;
 
 	case R_TYPE(DPREL21L):
 		/* LR(symbol - GP, addend) */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value = LR(addr - GP, value);
 		break;
 
 	case R_TYPE(DPREL14R):
 		/* RR(symbol - GP, addend) */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value = RR(addr - GP, value);
 		break;
 
 	case R_TYPE(PLABEL32):
 		/* fptr(symbol) */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value = addr;
 		break;
 
 	case R_TYPE(SEGREL32):
 		/* symbol - SB + addend */
 		/* XXX SB */
-		addr = kobj_sym_lookup(ko, symidx);
+		kobj_sym_lookup(ko, symidx, &addr);
 		value += addr;
 		break;
 

Index: src/sys/arch/i386/i386/kobj_machdep.c
diff -u src/sys/arch/i386/i386/kobj_machdep.c:1.7 src/sys/arch/i386/i386/kobj_machdep.c:1.8
--- src/sys/arch/i386/i386/kobj_machdep.c:1.7	Thu Jan  8 01:03:24 2009
+++ src/sys/arch/i386/i386/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.7 2009/01/08 01:03:24 pooka Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.8 2017/11/03 09:59:08 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.7 2009/01/08 01:03:24 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.8 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -79,6 +79,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Word rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	if (isrela) {
 		rela = (const Elf_Rela *)data;
@@ -99,22 +100,22 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		return 0;
 
 	case R_386_32:		/* S + A */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		addr += addend;
 		break;
 
 	case R_386_PC32:	/* S + A - P */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		addr += addend - (Elf_Addr)where;
 		break;
 
 	case R_386_GLOB_DAT:	/* S */
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		break;
 

Index: src/sys/arch/m68k/m68k/kobj_machdep.c
diff -u src/sys/arch/m68k/m68k/kobj_machdep.c:1.3 src/sys/arch/m68k/m68k/kobj_machdep.c:1.4
--- src/sys/arch/m68k/m68k/kobj_machdep.c:1.3	Thu Oct 14 16:33:50 2010
+++ src/sys/arch/m68k/m68k/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.3 2010/10/14 16:33:50 tsutsui Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.4 2017/11/03 09:59:08 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.3 2010/10/14 16:33:50 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.4 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -45,6 +45,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	uintptr_t addr, tmp;
 	int rtype, symnum;
 	const Elf_Rela *rela;
+	int error;
 
 	if (!isrela) {
 		printf("kobj_reloc: support only RELA relocations\n");
@@ -61,8 +62,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		break;
 
 	case R_TYPE(PC32):
-		addr = kobj_sym_lookup(ko, symnum);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symnum, &addr);
+		if (error)
 			return -1;
 		tmp = (Elf_Addr)(addr + rela->r_addend) - (Elf_Addr)where;
 		if (*where != tmp)
@@ -71,8 +72,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 
 	case R_TYPE(32):
 	case R_TYPE(GLOB_DAT):
-		addr = kobj_sym_lookup(ko, symnum);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symnum, &addr);
+		if (error)
 			return -1;
 		tmp = (Elf_Addr)(addr + *where + rela->r_addend);
 		*where = tmp;

Index: src/sys/arch/powerpc/powerpc/kobj_machdep.c
diff -u src/sys/arch/powerpc/powerpc/kobj_machdep.c:1.6 src/sys/arch/powerpc/powerpc/kobj_machdep.c:1.7
--- src/sys/arch/powerpc/powerpc/kobj_machdep.c:1.6	Thu Mar  6 09:22:52 2014
+++ src/sys/arch/powerpc/powerpc/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.6 2014/03/06 09:22:52 matt Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.7 2017/11/03 09:59:08 maxv 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.6 2014/03/06 09:22:52 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.7 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -75,6 +75,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Sword addend;		/* needs to be signed */
 	u_int rtype, symidx;
 	const Elf_Rela *rela;
+	int error;
 
 	if (!isrela) {
 		panic("kobj_reloc: REL relocations not supported");
@@ -114,9 +115,9 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	case R_PPC_ADDR16_LO:	/* half16 #lo(S + A) */
 	case R_PPC_ADDR16_HA:	/* half16 #ha(S + A) */
 	case R_PPC_ADDR16_HI:	/* half16 #hi(S + A) */
-		addr = kobj_sym_lookup(ko, symidx);
-	       	if (addr == 0)
-	       		return -1;
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
+			return -1;
 
 #if 0
 		/*

Index: src/sys/arch/riscv/riscv/kobj_machdep.c
diff -u src/sys/arch/riscv/riscv/kobj_machdep.c:1.1 src/sys/arch/riscv/riscv/kobj_machdep.c:1.2
--- src/sys/arch/riscv/riscv/kobj_machdep.c:1.1	Sat Mar 28 16:13:56 2015
+++ src/sys/arch/riscv/riscv/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 
-__RCSID("$NetBSD: kobj_machdep.c,v 1.1 2015/03/28 16:13:56 matt Exp $");
+__RCSID("$NetBSD: kobj_machdep.c,v 1.2 2017/11/03 09:59:08 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,6 +57,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Sword addend = rela->r_addend;	/* needs to be signed */
 	const u_int rtype = ELF_R_TYPE(rela->r_info);
 	const u_int symidx = ELF_R_SYM(rela->r_info);
+	int error;
 
 	switch (rtype) {
 	case R_RISCV_NONE:
@@ -81,9 +82,10 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 #endif
 	case R_RISCV_LO12_I:
 	case R_RISCV_LO12_S: {
-		Elf_Addr addr = kobj_sym_lookup(ko, symidx);
-	       	if (addr == 0)
-	       		return -1;
+		Elf_Addr addr;
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
+			return -1;
 
 #if 0
 		/*

Index: src/sys/arch/sh3/sh3/kobj_machdep.c
diff -u src/sys/arch/sh3/sh3/kobj_machdep.c:1.4 src/sys/arch/sh3/sh3/kobj_machdep.c:1.5
--- src/sys/arch/sh3/sh3/kobj_machdep.c:1.4	Fri Nov 21 23:18:11 2008
+++ src/sys/arch/sh3/sh3/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.4 2008/11/21 23:18:11 uwe Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.5 2017/11/03 09:59:08 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.4 2008/11/21 23:18:11 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.5 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -47,6 +47,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Addr *where;
 	uintptr_t addr, tmp;
 	int symidx, rtype;
+	int error;
 
 	if (!isrela) {
 		printf("kobj_reloc: support only RELA relocations\n");
@@ -63,8 +64,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 		break;
 
 	case R_TYPE(DIR32):
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 
 		tmp = (Elf_Addr)(addr + *where + rela->r_addend);

Index: src/sys/arch/sparc/sparc/kobj_machdep.c
diff -u src/sys/arch/sparc/sparc/kobj_machdep.c:1.3 src/sys/arch/sparc/sparc/kobj_machdep.c:1.4
--- src/sys/arch/sparc/sparc/kobj_machdep.c:1.3	Sun Jun 12 01:29:58 2011
+++ src/sys/arch/sparc/sparc/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.3 2011/06/12 01:29:58 mrg Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.4 2017/11/03 09:59:08 maxv Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2002, 2008 The NetBSD Foundation, Inc.
@@ -130,6 +130,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Word value, mask;
 	uintptr_t tmp, addr;
 	u_int symidx, type;
+	int error;
 
 	rela = data;
 	where = (Elf_Addr *) (relocbase + rela->r_offset);
@@ -157,8 +158,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	}
 
 	if (RELOC_RESOLVE_SYMBOL(type)) {
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		value += addr;
 	}

Index: src/sys/arch/sparc64/sparc64/kobj_machdep.c
diff -u src/sys/arch/sparc64/sparc64/kobj_machdep.c:1.6 src/sys/arch/sparc64/sparc64/kobj_machdep.c:1.7
--- src/sys/arch/sparc64/sparc64/kobj_machdep.c:1.6	Mon Aug 29 15:57:07 2016
+++ src/sys/arch/sparc64/sparc64/kobj_machdep.c	Fri Nov  3 09:59:08 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj_machdep.c,v 1.6 2016/08/29 15:57:07 martin Exp $	*/
+/*	$NetBSD: kobj_machdep.c,v 1.7 2017/11/03 09:59:08 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2001 Jake Burkholder.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.6 2016/08/29 15:57:07 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.7 2017/11/03 09:59:08 maxv Exp $");
 
 #define	ELFSIZE		ARCH_ELFSIZE
 
@@ -190,6 +190,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	Elf_Addr mask;
 	Elf_Addr addr;
 	vaddr_t base;
+	int error;
 
 	if (!isrela)
 		return -1;
@@ -224,8 +225,8 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
 	value = rela->r_addend;
 
 	if (RELOC_RESOLVE_SYMBOL(rtype)) {
-		addr = kobj_sym_lookup(ko, symidx);
-		if (addr == 0)
+		error = kobj_sym_lookup(ko, symidx, &addr);
+		if (error)
 			return -1;
 		value += addr;
 	}

Index: src/sys/ddb/db_sym.c
diff -u src/sys/ddb/db_sym.c:1.64 src/sys/ddb/db_sym.c:1.65
--- src/sys/ddb/db_sym.c:1.64	Fri Feb 10 02:14:04 2012
+++ src/sys/ddb/db_sym.c	Fri Nov  3 09:59:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: db_sym.c,v 1.64 2012/02/10 02:14:04 christos Exp $	*/
+/*	$NetBSD: db_sym.c,v 1.65 2017/11/03 09:59:07 maxv Exp $	*/
 
 /*
  * Mach Operating System
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_sym.c,v 1.64 2012/02/10 02:14:04 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_sym.c,v 1.65 2017/11/03 09:59:07 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddbparam.h"
@@ -112,12 +112,12 @@ db_value_of_name(const char *name, db_ex
 	(void)strlcpy(symbol, name, sizeof(symbol));
 	db_symsplit(symbol, &mod, &sym);
 #ifdef _KERNEL
-	if (ksyms_getval_unlocked(mod, sym, &uval, KSYMS_EXTERN) == 0) {
+	if (ksyms_getval_unlocked(mod, sym, NULL, &uval, KSYMS_EXTERN) == 0) {
 		val = (long) uval;
 		*valuep = (db_expr_t)val;
 		return true;
 	}
-	if (ksyms_getval_unlocked(mod, sym, &uval, KSYMS_ANY) == 0) {
+	if (ksyms_getval_unlocked(mod, sym, NULL, &uval, KSYMS_ANY) == 0) {
 		val = (long) uval;
 		*valuep = (db_expr_t)val;
 		return true;
@@ -239,7 +239,7 @@ db_search_symbol(db_addr_t val, db_strat
 
 #ifdef _KERNEL
 	if (ksyms_getname(&mod, &sym, (vaddr_t)val, strategy) == 0) {
-		(void)ksyms_getval_unlocked(mod, sym, &naddr, KSYMS_ANY);
+		(void)ksyms_getval_unlocked(mod, sym, NULL, &naddr, KSYMS_ANY);
 		diff = val - (db_addr_t)naddr;
 		ret = (db_sym_t)naddr;
 	} else
@@ -346,7 +346,7 @@ db_symstr(char *buf, size_t buflen, db_e
 #ifdef _KERNEL
 	if (ksyms_getname(&mod, &name, (vaddr_t)off,
 	    strategy|KSYMS_CLOSEST) == 0) {
-		(void)ksyms_getval_unlocked(mod, name, &val, KSYMS_ANY);
+		(void)ksyms_getval_unlocked(mod, name, NULL, &val, KSYMS_ANY);
 		if (((off - val) < db_maxoff) && val) {
 			snprintf(buf, buflen, "%s:%s", mod, name);
 			if (off - val) {
@@ -417,7 +417,7 @@ db_printsym(db_expr_t off, db_strategy_t
 #ifdef _KERNEL
 	if (ksyms_getname(&mod, &name, (vaddr_t)off,
 	    strategy|KSYMS_CLOSEST) == 0) {
-		(void)ksyms_getval_unlocked(mod, name, &uval, KSYMS_ANY);
+		(void)ksyms_getval_unlocked(mod, name, NULL, &uval, KSYMS_ANY);
 		val = (long) uval;
 		if (((off - val) < db_maxoff) && val) {
 			(*pr)("%s:%s", mod, name);

Index: src/sys/kern/kern_ksyms.c
diff -u src/sys/kern/kern_ksyms.c:1.85 src/sys/kern/kern_ksyms.c:1.86
--- src/sys/kern/kern_ksyms.c:1.85	Wed Jun 14 00:52:37 2017
+++ src/sys/kern/kern_ksyms.c	Fri Nov  3 09:59:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_ksyms.c,v 1.85 2017/06/14 00:52:37 chs Exp $	*/
+/*	$NetBSD: kern_ksyms.c,v 1.86 2017/11/03 09:59:07 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.85 2017/06/14 00:52:37 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.86 2017/11/03 09:59:07 maxv Exp $");
 
 #if defined(_KERNEL) && defined(_KERNEL_OPT)
 #include "opt_copy_symtab.h"
@@ -374,7 +374,12 @@ addsymtab(const char *name, void *symsta
 		}
 #endif
 
-		nsym[n].st_shndx = SHBSS;
+		if (sym[i].st_shndx != SHN_ABS) {
+			nsym[n].st_shndx = SHBSS;
+		} else {
+			/* SHN_ABS is a magic value, don't overwrite it */
+		}
+
 		j = strlen(nsym[n].st_name + str) + 1;
 		if (j > ksyms_maxlen)
 			ksyms_maxlen = j;
@@ -561,8 +566,8 @@ ksyms_addsyms_explicit(void *ehdr, void 
  * Call with ksyms_lock, unless known that the symbol table can't change.
  */
 int
-ksyms_getval_unlocked(const char *mod, const char *sym, unsigned long *val,
-    int type)
+ksyms_getval_unlocked(const char *mod, const char *sym, void **symp,
+    unsigned long *val, int type)
 {
 	struct ksyms_symtab *st;
 	Elf_Sym *es;
@@ -580,6 +585,8 @@ ksyms_getval_unlocked(const char *mod, c
 			continue;
 		if ((es = findsym(sym, st, type)) != NULL) {
 			*val = es->st_value;
+			if (symp)
+				*symp = (void *)es;
 			return 0;
 		}
 	}
@@ -595,7 +602,7 @@ ksyms_getval(const char *mod, const char
 		return ENOENT;
 
 	mutex_enter(&ksyms_lock);
-	rc = ksyms_getval_unlocked(mod, sym, val, type);
+	rc = ksyms_getval_unlocked(mod, sym, NULL, val, type);
 	mutex_exit(&ksyms_lock);
 	return rc;
 }

Index: src/sys/kern/subr_kobj.c
diff -u src/sys/kern/subr_kobj.c:1.62 src/sys/kern/subr_kobj.c:1.63
--- src/sys/kern/subr_kobj.c:1.62	Thu Jun  1 02:45:13 2017
+++ src/sys/kern/subr_kobj.c	Fri Nov  3 09:59:07 2017
@@ -1,6 +1,6 @@
-/*	$NetBSD: subr_kobj.c,v 1.62 2017/06/01 02:45:13 chs Exp $	*/
+/*	$NetBSD: subr_kobj.c,v 1.63 2017/11/03 09:59:07 maxv Exp $	*/
 
-/*-
+/*
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*-
+/*
  * Copyright (c) 1998-2000 Doug Rabson
  * Copyright (c) 2004 Peter Wemm
  * All rights reserved.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.62 2017/06/01 02:45:13 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.63 2017/11/03 09:59:07 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_modular.h"
@@ -873,21 +873,29 @@ kobj_jettison(kobj_t ko)
  *	Symbol lookup function to be used when the symbol index
  *	is known (ie during relocation).
  */
-uintptr_t
-kobj_sym_lookup(kobj_t ko, uintptr_t symidx)
+int
+kobj_sym_lookup(kobj_t ko, uintptr_t symidx, uintptr_t *val)
 {
 	const Elf_Sym *sym;
 	const char *symbol;
 
-	/* Don't even try to lookup the symbol if the index is bogus. */
-	if (symidx >= ko->ko_symcnt)
-		return 0;
-
 	sym = ko->ko_symtab + symidx;
 
+	if (symidx == SHN_ABS) {
+		*val = (uintptr_t)sym->st_value;
+		return 0;
+	} else if (symidx >= ko->ko_symcnt) {
+		/*
+		 * Don't even try to lookup the symbol if the index is
+		 * bogus.
+		 */
+		return EINVAL;
+	}
+
 	/* Quick answer if there is a definition included. */
 	if (sym->st_shndx != SHN_UNDEF) {
-		return (uintptr_t)sym->st_value;
+		*val = (uintptr_t)sym->st_value;
+		return 0;
 	}
 
 	/* If we get here, then it is undefined and needs a lookup. */
@@ -895,7 +903,7 @@ kobj_sym_lookup(kobj_t ko, uintptr_t sym
 	case STB_LOCAL:
 		/* Local, but undefined? huh? */
 		kobj_error(ko, "local symbol undefined");
-		return 0;
+		return EINVAL;
 
 	case STB_GLOBAL:
 		/* Relative to Data or Function name */
@@ -904,17 +912,22 @@ kobj_sym_lookup(kobj_t ko, uintptr_t sym
 		/* Force a lookup failure if the symbol name is bogus. */
 		if (*symbol == 0) {
 			kobj_error(ko, "bad symbol name");
-			return 0;
+			return EINVAL;
+		}
+		if (sym->st_value == 0) {
+			kobj_error(ko, "bad value");
+			return EINVAL;
 		}
 
-		return (uintptr_t)sym->st_value;
+		*val = (uintptr_t)sym->st_value;
+		return 0;
 
 	case STB_WEAK:
 		kobj_error(ko, "weak symbols not supported");
-		return 0;
+		return EINVAL;
 
 	default:
-		return 0;
+		return EINVAL;
 	}
 }
 
@@ -946,7 +959,7 @@ static int
 kobj_checksyms(kobj_t ko, bool undefined)
 {
 	unsigned long rval;
-	Elf_Sym *sym, *ms;
+	Elf_Sym *sym, *ksym, *ms;
 	const char *name;
 	int error;
 
@@ -967,7 +980,7 @@ kobj_checksyms(kobj_t ko, bool undefined
 		 * module_lock).
 		 */
 		name = ko->ko_strtab + sym->st_name;
-		if (ksyms_getval_unlocked(NULL, name, &rval,
+		if (ksyms_getval_unlocked(NULL, name, (void **)&ksym, &rval,
 		    KSYMS_EXTERN) != 0) {
 			if (undefined) {
 				kobj_error(ko, "symbol `%s' not found",
@@ -979,6 +992,9 @@ kobj_checksyms(kobj_t ko, bool undefined
 
 		/* Save values of undefined globals. */
 		if (undefined) {
+			if (ksym->st_shndx == SHN_ABS) {
+				sym->st_shndx = SHN_ABS;
+			}
 			sym->st_value = (Elf_Addr)rval;
 			continue;
 		}

Index: src/sys/sys/kobj.h
diff -u src/sys/sys/kobj.h:1.16 src/sys/sys/kobj.h:1.17
--- src/sys/sys/kobj.h:1.16	Sat Aug 13 21:04:07 2011
+++ src/sys/sys/kobj.h	Fri Nov  3 09:59:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobj.h,v 1.16 2011/08/13 21:04:07 christos Exp $	*/
+/*	$NetBSD: kobj.h,v 1.17 2017/11/03 09:59:07 maxv Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@ int		kobj_stat(kobj_t, vaddr_t *, size_t
 int		kobj_find_section(kobj_t, const char *, void **, size_t *);
 
 /* MI-MD interface. */
-uintptr_t	kobj_sym_lookup(kobj_t, uintptr_t);
+int		kobj_sym_lookup(kobj_t, uintptr_t, uintptr_t *);
 int		kobj_reloc(kobj_t, uintptr_t, const void *, bool, bool);
 int		kobj_machdep(kobj_t, void *, size_t, bool);
 

Index: src/sys/sys/ksyms.h
diff -u src/sys/sys/ksyms.h:1.33 src/sys/sys/ksyms.h:1.34
--- src/sys/sys/ksyms.h:1.33	Sun Sep  6 06:01:02 2015
+++ src/sys/sys/ksyms.h	Fri Nov  3 09:59:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ksyms.h,v 1.33 2015/09/06 06:01:02 dholland Exp $	*/
+/*	$NetBSD: ksyms.h,v 1.34 2017/11/03 09:59:07 maxv Exp $	*/
 
 /*
  * Copyright (c) 2001, 2003 Anders Magnusson (ra...@ludd.luth.se).
@@ -131,7 +131,8 @@ typedef int (*ksyms_callback_t)(const ch
 
 int ksyms_getname(const char **, const char **, vaddr_t, int);
 int ksyms_getval(const char *, const char *, unsigned long *, int);
-int ksyms_getval_unlocked(const char *, const char *, unsigned long *, int);
+int ksyms_getval_unlocked(const char *, const char *, void **,
+    unsigned long *, int);
 struct ksyms_symtab *ksyms_get_mod(const char *);
 int ksyms_mod_foreach(const char *mod, ksyms_callback_t, void *);
 int ksyms_addsymtab(const char *, void *, vsize_t, char *, vsize_t);

Reply via email to