Subject: ELF prebinding round 2: shared object prerelocation
To: None <tech-userlevel@netbsd.org>
From: Bang Jun-Young <junyoung@mogua.com>
List: tech-userlevel
Date: 09/21/2002 16:21:10
--vkogqOf2sHV7VnPd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

During the last couple weeks I have written 'prebind' program and 
modified ld.elf_so so that it handles shared libraries modified by
prebind. Here is a brief description.

A shared object now has preferred base address, which gives a hint
to ld.elf_so where to load the object. This information must be known
to ld.elf_so before shared object is actually loaded, so I decided to 
put it in p_paddr of the first PT_LOAD entry. This field has unspecifed
contents and is ignored, according to SysV ABI spec (in normal case
p_paddr == p_vaddr).

If executed with -b <preferred baseaddr>, prebind performs relocation
on the given shared object as if it were loaded at the preferred base,
and save relocated entries to the file. This process is completely
reversible, so you can always undo by rerunning prebind with 
-b <orignal baseaddr> which is simply 0 in most cases.

ld.elf_so has been modified accordingly. It checks if the shared object
is prerelocated by prebind, and then skips most of relocations, thereby
reducing loading time of dynamically linked binaries significantly.
The number of relocations made in libc.so was reduced from 1273 rel/
675 pltrel to 0 rel/6 pltrel (saving 1943!). I did a simple benchmark
with David Laight's program on Athlon XP 1800 with 256MB DDR:

$ time ./david.prebind 999
real	0m0.386s
user	0m0.017s
sys	0m0.307s

$ time ./david.normal 999
real	0m0.530s
user	0m0.089s
sys	0m0.437s

As seen above, approx. 30% of time was saved. I guess gain could be
larger on slower machines, but I haven't tested.

Finally, I have to say that it has a fatal bug. :-( All programs that
make a call to malloc() (or something else) don't run with prerelocated
libc.so. I see errors like

$ ./whoami
whoami: Cannot allocate memory

but haven't found what makes this trouble yet. So I need your help.
All the patches and files are attached in this mail (note that prebind
code is far from complete).

Jun-Young

-- 
Bang Jun-Young <junyoung@mogua.com>

--vkogqOf2sHV7VnPd
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ld.elf_so.prebind.diff"

Index: headers.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/headers.c,v
retrieving revision 1.13
diff -u -r1.13 headers.c
--- headers.c	2002/09/13 13:28:43	1.13
+++ headers.c	2002/09/21 06:04:09
@@ -298,6 +298,7 @@
 			assert(nsegs < 2);
 			if (nsegs == 0) {	/* First load segment */
 				obj->vaddrbase = round_down(ph->p_vaddr);
+				obj->prefbase = round_down(ph->p_paddr);
 				obj->mapbase = (caddr_t) obj->vaddrbase;
 				obj->relocbase = obj->mapbase - obj->vaddrbase;
 				obj->textsize = round_up(ph->p_vaddr +
Index: map_object.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/map_object.c,v
retrieving revision 1.15
diff -u -r1.15 map_object.c
--- map_object.c	2002/09/13 03:12:40	1.15
+++ map_object.c	2002/09/21 06:04:09
@@ -41,6 +41,7 @@
 #include <sys/mman.h>
 
 #include "rtld.h"
+#include "debug.h"
 
 static int protflags __P((int));	/* Elf flags -> mmap protection */
 
@@ -74,6 +75,7 @@
 	size_t          mapsize;
 	Elf_Off         base_offset;
 	Elf_Addr        base_vaddr;
+	Elf_Addr	base_paddr;
 	Elf_Addr        base_vlimit;
 	Elf_Addr	text_vlimit;
 	caddr_t         base_addr;
@@ -184,12 +186,14 @@
 
 	base_offset = round_down(segs[0]->p_offset);
 	base_vaddr = round_down(segs[0]->p_vaddr);
+	base_paddr = round_down(segs[0]->p_paddr);
 	base_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz);
 	text_vlimit = round_up(segs[0]->p_vaddr + segs[0]->p_memsz);
 	mapsize = base_vlimit - base_vaddr;
 
 #ifdef RTLD_LOADER
-	base_addr = u.hdr.e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL;
+	base_addr = u.hdr.e_type == ET_EXEC ? (caddr_t) base_vaddr : 
+	    (caddr_t)base_paddr;
 #else
 	base_addr = NULL;
 #endif
@@ -202,6 +206,8 @@
 		return NULL;
 	}
 
+	if (mapbase == base_addr)
+		dbg(("  loaded at the preferred address"));
 	base_addr = mapbase;
 
 	/* Overlay the data segment onto the proper region. */
@@ -259,6 +265,15 @@
 	    base_vaddr;
 	obj->vaddrbase = base_vaddr;
 	obj->relocbase = mapbase - base_vaddr;
+	obj->prefbase = base_paddr;
+	if (obj->prefbase != obj->vaddrbase &&
+	    obj->mapbase == (caddr_t)obj->prefbase) {
+		dbg(("  prerelocated object"));
+		obj->prereloc = 1;
+	} else
+		obj->prereloc = 0;
+	obj->unresolent = segs[1]->p_paddr;
+	obj->unresolved = (segs[1]->p_vaddr != segs[1]->p_paddr) ? 1 : 0;
 	obj->dynamic = (Elf_Dyn *)(obj->relocbase + phdyn->p_vaddr);
 	if (u.hdr.e_entry != 0)
 		obj->entry = (caddr_t)(obj->relocbase + u.hdr.e_entry);
Index: reloc.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/reloc.c,v
retrieving revision 1.68
diff -u -r1.68 reloc.c
--- reloc.c	2002/09/17 07:29:46	1.68
+++ reloc.c	2002/09/21 06:04:09
@@ -236,8 +236,10 @@
 				return -1;
 			}
 		}
