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@.
This commit is contained in:
maxv 2017-11-03 09:59:07 +00:00
parent 2954611269
commit 4e8a8f71db
16 changed files with 146 additions and 111 deletions

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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;

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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;

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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;

View File

@ -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 relocbase, const void *data,
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;

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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;

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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 relocbase, const void *data,
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;

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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
/*

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
#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
/*

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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);

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
}
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;
}

View File

@ -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 relocbase, const void *data,
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 relocbase, const void *data,
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;
}

View File

@ -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_expr_t *valuep)
(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_strategy_t strategy, db_expr_t *offp)
#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_expr_t off, db_strategy_t strategy)
#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 strategy,
#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);

View File

@ -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 *symstart, size_t symsize,
}
#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 *symstart, size_t symsize,
* 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, const char *sym, unsigned long *val,
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 *sym, unsigned long *val, int type)
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;
}

View File

@ -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 symidx)
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 symidx)
/* 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;
}

View File

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

View File

@ -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 (ragge@ludd.luth.se).
@ -131,7 +131,8 @@ typedef int (*ksyms_callback_t)(const char *, int, void *,
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);