summaryrefslogtreecommitdiff
path: root/libexec/ld.so/loader.c
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2003-09-04 19:33:51 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2003-09-04 19:33:51 +0000
commit29153d4f5d5ce3630a02cc3cf4cf730b0a5ead11 (patch)
tree2a1d053c01a48b7525f6a6f8419e05bd86dff69d /libexec/ld.so/loader.c
parent60dd990bce1a4f0ccb85ad7cb0957d7c47a202ef (diff)
Symbol cache for GOT lookup. When a symbol is found it is saved in a cache
for future lookups in the same GOT relocation table. Uses static buffer for small symbol tables, mmap for larger ones. ok deraadt@
Diffstat (limited to 'libexec/ld.so/loader.c')
-rw-r--r--libexec/ld.so/loader.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index a6d77780a1f..dac1f42f17b 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.67 2003/09/02 15:17:51 drahn Exp $ */
+/* $OpenBSD: loader.c,v 1.68 2003/09/04 19:33:48 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -42,6 +42,7 @@
#include "archdep.h"
#include "resolve.h"
#include "sod.h"
+#include "stdlib.h"
/*
* Local decls.
@@ -599,21 +600,50 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
*/
}
+#define DL_SM_SYMBUF_CNT 512
+sym_cache _dl_sm_symcache_buffer[DL_SM_SYMBUF_CNT];
+
void
_dl_rtld(elf_object_t *object)
{
+ size_t sz;
if (object->next)
_dl_rtld(object->next);
if (object->status & STAT_RELOC_DONE)
return;
+ sz = 0;
+ if (object->nchains < DL_SM_SYMBUF_CNT) {
+ _dl_symcache = _dl_sm_symcache_buffer;
+ DL_DEB(("using static buffer for %d entries\n",
+ object->nchains));
+ _dl_memset(_dl_symcache, 0,
+ sizeof (sym_cache) * object->nchains);
+ } else {
+ sz = ELF_ROUND(sizeof (sym_cache) * object->nchains,
+ _dl_pagesz);
+ DL_DEB(("allocating symcache sz %x with mmap\n", sz));
+
+ _dl_symcache = (void *)_dl_mmap(0, sz, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANON, -1, 0);
+ if (_dl_symcache == (void *)MAP_FAILED) {
+ sz = 0;
+ _dl_symcache = NULL;
+ }
+ }
/*
* Do relocation information first, then GOT.
*/
_dl_md_reloc(object, DT_REL, DT_RELSZ);
_dl_md_reloc(object, DT_RELA, DT_RELASZ);
_dl_md_reloc_got(object, !(_dl_bindnow || object->dyn.bind_now));
+
+ if (_dl_symcache != NULL) {
+ if (sz != 0)
+ _dl_munmap( _dl_symcache, sz);
+ _dl_symcache = NULL;
+ }
object->status |= STAT_RELOC_DONE;
}