summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2004-02-10 16:14:12 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2004-02-10 16:14:12 +0000
commit072f1c2a5e0d134c2b6927e3a6b2055d810a7f4a (patch)
treee30f2d3ea1bdb36d9db9f8fe111e961a185102ff
parent29ac32c6067f19ba2d955039c13771eb909853ff (diff)
Fix/enable lazy binding on amd64 ld.so
-rw-r--r--libexec/ld.so/amd64/rtld_machine.c42
-rw-r--r--libexec/ld.so/x86_64/rtld_machine.c42
2 files changed, 22 insertions, 62 deletions
diff --git a/libexec/ld.so/amd64/rtld_machine.c b/libexec/ld.so/amd64/rtld_machine.c
index 8cba8174cab..2f4a2a7fb83 100644
--- a/libexec/ld.so/amd64/rtld_machine.c
+++ b/libexec/ld.so/amd64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.3 2004/02/10 14:47:07 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.4 2004/02/10 16:14:11 drahn Exp $ */
/*
* Copyright (c) 2002,2004 Dale Rahn
@@ -228,11 +228,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
where = (Elf_Addr *)(rels->r_offset + loff);
if (RELOC_USE_ADDEND(type))
-#if 1
value = rels->r_addend;
-#else
- value = *where & RELOC_VALUE_BITMASK(type);
-#endif
else
value = 0;
@@ -339,16 +335,6 @@ resolve_failed:
return (fails);
}
-#if 0
-struct jmpslot {
- u_short opcode;
- u_short addr[2];
- u_short reloc_index;
-#define JMPSLOT_RELOC_MASK 0xffff
-};
-#define JUMP 0xe990 /* NOP + JMP opcode */
-#endif
-
void
_dl_reloc_plt(Elf_Addr *where, Elf_Addr value)
{
@@ -361,16 +347,16 @@ _dl_reloc_plt(Elf_Addr *where, Elf_Addr value)
Elf_Addr
_dl_bind(elf_object_t *object, int index)
{
- Elf_Rel *rel;
+ Elf_RelA *rel;
Elf_Word *addr;
const Elf_Sym *sym, *this;
const char *symn;
- Elf_Addr ooff;
+ Elf_Addr ooff, newval;
sigset_t omask, nmask;
- rel = (Elf_Rel *)(object->Dyn.info[DT_JMPREL]);
+ rel = (Elf_RelA *)(object->Dyn.info[DT_JMPREL]);
- rel += index/sizeof(Elf_Rel);
+ rel += index;
sym = object->dyn.symtab;
sym += ELF_R_SYM(rel->r_info);
@@ -385,6 +371,8 @@ _dl_bind(elf_object_t *object, int index)
*((int *)0) = 0; /* XXX */
}
+ newval = ooff + this->st_value + rel->r_addend;
+
/* if GOT is protected, allow the write */
if (object->got_size != 0) {
sigfillset(&nmask);
@@ -393,7 +381,7 @@ _dl_bind(elf_object_t *object, int index)
PROT_READ|PROT_WRITE);
}
- _dl_reloc_plt((Elf_Addr *)addr, ooff + this->st_value);
+ _dl_reloc_plt((Elf_Addr *)addr, newval);
/* put the GOT back to RO */
if (object->got_size != 0) {
@@ -402,21 +390,16 @@ _dl_bind(elf_object_t *object, int index)
_dl_sigprocmask(SIG_SETMASK, &omask, NULL);
}
- return((Elf_Addr)ooff + this->st_value);
+ return(newval);
}
-/*/
-#define LAZY_BINDING_WORKS
- */
void
_dl_md_reloc_got(elf_object_t *object, int lazy)
{
extern void _dl_bind_start(void); /* XXX */
Elf_Addr *pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT];
-#ifdef LAZY_BINDING_WORKS
int i, num;
Elf_RelA *rel;
-#endif
Elf_Addr ooff;
const Elf_Sym *this;
@@ -451,22 +434,19 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
}
-#ifdef LAZY_BINDING_WORKS
if (!lazy) {
-#endif
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
-#ifdef LAZY_BINDING_WORKS
} else {
rel = (Elf_RelA *)(object->Dyn.info[DT_JMPREL]);
num = (object->Dyn.info[DT_PLTRELSZ]);
for (i = 0; i < num/sizeof(Elf_RelA); i++, rel++) {
Elf_Addr *where;
where = (Elf_Addr *)(rel->r_offset + object->load_offs);
- *where = object->load_offs + rel->r_addend;
+ *where += object->load_offs;
}
}
-#endif
+
/* PLT is already RO on i386, no point in mprotecting it, just GOT */
if (object->got_size != 0)
_dl_mprotect((void*)object->got_start, object->got_size,
diff --git a/libexec/ld.so/x86_64/rtld_machine.c b/libexec/ld.so/x86_64/rtld_machine.c
index 8cba8174cab..2f4a2a7fb83 100644
--- a/libexec/ld.so/x86_64/rtld_machine.c
+++ b/libexec/ld.so/x86_64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.3 2004/02/10 14:47:07 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.4 2004/02/10 16:14:11 drahn Exp $ */
/*
* Copyright (c) 2002,2004 Dale Rahn
@@ -228,11 +228,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
where = (Elf_Addr *)(rels->r_offset + loff);
if (RELOC_USE_ADDEND(type))
-#if 1
value = rels->r_addend;
-#else
- value = *where & RELOC_VALUE_BITMASK(type);
-#endif
else
value = 0;
@@ -339,16 +335,6 @@ resolve_failed:
return (fails);
}
-#if 0
-struct jmpslot {
- u_short opcode;
- u_short addr[2];
- u_short reloc_index;
-#define JMPSLOT_RELOC_MASK 0xffff
-};
-#define JUMP 0xe990 /* NOP + JMP opcode */
-#endif
-
void
_dl_reloc_plt(Elf_Addr *where, Elf_Addr value)
{
@@ -361,16 +347,16 @@ _dl_reloc_plt(Elf_Addr *where, Elf_Addr value)
Elf_Addr
_dl_bind(elf_object_t *object, int index)
{
- Elf_Rel *rel;
+ Elf_RelA *rel;
Elf_Word *addr;
const Elf_Sym *sym, *this;
const char *symn;
- Elf_Addr ooff;
+ Elf_Addr ooff, newval;
sigset_t omask, nmask;
- rel = (Elf_Rel *)(object->Dyn.info[DT_JMPREL]);
+ rel = (Elf_RelA *)(object->Dyn.info[DT_JMPREL]);
- rel += index/sizeof(Elf_Rel);
+ rel += index;
sym = object->dyn.symtab;
sym += ELF_R_SYM(rel->r_info);
@@ -385,6 +371,8 @@ _dl_bind(elf_object_t *object, int index)
*((int *)0) = 0; /* XXX */
}
+ newval = ooff + this->st_value + rel->r_addend;
+
/* if GOT is protected, allow the write */
if (object->got_size != 0) {
sigfillset(&nmask);
@@ -393,7 +381,7 @@ _dl_bind(elf_object_t *object, int index)
PROT_READ|PROT_WRITE);
}
- _dl_reloc_plt((Elf_Addr *)addr, ooff + this->st_value);
+ _dl_reloc_plt((Elf_Addr *)addr, newval);
/* put the GOT back to RO */
if (object->got_size != 0) {
@@ -402,21 +390,16 @@ _dl_bind(elf_object_t *object, int index)
_dl_sigprocmask(SIG_SETMASK, &omask, NULL);
}
- return((Elf_Addr)ooff + this->st_value);
+ return(newval);
}
-/*/
-#define LAZY_BINDING_WORKS
- */
void
_dl_md_reloc_got(elf_object_t *object, int lazy)
{
extern void _dl_bind_start(void); /* XXX */
Elf_Addr *pltgot = (Elf_Addr *)object->Dyn.info[DT_PLTGOT];
-#ifdef LAZY_BINDING_WORKS
int i, num;
Elf_RelA *rel;
-#endif
Elf_Addr ooff;
const Elf_Sym *this;
@@ -451,22 +434,19 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
object->got_size = ELF_ROUND(object->got_size, _dl_pagesz);
}
-#ifdef LAZY_BINDING_WORKS
if (!lazy) {
-#endif
_dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
-#ifdef LAZY_BINDING_WORKS
} else {
rel = (Elf_RelA *)(object->Dyn.info[DT_JMPREL]);
num = (object->Dyn.info[DT_PLTRELSZ]);
for (i = 0; i < num/sizeof(Elf_RelA); i++, rel++) {
Elf_Addr *where;
where = (Elf_Addr *)(rel->r_offset + object->load_offs);
- *where = object->load_offs + rel->r_addend;
+ *where += object->load_offs;
}
}
-#endif
+
/* PLT is already RO on i386, no point in mprotecting it, just GOT */
if (object->got_size != 0)
_dl_mprotect((void*)object->got_start, object->got_size,