-		if (_rtld_relocate_nonplt_objects(obj, self) < 0)
-			ok = 0;
+		if (obj->prereloc)
+			ok = _rtld_relocate_unresolved_nonplt(obj);
+		else
+			ok = _rtld_relocate_nonplt_objects(obj, self);
 		if (obj->textrel) {	/* Re-protected the text segment. */
 			if (mprotect(obj->mapbase, obj->textsize,
 				     PROT_READ | PROT_EXEC) == -1) {
@@ -246,14 +248,13 @@
 				return -1;
 			}
 		}
-		if (_rtld_relocate_plt_lazy(obj) < 0)
-			ok = 0;
+		if (!obj->prereloc)
+			ok = _rtld_relocate_plt_lazy(obj);
 #if defined(__i386__)
 		if (bind_now)
-			if (_rtld_relocate_plt_objects(obj) < 0)
-				ok = 0;
+			ok = _rtld_relocate_plt_objects(obj);
 #endif
-		if (!ok)
+		if (ok < 0)
 			return -1;
 
 
Index: rtld.h
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/rtld.h,v
retrieving revision 1.52
diff -u -r1.52 rtld.h
--- rtld.h	2002/09/19 14:05:37	1.52
+++ rtld.h	2002/09/21 06:04:09
@@ -149,6 +149,8 @@
 	size_t          textsize;	/* Size of text segment in bytes */
 	Elf_Addr        vaddrbase;	/* Base address in shared object file */
 	caddr_t         relocbase;	/* Reloc const = mapbase - *vaddrbase */
+	Elf_Addr	prefbase;	/* Preferred base address */
+	size_t		unresolent;	/* Offset of first unresolved ent. */
 	Elf_Dyn        *dynamic;	/* Dynamic section */
 	caddr_t         entry;		/* Entry point */
 	const Elf_Phdr *phdr;		/* Program header if mapped, ow NULL */
@@ -200,7 +202,9 @@
 			symbolic:1,	/* True if generated with
 					 * "-Bsymbolic" */
 			printed:1,	/* True if ldd has printed it */
-			isdynamic:1;	/* True if this is a pure PIC object */
+			isdynamic:1,	/* True if this is a pure PIC object */
+			prereloc:1,	/* True if prerelocated. */
+			unresolved:1;	/* True if there's unresolved entry */
 
 	struct link_map linkmap;	/* for GDB */
 
