Module Name:    src
Committed By:   snj
Date:           Tue Jul 25 02:19:04 UTC 2017

Modified Files:
        src/libexec/ld.elf_so/arch/sparc64 [netbsd-8]: mdreloc.c

Log Message:
Pull up following revision(s) (requested by martin in ticket #156):
        libexec/ld.elf_so/arch/sparc64/mdreloc.c: 1.62, 1.63
Simplify and fix the offset calculation when doing a %pc relative
branch from the PLT slot to the target.
--
Fix thinko in previous: even if the address is an unsigned value and we
have verified the range before, we still need to mask the bit pattern
to the target instruction field.


To generate a diff of this commit:
cvs rdiff -u -r1.59.6.1 -r1.59.6.2 \
    src/libexec/ld.elf_so/arch/sparc64/mdreloc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/ld.elf_so/arch/sparc64/mdreloc.c
diff -u src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.59.6.1 src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.59.6.2
--- src/libexec/ld.elf_so/arch/sparc64/mdreloc.c:1.59.6.1	Tue Jul  4 12:47:58 2017
+++ src/libexec/ld.elf_so/arch/sparc64/mdreloc.c	Tue Jul 25 02:19:03 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mdreloc.c,v 1.59.6.1 2017/07/04 12:47:58 martin Exp $	*/
+/*	$NetBSD: mdreloc.c,v 1.59.6.2 2017/07/25 02:19:03 snj Exp $	*/
 
 /*-
  * Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.59.6.1 2017/07/04 12:47:58 martin Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.59.6.2 2017/07/25 02:19:03 snj Exp $");
 #endif /* not lint */
 
 #include <errno.h>
@@ -579,7 +579,7 @@ _rtld_relocate_plt_object(const Obj_Entr
 	Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
 	const Elf_Sym *def;
 	const Obj_Entry *defobj;
-	Elf_Addr value, offset;
+	Elf_Addr value, offset, offBAA;
 	unsigned long info = rela->r_info;
 
 	assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
@@ -625,6 +625,7 @@ _rtld_relocate_plt_object(const Obj_Entr
 	 */
 
 	offset = ((Elf_Addr)where) - value;
+	offBAA = value - (((Elf_Addr)where) +4);	/* ba,a at where[1] */
 	if (rela->r_addend) {
 		Elf_Addr *ptr = (Elf_Addr *)where;
 		/*
@@ -634,7 +635,7 @@ _rtld_relocate_plt_object(const Obj_Entr
 		 */
 		ptr[0] += value - (Elf_Addr)obj->pltgot;
 
-	} else if (offset <= (1L<<20) && (Elf_SOff)offset >= -(1L<<20)) {
+	} else if (offBAA <= (1L<<20) && (Elf_SOff)offBAA >= -(1L<<20)) {
 		/* 
 		 * We're within 1MB -- we can use a direct branch insn.
 		 *
@@ -650,7 +651,7 @@ _rtld_relocate_plt_object(const Obj_Entr
 		 *	nop
 		 *
 		 */
-		where[1] = BAA | ((offset >> 2) & 0x7ffff);
+		where[1] = BAA | ((offBAA >> 2) & 0x7ffff);
 		__asm volatile("iflush %0+4" : : "r" (where));
 	} else if (value < (1L<<32)) {
 		/* 

Reply via email to