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