@@ -262,6 +266,7 @@
 caddr_t _rtld_bind __P((const Obj_Entry *, Elf_Word));
 int _rtld_relocate_objects __P((Obj_Entry *, bool, bool));
 int _rtld_relocate_nonplt_objects __P((const Obj_Entry *, bool));
+int _rtld_relocate_unresolved_nonplt(const Obj_Entry *);
 int _rtld_relocate_plt_lazy __P((const Obj_Entry *));
 int _rtld_relocate_plt_object __P((const Obj_Entry *, const Elf_Rela *,
     caddr_t *));
Index: arch/i386/mdreloc.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/arch/i386/mdreloc.c,v
retrieving revision 1.15
diff -u -r1.15 mdreloc.c
--- arch/i386/mdreloc.c	2002/09/17 07:29:49	1.15
+++ arch/i386/mdreloc.c	2002/09/21 06:04:09
@@ -157,6 +157,89 @@
 }
 
 int
+_rtld_relocate_unresolved_nonplt(obj)
+	const Obj_Entry *obj;
+{
+	const Elf_Rel *rel;
+#define COMBRELOC
+#ifdef COMBRELOC
+	unsigned long lastsym = -1;
+#endif
+	Elf_Addr target;
+
+	rel = (obj->unresolved) ? obj->rel + obj->unresolent : obj->rel;
+	for (; rel < obj->rellim; rel++) {
+		Elf_Addr        *where;
+		const Elf_Sym   *def;
+		const Obj_Entry *defobj;
+		Elf_Addr         tmp;
+		unsigned long	 symnum;
+
+		where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
+		symnum = ELF_R_SYM(rel->r_info);
+
+		switch (ELF_R_TYPE(rel->r_info)) {
+		case R_TYPE(NONE):
+			break;
+
+#if 1 /* XXX should not occur */
+		case R_TYPE(PC32):
+			if (obj->symtab[symnum].st_value != 0)
+				break;
+#ifdef COMBRELOC
+			if (symnum != lastsym) {
+#endif
+				def = _rtld_find_symdef(symnum, obj, &defobj,
+				    false);
+				if (def == NULL)
+					return -1;
+				target = (Elf_Addr)(defobj->relocbase +
+				    def->st_value);
+#ifdef COMBRELOC
+				lastsym = symnum;
+			}
+#endif
+
+			*where += target - (Elf_Addr)where;
+			rdbg(("PC32 %s in %s --> %p in %s",
+			    obj->strtab + obj->symtab[symnum].st_name,
+			    obj->path, (void *)*where, defobj->path));
+			break;
+
+		case R_TYPE(GOT32):
+#endif
+		case R_TYPE(32):
+		case R_TYPE(GLOB_DAT):
+			if (obj->symtab[symnum].st_value != 0)
+				break;
+#ifdef COMBRELOC
+			if (symnum != lastsym) {
+#endif
+				def = _rtld_find_symdef(symnum, obj, &defobj,
+				    false);
+				if (def == NULL)
+					return -1;
+				target = (Elf_Addr)(defobj->relocbase +
+				    def->st_value);
+#ifdef COMBRELOC
+				lastsym = symnum;
+			}
+#endif
+
+			tmp = target + *where;
+			if (*where != tmp)
+				*where = tmp;
+			rdbg(("32/GLOB_DAT %s in %s --> %p in %s",
+			    obj->strtab + obj->symtab[symnum].st_name,
+			    obj->path, (void *)*where, defobj->path));
+			break;
+
+		}
+	}
+	return 0;
+}
+
+int
 _rtld_relocate_plt_lazy(obj)
 	const Obj_Entry *obj;
 {

--vkogqOf2sHV7VnPd
Content-Type: application/x-tar-gz
Content-Disposition: attachment; filename="prebind-20020921.tar.gz"
Content-Transfer-Encoding: base64

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

--vkogqOf2sHV7VnPd--