Module Name:    src
Committed By:   skrll
Date:           Fri Oct 15 07:22:44 UTC 2010

Modified Files:
        src/libexec/ld.elf_so: headers.c

Log Message:
Be more tolerant to the location of PT_PHDR in the segment list.


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/libexec/ld.elf_so/headers.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/headers.c
diff -u src/libexec/ld.elf_so/headers.c:1.33 src/libexec/ld.elf_so/headers.c:1.34
--- src/libexec/ld.elf_so/headers.c:1.33	Thu Sep 30 19:45:24 2010
+++ src/libexec/ld.elf_so/headers.c	Fri Oct 15 07:22:44 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: headers.c,v 1.33 2010/09/30 19:45:24 skrll Exp $	 */
+/*	$NetBSD: headers.c,v 1.34 2010/10/15 07:22:44 skrll Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.33 2010/09/30 19:45:24 skrll Exp $");
+__RCSID("$NetBSD: headers.c,v 1.34 2010/10/15 07:22:44 skrll Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -307,20 +307,27 @@
 	const Elf_Phdr *phlimit = phdr + phnum;
 	const Elf_Phdr *ph;
 	int             nsegs = 0;
-	ptrdiff_t	relocoffs = 0;
 	Elf_Addr	vaddr;
 
 	obj = _rtld_obj_new();
+
+	for (ph = phdr; ph < phlimit; ++ph) {
+		if (ph->p_type != PT_PHDR)
+			continue;
+		
+		obj->phdr = (void *)(uintptr_t)phdr->p_vaddr;
+		obj->phsize = phdr->p_memsz;
+		obj->relocbase = (caddr_t)((uintptr_t)phdr - (uintptr_t)ph->p_vaddr);
+		dbg(("headers: phdr %p phsize %zu relocbase %lx", obj->phdr,
+		    obj->phsize, (long)obj->relocbase));
+		break;
+	}
+	assert(obj->phdr == phdr);
+	
 	for (ph = phdr; ph < phlimit; ++ph) {
-		vaddr = ph->p_vaddr + relocoffs;
+		vaddr = (Elf_Addr)obj->relocbase + ph->p_vaddr;
 		switch (ph->p_type) {
 
-		case PT_PHDR:
-			relocoffs = (uintptr_t)phdr - (uintptr_t)ph->p_vaddr;
-			dbg(("headers: phdr %p phsize %zu relocoffs %lx", obj->phdr,
-			    obj->phsize, (long)relocoffs));
-			break;
-
 		case PT_INTERP:
 			obj->interp = (const char *)(uintptr_t)vaddr;
 			break;
@@ -330,7 +337,6 @@
 			if (nsegs == 0) {	/* First load segment */
 				obj->vaddrbase = round_down(vaddr);
 				obj->mapbase = (caddr_t)(uintptr_t)obj->vaddrbase;
-				obj->relocbase = (void *)relocoffs;
 				obj->textsize = round_up(vaddr + ph->p_memsz) -
 				    obj->vaddrbase;
 			} else {		/* Last load segment */

Reply via email to