Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Sep 2015 01:33:44 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r288287 - in stable/10/sys: amd64/amd64 arm/arm i386/i386 ia64/ia64 kern mips/mips powerpc/powerpc sparc64/sparc64 sys
Message-ID:  <201509270133.t8R1Xix6099851@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun Sep 27 01:33:43 2015
New Revision: 288287
URL: https://svnweb.freebsd.org/changeset/base/288287

Log:
  MFC r288000:
  Add support for weak symbols to the kernel linkers.

Modified:
  stable/10/sys/amd64/amd64/elf_machdep.c
  stable/10/sys/arm/arm/elf_machdep.c
  stable/10/sys/i386/i386/elf_machdep.c
  stable/10/sys/ia64/ia64/elf_machdep.c
  stable/10/sys/kern/link_elf.c
  stable/10/sys/kern/link_elf_obj.c
  stable/10/sys/mips/mips/elf_machdep.c
  stable/10/sys/powerpc/powerpc/elf32_machdep.c
  stable/10/sys/powerpc/powerpc/elf64_machdep.c
  stable/10/sys/sparc64/sparc64/elf_machdep.c
  stable/10/sys/sys/linker.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/amd64/elf_machdep.c
==============================================================================
--- stable/10/sys/amd64/amd64/elf_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/amd64/amd64/elf_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -167,6 +167,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Size rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	switch (type) {
 	case ELF_RELOC_REL:
@@ -202,29 +203,29 @@ elf_reloc_internal(linker_file_t lf, Elf
 			break;
 
 		case R_X86_64_64:		/* S + A */
-			addr = lookup(lf, symidx, 1);
+			error = lookup(lf, symidx, 1, &addr);
 			val = addr + addend;
-			if (addr == 0)
+			if (error != 0)
 				return -1;
 			if (*where != val)
 				*where = val;
 			break;
 
 		case R_X86_64_PC32:	/* S + A - P */
-			addr = lookup(lf, symidx, 1);
+			error = lookup(lf, symidx, 1, &addr);
 			where32 = (Elf32_Addr *)where;
 			val32 = (Elf32_Addr)(addr + addend - (Elf_Addr)where);
-			if (addr == 0)
+			if (error != 0)
 				return -1;
 			if (*where32 != val32)
 				*where32 = val32;
 			break;
 
 		case R_X86_64_32S:	/* S + A sign extend */
-			addr = lookup(lf, symidx, 1);
+			error = lookup(lf, symidx, 1, &addr);
 			val32 = (Elf32_Addr)(addr + addend);
 			where32 = (Elf32_Addr *)where;
-			if (addr == 0)
+			if (error != 0)
 				return -1;
 			if (*where32 != val32)
 				*where32 = val32;
@@ -241,8 +242,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 
 		case R_X86_64_GLOB_DAT:	/* S */
 		case R_X86_64_JMP_SLOT:	/* XXX need addend + offset */
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return -1;
 			if (*where != addr)
 				*where = addr;

Modified: stable/10/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/10/sys/arm/arm/elf_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/arm/arm/elf_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -132,6 +132,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Word rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	switch (type) {
 	case ELF_RELOC_REL:
@@ -167,8 +168,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 			break;
 
 		case R_ARM_ABS32:
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return -1;
 			*where += addr;
 			break;
@@ -183,8 +184,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 			break;
 
 		case R_ARM_JUMP_SLOT:
-			addr = lookup(lf, symidx, 1);
-			if (addr) {
+			error = lookup(lf, symidx, 1, &addr);
+			if (error == 0) {
 				*where = addr;
 				return (0);
 			}

Modified: stable/10/sys/i386/i386/elf_machdep.c
==============================================================================
--- stable/10/sys/i386/i386/elf_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/i386/i386/elf_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -177,6 +177,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Word rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	switch (type) {
 	case ELF_RELOC_REL:
@@ -212,8 +213,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 			break;
 
 		case R_386_32:		/* S + A */
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return -1;
 			addr += addend;
 			if (*where != addr)
@@ -221,8 +222,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 			break;
 
 		case R_386_PC32:	/* S + A - P */
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return -1;
 			addr += addend - (Elf_Addr)where;
 			if (*where != addr)
@@ -239,8 +240,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 			break;
 
 		case R_386_GLOB_DAT:	/* S */
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return -1;
 			if (*where != addr)
 				*where = addr;

Modified: stable/10/sys/ia64/ia64/elf_machdep.c
==============================================================================
--- stable/10/sys/ia64/ia64/elf_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/ia64/ia64/elf_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -127,17 +127,18 @@ elf64_dump_thread(struct thread *td, voi
 }
 
 
-static Elf_Addr
-lookup_fdesc(linker_file_t lf, Elf_Size symidx, elf_lookup_fn lookup)
+static int
+lookup_fdesc(linker_file_t lf, Elf_Size symidx, elf_lookup_fn lookup,
+    Elf_Addr *addr1)
 {
 	linker_file_t top;
 	Elf_Addr addr;
 	const char *symname;
-	int i;
+	int i, error;
 	static int eot = 0;
 
-	addr = lookup(lf, symidx, 0);
-	if (addr == 0) {
+	error = lookup(lf, symidx, 0, &addr);
+	if (error != 0) {
 		top = lf;
 		symname = elf_get_symname(top, symidx);
 		for (i = 0; i < top->ndeps; i++) {
@@ -148,30 +149,33 @@ lookup_fdesc(linker_file_t lf, Elf_Size 
 				break;
 		}
 		if (addr == 0)
-			return (0);
+			return (EINVAL);
 	}
 
 	if (eot)
-		return (0);
+		return (EINVAL);
 
 	/*
 	 * Lookup and/or construct OPD
 	 */
 	for (i = 0; i < 8192; i += 2) {
-		if (fptr_storage[i] == addr)
-			return (Elf_Addr)(fptr_storage + i);
+		if (fptr_storage[i] == addr) {
+			*addr1 = (Elf_Addr)(fptr_storage + i);
+			return (0);
+		}
 
 		if (fptr_storage[i] == 0) {
 			fptr_storage[i] = addr;
 			fptr_storage[i+1] = link_elf_get_gp(lf);
-			return (Elf_Addr)(fptr_storage + i);
+			*addr1 = (Elf_Addr)(fptr_storage + i);
+			return (0);
 		}
 	}
 
 	printf("%s: fptr table full\n", __func__);
 	eot = 1;
 
-	return (0);
+	return (EINVAL);
 }
 
 /* Process one elf relocation with addend. */
@@ -184,6 +188,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Size rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
+	int error;
 
 	switch (type) {
 	case ELF_RELOC_REL:
@@ -223,8 +228,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 	case R_IA_64_NONE:
 		break;
 	case R_IA_64_DIR64LSB:	/* word64 LSB	S + A */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 		*where = addr + addend;
 		break;
@@ -233,16 +238,16 @@ elf_reloc_internal(linker_file_t lf, Elf
 			printf("%s: addend ignored for OPD relocation\n",
 			    __func__);
 		}
-		addr = lookup_fdesc(lf, symidx, lookup);
-		if (addr == 0)
+		error = lookup_fdesc(lf, symidx, lookup, &addr);
+		if (error != 0)
 			return (-1);
 		*where = addr;
 		break;
 	case R_IA_64_REL64LSB:	/* word64 LSB	BD + A */
 		break;
 	case R_IA_64_IPLTLSB:
-		addr = lookup_fdesc(lf, symidx, lookup);
-		if (addr == 0)
+		error = lookup_fdesc(lf, symidx, lookup, &addr);
+		if (error != 0)
 			return (-1);
 		where[0] = *((Elf_Addr*)addr) + addend;
 		where[1] = *((Elf_Addr*)addr + 1);

Modified: stable/10/sys/kern/link_elf.c
==============================================================================
--- stable/10/sys/kern/link_elf.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/kern/link_elf.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -158,7 +158,7 @@ static int	link_elf_each_function_nameva
 static void	link_elf_reloc_local(linker_file_t);
 static long	link_elf_symtab_get(linker_file_t, const Elf_Sym **);
 static long	link_elf_strtab_get(linker_file_t, caddr_t *);
-static Elf_Addr	elf_lookup(linker_file_t, Elf_Size, int);
+static int	elf_lookup(linker_file_t, Elf_Size, int, Elf_Addr *);
 
 static kobj_method_t link_elf_methods[] = {
 	KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
@@ -1498,8 +1498,8 @@ elf_get_symname(linker_file_t lf, Elf_Si
  * This is not only more efficient, it's also more correct. It's not always
  * the case that the symbol can be found through the hash table.
  */
-static Elf_Addr
-elf_lookup(linker_file_t lf, Elf_Size symidx, int deps)
+static int
+elf_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
 {
 	elf_file_t ef = (elf_file_t)lf;
 	const Elf_Sym *sym;
@@ -1507,8 +1507,10 @@ elf_lookup(linker_file_t lf, Elf_Size sy
 	Elf_Addr addr, start, base;
 
 	/* Don't even try to lookup the symbol if the index is bogus. */
-	if (symidx >= ef->nchains)
-		return (0);
+	if (symidx >= ef->nchains) {
+		*res = 0;
+		return (EINVAL);
+	}
 
 	sym = ef->symtab + symidx;
 
@@ -1518,9 +1520,12 @@ elf_lookup(linker_file_t lf, Elf_Size sy
 	 */
 	if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
 		/* Force lookup failure when we have an insanity. */
-		if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0)
-			return (0);
-		return ((Elf_Addr)ef->address + sym->st_value);
+		if (sym->st_shndx == SHN_UNDEF || sym->st_value == 0) {
+			*res = 0;
+			return (EINVAL);
+		}
+		*res = ((Elf_Addr)ef->address + sym->st_value);
+		return (0);
 	}
 
 	/*
@@ -1533,8 +1538,10 @@ elf_lookup(linker_file_t lf, Elf_Size sy
 	symbol = ef->strtab + sym->st_name;
 
 	/* Force a lookup failure if the symbol name is bogus. */
-	if (*symbol == 0)
-		return (0);
+	if (*symbol == 0) {
+		*res = 0;
+		return (EINVAL);
+	}
 
 	addr = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
 
@@ -1544,7 +1551,8 @@ elf_lookup(linker_file_t lf, Elf_Size sy
 	else if (elf_set_find(&set_vnet_list, addr, &start, &base))
 		addr = addr - start + base;
 #endif
-	return addr;
+	*res = addr;
+	return (0);
 }
 
 static void

Modified: stable/10/sys/kern/link_elf_obj.c
==============================================================================
--- stable/10/sys/kern/link_elf_obj.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/kern/link_elf_obj.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -144,7 +144,8 @@ static void	link_elf_reloc_local(linker_
 static long	link_elf_symtab_get(linker_file_t, const Elf_Sym **);
 static long	link_elf_strtab_get(linker_file_t, caddr_t *);
 
-static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps);
+static int	elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps,
+		    Elf_Addr *);
 
 static kobj_method_t link_elf_methods[] = {
 	KOBJMETHOD(linker_lookup_symbol,	link_elf_lookup_symbol),
@@ -1224,38 +1225,46 @@ elf_obj_cleanup_globals_cache(elf_file_t
  * This is not only more efficient, it's also more correct. It's not always
  * the case that the symbol can be found through the hash table.
  */
-static Elf_Addr
-elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps)
+static int
+elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps, Elf_Addr *res)
 {
 	elf_file_t ef = (elf_file_t)lf;
 	Elf_Sym *sym;
 	const char *symbol;
-	Elf_Addr ret;
+	Elf_Addr res1;
 
 	/* Don't even try to lookup the symbol if the index is bogus. */
-	if (symidx >= ef->ddbsymcnt)
-		return (0);
+	if (symidx >= ef->ddbsymcnt) {
+		*res = 0;
+		return (EINVAL);
+	}
 
 	sym = ef->ddbsymtab + symidx;
 
 	/* Quick answer if there is a definition included. */
-	if (sym->st_shndx != SHN_UNDEF)
-		return (sym->st_value);
+	if (sym->st_shndx != SHN_UNDEF) {
+		*res = sym->st_value;
+		return (0);
+	}
 
 	/* If we get here, then it is undefined and needs a lookup. */
 	switch (ELF_ST_BIND(sym->st_info)) {
 	case STB_LOCAL:
 		/* Local, but undefined? huh? */
-		return (0);
+		*res = 0;
+		return (EINVAL);
 
 	case STB_GLOBAL:
+	case STB_WEAK:
 		/* Relative to Data or Function name */
 		symbol = ef->ddbstrtab + sym->st_name;
 
 		/* Force a lookup failure if the symbol name is bogus. */
-		if (*symbol == 0)
-			return (0);
-		ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+		if (*symbol == 0) {
+			*res = 0;
+			return (EINVAL);
+		}
+		res1 = (Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps);
 
 		/*
 		 * Cache global lookups during module relocation. The failure
@@ -1267,18 +1276,20 @@ elf_obj_lookup(linker_file_t lf, Elf_Siz
 		 * restored to SHN_UNDEF in elf_obj_cleanup_globals_cache(),
 		 * above.
 		 */
-		if (ret != 0) {
+		if (res1 != 0) {
 			sym->st_shndx = SHN_FBSD_CACHED;
-			sym->st_value = ret;
+			sym->st_value = res1;
+			*res = res1;
+			return (0);
+		} else if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
+			sym->st_value = 0;
+			*res = 0;
+			return (0);
 		}
-		return (ret);
-
-	case STB_WEAK:
-		printf("link_elf_obj: Weak symbols not supported\n");
-		return (0);
+		return (EINVAL);
 
 	default:
-		return (0);
+		return (EINVAL);
 	}
 }
 

Modified: stable/10/sys/mips/mips/elf_machdep.c
==============================================================================
--- stable/10/sys/mips/mips/elf_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/mips/mips/elf_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -174,6 +174,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Word rtype = (Elf_Word)0, symidx;
 	const Elf_Rel *rel = NULL;
 	const Elf_Rela *rela = NULL;
+	int error;
 
 	/*
 	 * Stash R_MIPS_HI16 info so we can use it when processing R_MIPS_LO16
@@ -213,8 +214,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_MIPS_32:		/* S + A */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 		addr += addend;
 		if (*where != addr)
@@ -222,8 +223,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_MIPS_26:		/* ((A << 2) | (P & 0xf0000000) + S) >> 2 */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 
 		addend &= 0x03ffffff;
@@ -241,8 +242,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_MIPS_64:		/* S + A */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 		addr += addend;
 		if (*(Elf64_Addr*)where != addr)
@@ -251,8 +252,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 
 	case R_MIPS_HI16:	/* ((AHL + S) - ((short)(AHL + S)) >> 16 */
 		if (rela != NULL) {
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return (-1);
 			addr += addend;
 			*where &= 0xffff0000;
@@ -266,8 +267,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 
 	case R_MIPS_LO16:	/* AHL + S */
 		if (rela != NULL) {
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return (-1);
 			addr += addend;
 			*where &= 0xffff0000;
@@ -275,8 +276,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		}
 		else {
 			ahl += (int16_t)addend;
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
+			error = lookup(lf, symidx, 1, &addr);
+			if (error != 0)
 				return (-1);
 
 			addend &= 0xffff0000;
@@ -292,8 +293,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_MIPS_HIGHER:	/* %higher(A+S) */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 		addr += addend;
 		*where &= 0xffff0000;
@@ -301,8 +302,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_MIPS_HIGHEST:	/* %highest(A+S) */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 		addr += addend;
 		*where &= 0xffff0000;

Modified: stable/10/sys/powerpc/powerpc/elf32_machdep.c
==============================================================================
--- stable/10/sys/powerpc/powerpc/elf32_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/powerpc/powerpc/elf32_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -164,6 +164,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Addr addend;
 	Elf_Word rtype, symidx;
 	const Elf_Rela *rela;
+	int error;
 
 	switch (type) {
 	case ELF_RELOC_REL:
@@ -187,16 +188,16 @@ elf_reloc_internal(linker_file_t lf, Elf
 	       	break;
 
 	case R_PPC_ADDR32: /* word32 S + A */
-       		addr = lookup(lf, symidx, 1);
-	       	if (addr == 0)
-	       		return -1;
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
+			return -1;
 		addr += addend;
 	       	*where = addr;
 	       	break;
 
        	case R_PPC_ADDR16_LO: /* #lo(S) */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return -1;
 		/*
 		 * addend values are sometimes relative to sections
@@ -211,8 +212,8 @@ elf_reloc_internal(linker_file_t lf, Elf
 		break;
 
 	case R_PPC_ADDR16_HA: /* #ha(S) */
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return -1;
 		/*
 		 * addend values are sometimes relative to sections

Modified: stable/10/sys/powerpc/powerpc/elf64_machdep.c
==============================================================================
--- stable/10/sys/powerpc/powerpc/elf64_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/powerpc/powerpc/elf64_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -135,6 +135,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	Elf_Addr addend;
 	Elf_Word rtype, symidx;
 	const Elf_Rela *rela;
+	int error;
 
 	switch (type) {
 	case ELF_RELOC_REL:
@@ -157,9 +158,9 @@ elf_reloc_internal(linker_file_t lf, Elf
 	       	break;
 
 	case R_PPC64_ADDR64:	/* doubleword64 S + A */
-       		addr = lookup(lf, symidx, 1);
-	       	if (addr == 0)
-	       		return -1;
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
+			return -1;
 		addr += addend;
 	       	*where = addr;
 	       	break;
@@ -169,7 +170,7 @@ elf_reloc_internal(linker_file_t lf, Elf
 	       	break;
 
 	case R_PPC_JMP_SLOT:	/* function descriptor copy */
-		addr = lookup(lf, symidx, 1);
+		lookup(lf, symidx, 1, &addr);
 		memcpy(where, (Elf_Addr *)addr, 3*sizeof(Elf_Addr));
 		__asm __volatile("dcbst 0,%0; sync" :: "r"(where) : "memory");
 		break;

Modified: stable/10/sys/sparc64/sparc64/elf_machdep.c
==============================================================================
--- stable/10/sys/sparc64/sparc64/elf_machdep.c	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/sparc64/sparc64/elf_machdep.c	Sun Sep 27 01:33:43 2015	(r288287)
@@ -343,6 +343,7 @@ elf_reloc(linker_file_t lf, Elf_Addr rel
 	Elf_Addr value;
 	Elf_Addr mask;
 	Elf_Addr addr;
+	int error;
 
 	if (type != ELF_RELOC_RELA)
 		return (-1);
@@ -371,8 +372,8 @@ elf_reloc(linker_file_t lf, Elf_Addr rel
 	value = rela->r_addend;
 
 	if (RELOC_RESOLVE_SYMBOL(rtype)) {
-		addr = lookup(lf, symidx, 1);
-		if (addr == 0)
+		error = lookup(lf, symidx, 1, &addr);
+		if (error != 0)
 			return (-1);
 		value += addr;
 		if (RELOC_BARE_SYMBOL(rtype))

Modified: stable/10/sys/sys/linker.h
==============================================================================
--- stable/10/sys/sys/linker.h	Sun Sep 27 01:26:41 2015	(r288286)
+++ stable/10/sys/sys/linker.h	Sun Sep 27 01:33:43 2015	(r288287)
@@ -259,7 +259,7 @@ extern int kld_debug;
 
 #endif
 
-typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Size, int);
+typedef int elf_lookup_fn(linker_file_t, Elf_Size, int, Elf_Addr *);
 
 /* Support functions */
 int	elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509270133.t8R1Xix6099851>