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 */