svn commit: r202646 - stable/7/sys/kern

Konstantin Belousov kib at FreeBSD.org
Tue Jan 19 19:59:04 UTC 2010


Author: kib
Date: Tue Jan 19 19:59:03 2010
New Revision: 202646
URL: http://svn.freebsd.org/changeset/base/202646

Log:
  MFC r198202:
  If ET_DYN binary has non-zero base address for some reason, honour it
  and do not relocate the binary to ET_DYN_LOAD_ADDR. Communicate the
  relocation bias of the mapping for interpeter-less ET_DYN binary.
  
  Tested by:	Mykola Dzham <i levsha me>

Modified:
  stable/7/sys/kern/imgact_elf.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/kern/imgact_elf.c
==============================================================================
--- stable/7/sys/kern/imgact_elf.c	Tue Jan 19 19:56:50 2010	(r202645)
+++ stable/7/sys/kern/imgact_elf.c	Tue Jan 19 19:59:03 2010	(r202646)
@@ -692,9 +692,9 @@ __CONCAT(exec_, __elfN(imgact))(struct i
 	u_long text_size = 0, data_size = 0, total_size = 0;
 	u_long text_addr = 0, data_addr = 0;
 	u_long seg_size, seg_addr;
-	u_long addr, et_dyn_addr, entry = 0, proghdr = 0;
+	u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
 	int32_t osrel = 0;
-	int error = 0, i;
+	int error = 0, i, n;
 	const char *interp = NULL, *newinterp = NULL;
 	Elf_Brandinfo *brand_info;
 	char *path;
@@ -724,14 +724,22 @@ __CONCAT(exec_, __elfN(imgact))(struct i
 	phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
 	if (!aligned(phdr, Elf_Addr))
 		return (ENOEXEC);
+	n = 0;
+	baddr = 0;
 	for (i = 0; i < hdr->e_phnum; i++) {
+		if (phdr[i].p_type == PT_LOAD) {
+			if (n == 0)
+				baddr = phdr[i].p_vaddr;
+			n++;
+			continue;
+		}
 		if (phdr[i].p_type == PT_INTERP) {
 			/* Path to interpreter */
 			if (phdr[i].p_filesz > MAXPATHLEN ||
 			    phdr[i].p_offset + phdr[i].p_filesz > PAGE_SIZE)
 				return (ENOEXEC);
 			interp = imgp->image_header + phdr[i].p_offset;
-			break;
+			continue;
 		}
 	}
 
@@ -744,7 +752,14 @@ __CONCAT(exec_, __elfN(imgact))(struct i
 	if (hdr->e_type == ET_DYN) {
 		if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0)
 			return (ENOEXEC);
-		et_dyn_addr = ET_DYN_LOAD_ADDR;
+		/*
+		 * Honour the base load address from the dso if it is
+		 * non-zero for some reason.
+		 */
+		if (baddr == 0)
+			et_dyn_addr = ET_DYN_LOAD_ADDR;
+		else
+			et_dyn_addr = 0;
 	} else
 		et_dyn_addr = 0;
 	sv = brand_info->sysvec;
@@ -915,7 +930,7 @@ __CONCAT(exec_, __elfN(imgact))(struct i
 			return (error);
 		}
 	} else
-		addr = 0;
+		addr = et_dyn_addr;
 
 	/*
 	 * Construct auxargs table (used by the fixup routine)


More information about the svn-src-all mailing list