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:
parent
2954611269
commit
4e8a8f71db
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue