Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Jan 2010 20:05:20 +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-7@freebsd.org
Subject:   svn commit: r202647 - stable/7/libexec/rtld-elf
Message-ID:  <201001192005.o0JK5KUJ093547@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Jan 19 20:05:20 2010
New Revision: 202647
URL: http://svn.freebsd.org/changeset/base/202647

Log:
  MFC r197931:
  Calculate relocation base for the main object, and apply the relocation
  adjustment for all virtual addresses encoded into the ELF structures of it.
  
  Tested by:	Mykola Dzham <i levsha me>

Modified:
  stable/7/libexec/rtld-elf/rtld.c
Directory Properties:
  stable/7/libexec/rtld-elf/   (props changed)

Modified: stable/7/libexec/rtld-elf/rtld.c
==============================================================================
--- stable/7/libexec/rtld-elf/rtld.c	Tue Jan 19 19:59:03 2010	(r202646)
+++ stable/7/libexec/rtld-elf/rtld.c	Tue Jan 19 20:05:20 2010	(r202647)
@@ -474,6 +474,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
     /* Initialize a fake symbol for resolving undefined weak references. */
     sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
     sym_zero.st_shndx = SHN_UNDEF;
+    sym_zero.st_value = -(uintptr_t)obj_main->relocbase;
 
     if (!libmap_disable)
         libmap_disable = (bool)lm_init(libmap_override);
@@ -961,26 +962,26 @@ digest_phdr(const Elf_Phdr *phdr, int ph
 
     obj = obj_new();
     for (ph = phdr;  ph < phlimit;  ph++) {
-	switch (ph->p_type) {
+	if (ph->p_type != PT_PHDR)
+	    continue;
 
-	case PT_PHDR:
-	    if ((const Elf_Phdr *)ph->p_vaddr != phdr) {
-		_rtld_error("%s: invalid PT_PHDR", path);
-		return NULL;
-	    }
-	    obj->phdr = (const Elf_Phdr *) ph->p_vaddr;
-	    obj->phsize = ph->p_memsz;
-	    break;
+	obj->phdr = phdr;
+	obj->phsize = ph->p_memsz;
+	obj->relocbase = (caddr_t)phdr - ph->p_vaddr;
+	break;
+    }
+
+    for (ph = phdr;  ph < phlimit;  ph++) {
+	switch (ph->p_type) {
 
 	case PT_INTERP:
-	    obj->interp = (const char *) ph->p_vaddr;
+	    obj->interp = (const char *)(ph->p_vaddr + obj->relocbase);
 	    break;
 
 	case PT_LOAD:
 	    if (nsegs == 0) {	/* First load segment */
 		obj->vaddrbase = trunc_page(ph->p_vaddr);
-		obj->mapbase = (caddr_t) obj->vaddrbase;
-		obj->relocbase = obj->mapbase - obj->vaddrbase;
+		obj->mapbase = obj->vaddrbase + obj->relocbase;
 		obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
 		  obj->vaddrbase;
 	    } else {		/* Last load segment */
@@ -991,7 +992,7 @@ digest_phdr(const Elf_Phdr *phdr, int ph
 	    break;
 
 	case PT_DYNAMIC:
-	    obj->dynamic = (const Elf_Dyn *) ph->p_vaddr;
+	    obj->dynamic = (const Elf_Dyn *)(ph->p_vaddr + obj->relocbase);
 	    break;
 
 	case PT_TLS:
@@ -999,7 +1000,7 @@ digest_phdr(const Elf_Phdr *phdr, int ph
 	    obj->tlssize = ph->p_memsz;
 	    obj->tlsalign = ph->p_align;
 	    obj->tlsinitsize = ph->p_filesz;
-	    obj->tlsinit = (void*) ph->p_vaddr;
+	    obj->tlsinit = (void*)(ph->p_vaddr + obj->relocbase);
 	    break;
 	}
     }



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