summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/csu/boot.h203
-rw-r--r--libexec/ld.so/alpha/archdep.h14
-rw-r--r--libexec/ld.so/amd64/archdep.h13
-rw-r--r--libexec/ld.so/arm/archdep.h13
-rw-r--r--libexec/ld.so/boot.c190
-rw-r--r--libexec/ld.so/hppa/archdep.h23
-rw-r--r--libexec/ld.so/i386/archdep.h12
-rw-r--r--libexec/ld.so/m88k/archdep.h14
-rw-r--r--libexec/ld.so/mips64/archdep.h29
-rw-r--r--libexec/ld.so/powerpc/archdep.h14
-rw-r--r--libexec/ld.so/sh/archdep.h19
-rw-r--r--libexec/ld.so/sparc/archdep.h14
-rw-r--r--libexec/ld.so/sparc64/archdep.h14
13 files changed, 207 insertions, 365 deletions
diff --git a/lib/csu/boot.h b/lib/csu/boot.h
index ee8e7b91c65..a4867b3035f 100644
--- a/lib/csu/boot.h
+++ b/lib/csu/boot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.h,v 1.13 2015/09/19 20:11:22 kettenis Exp $ */
+/* $OpenBSD: boot.h,v 1.14 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -50,10 +50,31 @@
#include "stdlib.h"
#include "dl_prebind.h"
-#define DT_PROC(n) ((n) - DT_LOPROC + DT_NUM)
-
#ifdef RCRT0
+#define DT_PROC(n) ((n) - DT_LOPROC)
+
+#if RELOC_TAG == DT_RELA
+typedef Elf_RelA RELOC_TYPE;
+#elif RELOC_TAG == DT_REL
+typedef Elf_Rel RELOC_TYPE;
+#else
+# error "unknown RELOC_TAG"
+#endif
+
+/* The set of dynamic tags that we're interested in for bootstrapping */
+struct boot_dyn {
+ RELOC_TYPE *dt_reloc; /* DT_RELA or DT_REL */
+ Elf_Addr dt_relocsz; /* DT_RELASZ or DT_RELSZ */
+ Elf_Addr *dt_pltgot;
+ Elf_Addr dt_pltrelsz;
+ const Elf_Sym *dt_symtab;
+ RELOC_TYPE *dt_jmprel;
+#if DT_PROCNUM > 0
+ u_long dt_proc[DT_PROCNUM];
+#endif
+};
+
/*
* Local decls.
*/
@@ -67,7 +88,7 @@ extern char __got_end[];
void
_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
{
- struct elf_object dynld; /* Resolver data for the loader */
+ struct boot_dyn dynld; /* Resolver data for the loader */
AuxInfo *auxstack;
long *stack;
Elf_Dyn *dynp;
@@ -75,9 +96,11 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
size_t size;
int pagesize;
int n, argc;
- char **argv, **envp;
- long loff;
- int prot_exec = 0;
+ char **argv, **envp;
+ long loff;
+ int prot_exec = 0;
+ RELOC_TYPE *rp;
+ Elf_Addr i;
/*
* Scan argument and environment vectors. Find dynamic
@@ -125,145 +148,61 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
#else
dynp = (Elf_Dyn *)((long)_DYNAMIC + loff);
#endif
- _dl_memset(dynld.Dyn.info, 0, sizeof(dynld.Dyn.info));
- while (dynp != NULL && dynp->d_tag != DT_NULL) {
- if (dynp->d_tag < DT_NUM)
- dynld.Dyn.info[dynp->d_tag] = dynp->d_un.d_val;
+
+ _dl_memset(&dynld, 0, sizeof(dynld));
+ while (dynp->d_tag != DT_NULL) {
+ /* first the tags that are pointers to be relocated */
+ if (dynp->d_tag == DT_PLTGOT)
+ dynld.dt_pltgot = (void *)(dynp->d_un.d_ptr + loff);
+ else if (dynp->d_tag == DT_SYMTAB)
+ dynld.dt_symtab = (void *)(dynp->d_un.d_ptr + loff);
+ else if (dynp->d_tag == RELOC_TAG) /* DT_{RELA,REL} */
+ dynld.dt_reloc = (void *)(dynp->d_un.d_ptr + loff);
+ else if (dynp->d_tag == DT_JMPREL)
+ dynld.dt_jmprel = (void *)(dynp->d_un.d_ptr + loff);
+
+ /* Now for the tags that are just sizes or counts */
+ else if (dynp->d_tag == DT_PLTRELSZ)
+ dynld.dt_pltrelsz = dynp->d_un.d_val;
+ else if (dynp->d_tag == RELOC_TAG+1) /* DT_{RELA,REL}SZ */
+ dynld.dt_relocsz = dynp->d_un.d_val;
+#if DT_PROCNUM > 0
else if (dynp->d_tag >= DT_LOPROC &&
dynp->d_tag < DT_LOPROC + DT_PROCNUM)
- dynld.Dyn.info[dynp->d_tag - DT_LOPROC + DT_NUM] =
+ dynld.dt_proc[dynp->d_tag - DT_LOPROC] =
dynp->d_un.d_val;
- if (dynp->d_tag == DT_TEXTREL)
- dynld.dyn.textrel = 1;
+#endif /* DT_PROCNUM */
dynp++;
}
- /*
- * Do the 'bootstrap relocation'. This is really only needed if
- * the code was loaded at another location than it was linked to.
- * We don't do undefined symbols resolving (to difficult..)
- */
+ rp = dynld.dt_jmprel;
+ for (i = 0; i < dynld.dt_pltrelsz; i += sizeof *rp) {
+ Elf_Addr *ra;
+ const Elf_Sym *sp;
- /* "relocate" dyn.X values if they represent addresses */
- {
- int i, val;
- /* must be code, not pic data */
- int table[20];
-
- i = 0;
- table[i++] = DT_PLTGOT;
- table[i++] = DT_HASH;
- table[i++] = DT_STRTAB;
- table[i++] = DT_SYMTAB;
- table[i++] = DT_RELA;
- table[i++] = DT_INIT;
- table[i++] = DT_FINI;
- table[i++] = DT_REL;
- table[i++] = DT_JMPREL;
- table[i++] = DT_PLTREL;
- /* other processors insert their extras here */
- table[i++] = DT_NULL;
- for (i = 0; table[i] != DT_NULL; i++) {
- val = table[i];
- if (val >= DT_LOPROC && val < DT_LOPROC + DT_PROCNUM)
- val = val - DT_LOPROC + DT_NUM;
- else if (val >= DT_NUM || val == DT_PLTREL)
- continue;
- if (dynld.Dyn.info[val] != 0)
- dynld.Dyn.info[val] += loff;
- }
- }
-
- for (n = 0; n < 2; n++) {
- u_int32_t rs;
- Elf_Rel *rp;
- int i;
-
- switch (n) {
- case 0:
- if (dynld.Dyn.info[DT_PLTREL] != DT_REL)
- continue;
- rp = (Elf_Rel *)(dynld.Dyn.info[DT_JMPREL]);
- rs = dynld.dyn.pltrelsz;
- break;
- case 1:
- rp = (Elf_Rel *)(dynld.Dyn.info[DT_REL]);
- rs = dynld.dyn.relsz;
- break;
- default:
- rp = NULL;
- rs = 0;
- }
- for (i = 0; i < rs; i += sizeof (Elf_Rel), rp++) {
- Elf_Addr *ra;
- const Elf_Sym *sp;
-
- sp = dynld.dyn.symtab;
- sp += ELF_R_SYM(rp->r_info);
-
- if (ELF_R_SYM(rp->r_info) && sp->st_value == 0) {
-#if 0
-/* cannot printf in this function */
- _dl_wrstderr("Dynamic loader failure: self bootstrapping impossible.\n");
- _dl_wrstderr("Undefined symbol: ");
- _dl_wrstderr((char *)dynld.dyn.strtab +
- sp->st_name);
-#endif
-#ifdef RCRT0
- continue;
+ sp = dynld.dt_symtab + ELF_R_SYM(rp->r_info);
+ if (!ELF_R_SYM(rp->r_info) || sp->st_value != 0) {
+#ifdef HAVE_JMPREL
+ ra = (Elf_Addr *)(rp->r_offset + loff);
+ RELOC_JMPREL(rp, sp, ra, loff, dynld.dt_pltgot);
#else
- _dl_exit(5);
+ _dl_exit(6);
#endif
- }
-
- ra = (Elf_Addr *)(rp->r_offset + loff);
- RELOC_REL(rp, sp, ra, loff);
}
+ rp++;
}
- for (n = 0; n < 2; n++) {
- unsigned long rs;
- Elf_RelA *rp;
- int i;
-
- switch (n) {
- case 0:
- if (dynld.Dyn.info[DT_PLTREL] != DT_RELA)
- continue;
- rp = (Elf_RelA *)(dynld.Dyn.info[DT_JMPREL]);
- rs = dynld.dyn.pltrelsz;
- break;
- case 1:
- rp = (Elf_RelA *)(dynld.Dyn.info[DT_RELA]);
- rs = dynld.dyn.relasz;
- break;
- default:
- rp = NULL;
- rs = 0;
- }
- for (i = 0; i < rs; i += sizeof (Elf_RelA), rp++) {
- Elf_Addr *ra;
- const Elf_Sym *sp;
-
- sp = dynld.dyn.symtab;
- sp += ELF_R_SYM(rp->r_info);
- if (ELF_R_SYM(rp->r_info) && sp->st_value == 0) {
-#if 0
- _dl_wrstderr("Dynamic loader failure: self bootstrapping impossible.\n");
- _dl_wrstderr("Undefined symbol: ");
- _dl_wrstderr((char *)dynld.dyn.strtab +
- sp->st_name);
-#endif
-#ifdef RCRT0
- continue;
-#else
- _dl_exit(6);
-#endif
- }
+ rp = dynld.dt_reloc;
+ for (i = 0; i < dynld.dt_relocsz; i += sizeof *rp) {
+ Elf_Addr *ra;
+ const Elf_Sym *sp;
+ sp = dynld.dt_symtab + ELF_R_SYM(rp->r_info);
+ if (!ELF_R_SYM(rp->r_info) || sp->st_value != 0) {
ra = (Elf_Addr *)(rp->r_offset + loff);
- RELOC_RELA(rp, sp, ra, loff, dynld.dyn.pltgot);
+ RELOC_DYN(rp, sp, ra, loff);
}
+ rp++;
}
RELOC_GOT(&dynld, loff);
@@ -291,7 +230,7 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
#endif
#if defined(__powerpc__)
- if (dynld.Dyn.info[DT_PROC(DT_PPC_GOT)] == 0)
+ if (dynld.dt_proc[DT_PROC(DT_PPC_GOT)] == 0)
prot_exec = PROT_EXEC;
#endif
diff --git a/libexec/ld.so/alpha/archdep.h b/libexec/ld.so/alpha/archdep.h
index 930efed3929..7cb62da591e 100644
--- a/libexec/ld.so/alpha/archdep.h
+++ b/libexec/ld.so/alpha/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.16 2014/12/27 13:13:25 kettenis Exp $ */
+/* $OpenBSD: archdep.h,v 1.17 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _ALPHA_ARCHDEP_H_
#define _ALPHA_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_ALPHA_EXP /* ELF e_machine ID value checked */
@@ -42,15 +44,7 @@
#include "util.h"
static inline void
-RELOC_REL(Elf64_Rel *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
-{
- /* Alpha does not use REL type relocations */
- _dl_exit(20);
-}
-
-static inline void
-RELOC_RELA(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
{
if (ELF64_R_TYPE(r->r_info) == RELOC_RELATIVE) {
/* handled by _reloc_alpha_got */
diff --git a/libexec/ld.so/amd64/archdep.h b/libexec/ld.so/amd64/archdep.h
index 93651a4134a..96b8e3d8642 100644
--- a/libexec/ld.so/amd64/archdep.h
+++ b/libexec/ld.so/amd64/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.6 2014/12/22 03:51:08 kurt Exp $ */
+/* $OpenBSD: archdep.h,v 1.7 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _X86_64_ARCHDEP_H_
#define _X86_64_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_AMD64 /* ELF e_machine ID value checked */
@@ -52,14 +54,7 @@ _dl_mmap(void *addr, unsigned int len, unsigned int prot,
static inline void
-RELOC_REL(Elf64_Rel *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
-{
- /* AMD64 is a rela architecture */
-}
-
-static inline void
-RELOC_RELA(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
{
if (ELF64_R_TYPE(r->r_info) == R_X86_64_RELATIVE) {
*p = v + r->r_addend;
diff --git a/libexec/ld.so/arm/archdep.h b/libexec/ld.so/arm/archdep.h
index 25fb901ab0b..e805dcd19c0 100644
--- a/libexec/ld.so/arm/archdep.h
+++ b/libexec/ld.so/arm/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.5 2014/07/05 12:22:41 miod Exp $ */
+/* $OpenBSD: archdep.h,v 1.6 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _ARM_ARCHDEP_H_
#define _ARM_ARCHDEP_H_
+#define RELOC_TAG DT_REL
+
#define DL_MALLOC_ALIGN 4 /* Arch constraint or otherwise */
#define MACHID EM_ARM /* ELF e_machine ID value checked */
@@ -55,7 +57,7 @@ _dl_mmap(void *addr, unsigned int len, unsigned int prot,
}
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
+RELOC_DYN(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
{
if (ELF_R_TYPE(r->r_info) == R_ARM_RELATIVE) {
*p += v;
@@ -66,13 +68,6 @@ RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
}
}
-static inline void
-RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
-{
- _dl_exit(20);
-}
-
#define RELOC_GOT(obj, offs)
#define GOT_PERMS (PROT_READ|PROT_EXEC)
diff --git a/libexec/ld.so/boot.c b/libexec/ld.so/boot.c
index ca51e80be22..30e646cb22f 100644
--- a/libexec/ld.so/boot.c
+++ b/libexec/ld.so/boot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.c,v 1.5 2015/01/16 16:18:07 deraadt Exp $ */
+/* $OpenBSD: boot.c,v 1.6 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -44,14 +44,33 @@
#include "syscall.h"
#include "archdep.h"
-#include "path.h"
-#include "resolve.h"
-#include "sod.h"
#include "stdlib.h"
-#include "dl_prebind.h"
#include "../../lib/csu/os-note-elf.h"
+#if RELOC_TAG == DT_RELA
+typedef Elf_RelA RELOC_TYPE;
+#elif RELOC_TAG == DT_REL
+typedef Elf_Rel RELOC_TYPE;
+#else
+# error "unknown RELOC_TAG"
+#endif
+
+/* The set of dynamic tags that we're interested in for bootstrapping */
+struct boot_dyn {
+ RELOC_TYPE *dt_reloc; /* DT_RELA or DT_REL */
+ Elf_Addr dt_relocsz; /* DT_RELASZ or DT_RELSZ */
+ Elf_Addr *dt_pltgot;
+ Elf_Addr dt_pltrelsz;
+ const Elf_Sym *dt_symtab;
+#ifdef HAVE_JMPREL
+ RELOC_TYPE *dt_jmprel;
+#endif
+#if DT_PROCNUM > 0
+ u_long dt_proc[DT_PROCNUM];
+#endif
+};
+
/*
* Local decls.
*/
@@ -60,13 +79,15 @@ void _dl_boot_bind(const long, long *, Elf_Dyn *);
void
_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
{
- struct elf_object dynld; /* Resolver data for the loader */
+ struct boot_dyn dynld; /* Resolver data for the loader */
AuxInfo *auxstack;
long *stack;
Elf_Dyn *dynp;
int n, argc;
- char **argv, **envp;
- long loff;
+ char **argv, **envp;
+ long loff;
+ Elf_Addr i;
+ RELOC_TYPE *rp;
/*
* Scan argument and environment vectors. Find dynamic
@@ -114,124 +135,63 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
#else
dynp = (Elf_Dyn *)((long)_DYNAMIC + loff);
#endif
- _dl_memset(dynld.Dyn.info, 0, sizeof(dynld.Dyn.info));
- while (dynp != NULL && dynp->d_tag != DT_NULL) {
- if (dynp->d_tag < DT_NUM)
- dynld.Dyn.info[dynp->d_tag] = dynp->d_un.d_val;
+
+ _dl_memset(&dynld, 0, sizeof(dynld));
+ while (dynp->d_tag != DT_NULL) {
+ /* first the tags that are pointers to be relocated */
+ if (dynp->d_tag == DT_PLTGOT)
+ dynld.dt_pltgot = (void *)(dynp->d_un.d_ptr + loff);
+ else if (dynp->d_tag == DT_SYMTAB)
+ dynld.dt_symtab = (void *)(dynp->d_un.d_ptr + loff);
+ else if (dynp->d_tag == RELOC_TAG) /* DT_{RELA,REL} */
+ dynld.dt_reloc = (void *)(dynp->d_un.d_ptr + loff);
+#ifdef HAVE_JMPREL
+ else if (dynp->d_tag == DT_JMPREL)
+ dynld.dt_jmprel = (void *)(dynp->d_un.d_ptr + loff);
+#endif
+
+ /* Now for the tags that are just sizes or counts */
+ else if (dynp->d_tag == DT_PLTRELSZ)
+ dynld.dt_pltrelsz = dynp->d_un.d_val;
+ else if (dynp->d_tag == RELOC_TAG+1) /* DT_{RELA,REL}SZ */
+ dynld.dt_relocsz = dynp->d_un.d_val;
+#if DT_PROCNUM > 0
else if (dynp->d_tag >= DT_LOPROC &&
dynp->d_tag < DT_LOPROC + DT_PROCNUM)
- dynld.Dyn.info[dynp->d_tag - DT_LOPROC + DT_NUM] =
+ dynld.dt_proc[dynp->d_tag - DT_LOPROC] =
dynp->d_un.d_val;
- if (dynp->d_tag == DT_TEXTREL)
- dynld.dyn.textrel = 1;
+#endif /* DT_PROCNUM */
dynp++;
}
- /*
- * Do the 'bootstrap relocation'. This is really only needed if
- * the code was loaded at another location than it was linked to.
- * We don't do undefined symbols resolving (to difficult..)
- */
-
- /* "relocate" dyn.X values if they represent addresses */
- {
- int i, val;
- /* must be code, not pic data */
- int table[20];
-
- i = 0;
- table[i++] = DT_PLTGOT;
- table[i++] = DT_HASH;
- table[i++] = DT_STRTAB;
- table[i++] = DT_SYMTAB;
- table[i++] = DT_RELA;
- table[i++] = DT_INIT;
- table[i++] = DT_FINI;
- table[i++] = DT_REL;
- table[i++] = DT_JMPREL;
- /* other processors insert their extras here */
- table[i++] = DT_NULL;
- for (i = 0; table[i] != DT_NULL; i++) {
- val = table[i];
- if (val >= DT_LOPROC && val < DT_LOPROC + DT_PROCNUM)
- val = val - DT_LOPROC + DT_NUM;
- else if (val >= DT_NUM)
- continue;
- if (dynld.Dyn.info[val] != 0)
- dynld.Dyn.info[val] += loff;
- }
- }
-
- {
- u_int32_t rs;
- Elf_Rel *rp;
- int i;
-
- rp = (Elf_Rel *)(dynld.Dyn.info[DT_REL]);
- rs = dynld.dyn.relsz;
+#ifdef HAVE_JMPREL
+ rp = dynld.dt_jmprel;
+ for (i = 0; i < dynld.dt_pltrelsz; i += sizeof *rp) {
+ Elf_Addr *ra;
+ const Elf_Sym *sp;
- for (i = 0; i < rs; i += sizeof (Elf_Rel)) {
- Elf_Addr *ra;
- const Elf_Sym *sp;
+ sp = dynld.dt_symtab + ELF_R_SYM(rp->r_info);
+ if (ELF_R_SYM(rp->r_info) && sp->st_value == 0)
+ _dl_exit(5);
- sp = dynld.dyn.symtab;
- sp += ELF_R_SYM(rp->r_info);
-
- if (ELF_R_SYM(rp->r_info) && sp->st_value == 0) {
-#if 0
-/* cannot printf in this function */
- _dl_wrstderr("Dynamic loader failure: self bootstrapping impossible.\n");
- _dl_wrstderr("Undefined symbol: ");
- _dl_wrstderr((char *)dynld.dyn.strtab +
- sp->st_name);
-#endif
- _dl_exit(5);
- }
-
- ra = (Elf_Addr *)(rp->r_offset + loff);
- RELOC_REL(rp, sp, ra, loff);
- rp++;
- }
+ ra = (Elf_Addr *)(rp->r_offset + loff);
+ RELOC_JMPREL(rp, sp, ra, loff, dynld.dt_pltgot);
+ rp++;
}
+#endif /* HAVE_JMPREL */
- for (n = 0; n < 2; n++) {
- unsigned long rs;
- Elf_RelA *rp;
- int i;
-
- switch (n) {
- case 0:
- rp = (Elf_RelA *)(dynld.Dyn.info[DT_JMPREL]);
- rs = dynld.dyn.pltrelsz;
- break;
- case 1:
- rp = (Elf_RelA *)(dynld.Dyn.info[DT_RELA]);
- rs = dynld.dyn.relasz;
- break;
- default:
- rp = NULL;
- rs = 0;
- }
- for (i = 0; i < rs; i += sizeof (Elf_RelA)) {
- Elf_Addr *ra;
- const Elf_Sym *sp;
-
- sp = dynld.dyn.symtab;
- sp += ELF_R_SYM(rp->r_info);
- if (ELF_R_SYM(rp->r_info) && sp->st_value == 0) {
-#if 0
- _dl_wrstderr("Dynamic loader failure: self bootstrapping impossible.\n");
- _dl_wrstderr("Undefined symbol: ");
- _dl_wrstderr((char *)dynld.dyn.strtab +
- sp->st_name);
-#endif
- _dl_exit(6);
- }
+ rp = dynld.dt_reloc;
+ for (i = 0; i < dynld.dt_relocsz; i += sizeof *rp) {
+ Elf_Addr *ra;
+ const Elf_Sym *sp;
+
+ sp = dynld.dt_symtab + ELF_R_SYM(rp->r_info);
+ if (ELF_R_SYM(rp->r_info) && sp->st_value == 0)
+ _dl_exit(6);
- ra = (Elf_Addr *)(rp->r_offset + loff);
- RELOC_RELA(rp, sp, ra, loff, dynld.dyn.pltgot);
- rp++;
- }
+ ra = (Elf_Addr *)(rp->r_offset + loff);
+ RELOC_DYN(rp, sp, ra, loff);
+ rp++;
}
RELOC_GOT(&dynld, loff);
diff --git a/libexec/ld.so/hppa/archdep.h b/libexec/ld.so/hppa/archdep.h
index b298f599757..700d1ce8226 100644
--- a/libexec/ld.so/hppa/archdep.h
+++ b/libexec/ld.so/hppa/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.9 2014/01/19 10:25:45 guenther Exp $ */
+/* $OpenBSD: archdep.h,v 1.10 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 2004 Michael Shalayeff
@@ -30,6 +30,9 @@
#ifndef _HPPA_ARCHDEP_H_
#define _HPPA_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+#define HAVE_JMPREL 1
+
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_PARISC /* ELF e_machine ID value checked */
@@ -53,24 +56,26 @@ _dl_mmap(void *addr, unsigned int len, unsigned int prot,
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
+RELOC_JMPREL(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v,
+ Elf_Addr *pltgot)
{
- /* HPPA does no REL type relocations */
- _dl_exit(20);
+ if (ELF_R_TYPE(r->r_info) == RELOC_IPLT) {
+ p[0] = v + s->st_value + r->r_addend;
+ p[1] = (Elf_Addr)pltgot;
+ } else {
+ _dl_printf("unknown bootstrap relocation\n");
+ _dl_exit(5);
+ }
}
static inline void
-RELOC_RELA(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
{
if (ELF_R_TYPE(r->r_info) == RELOC_DIR32) {
if (ELF_R_SYM(r->r_info) != 0)
*p = v + s->st_value + r->r_addend;
else
*p = v + r->r_addend;
- } else if (ELF_R_TYPE(r->r_info) == RELOC_IPLT) {
- p[0] = v + s->st_value + r->r_addend;
- p[1] = (Elf_Addr)pltgot;
} else if (ELF_R_TYPE(r->r_info) == RELOC_PLABEL32) {
*p = v + s->st_value + r->r_addend;
} else {
diff --git a/libexec/ld.so/i386/archdep.h b/libexec/ld.so/i386/archdep.h
index a08d058dc6c..5bcea320c22 100644
--- a/libexec/ld.so/i386/archdep.h
+++ b/libexec/ld.so/i386/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.13 2014/12/24 14:04:09 kurt Exp $ */
+/* $OpenBSD: archdep.h,v 1.14 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _I386_ARCHDEP_H_
#define _I386_ARCHDEP_H_
+#define RELOC_TAG DT_REL
+
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_386 /* ELF e_machine ID value checked */
@@ -60,7 +62,7 @@ _dl_mquery(void *addr, unsigned int len, unsigned int prot,
static inline void
-RELOC_REL(Elf32_Rel *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
+RELOC_DYN(Elf32_Rel *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
{
if (ELF32_R_TYPE(r->r_info) == RELOC_RELATIVE) {
@@ -75,12 +77,6 @@ RELOC_REL(Elf32_Rel *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
}
}
-static inline void
-RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
-{
-}
-
#define RELOC_GOT(obj, offs)
#define GOT_PERMS PROT_READ
diff --git a/libexec/ld.so/m88k/archdep.h b/libexec/ld.so/m88k/archdep.h
index 019acd62004..f55aa46bee9 100644
--- a/libexec/ld.so/m88k/archdep.h
+++ b/libexec/ld.so/m88k/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.1 2013/01/20 23:01:44 miod Exp $ */
+/* $OpenBSD: archdep.h,v 1.2 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _M88K_ARCHDEP_H_
#define _M88K_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 4 /* Arch constraint or otherwise */
#define MACHID EM_88K /* ELF e_machine ID value checked */
@@ -47,15 +49,7 @@
*/
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
-{
- /* m88k does not use REL type relocations */
- _dl_exit(20);
-}
-
-static inline void
-RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
{
if (ELF32_R_TYPE(r->r_info) == RELOC_BBASED_32) {
*p = v + r->r_addend;
diff --git a/libexec/ld.so/mips64/archdep.h b/libexec/ld.so/mips64/archdep.h
index ec34a50dec0..0709c7699ce 100644
--- a/libexec/ld.so/mips64/archdep.h
+++ b/libexec/ld.so/mips64/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.9 2014/12/30 11:26:48 kettenis Exp $ */
+/* $OpenBSD: archdep.h,v 1.10 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998-2002 Opsycon AB, Sweden.
@@ -35,11 +35,12 @@
#include "resolve.h"
#include "util.h"
+#define RELOC_TAG DT_REL
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_MIPS /* ELF e_machine ID value checked */
-#define RELOC_REL(relp, symp, adrp, val) \
+#define RELOC_DYN(relp, symp, adrp, val) \
do { \
if (ELF64_R_TYPE(relp->r_info) == R_MIPS_REL32_64) { \
if (ELF64_R_SYM(relp->r_info) != 0) \
@@ -51,24 +52,17 @@ do { \
} \
} while (0)
-#define RELOC_RELA(rela, sym, ptr, val, pltgot) \
-do { \
- _dl_exit(20); /* We don't do RELA now */ \
-} while (0)
-
-struct elf_object;
-
#define RELOC_GOT(obj, off) \
do { \
- struct elf_object *__dynld = obj; \
+ struct boot_dyn *__dynld = obj; \
long __loff = off; \
Elf64_Addr *gotp; \
int i, n; \
const Elf_Sym *sp; \
\
/* Do all local gots */ \
- gotp = __dynld->dyn.pltgot; \
- n = __dynld->Dyn.info[DT_MIPS_LOCAL_GOTNO - DT_LOPROC + DT_NUM];\
+ gotp = __dynld->dt_pltgot; \
+ n = __dynld->dt_proc[DT_MIPS_LOCAL_GOTNO - DT_LOPROC]; \
\
for (i = ((gotp[1] & 0x0000000080000000) ? 2 : 1); i < n; i++) {\
gotp[i] += __loff; \
@@ -76,16 +70,16 @@ do { \
gotp += n; \
\
/* Do symbol referencing gots. There should be no global... */ \
- n = __dynld->Dyn.info[DT_MIPS_SYMTABNO - DT_LOPROC + DT_NUM] - \
- __dynld->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM]; \
- sp = __dynld->dyn.symtab; \
- sp += __dynld->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM]; \
+ n = __dynld->dt_proc[DT_MIPS_SYMTABNO - DT_LOPROC] - \
+ __dynld->dt_proc[DT_MIPS_GOTSYM - DT_LOPROC]; \
+ sp = __dynld->dt_symtab; \
+ sp += __dynld->dt_proc[DT_MIPS_GOTSYM - DT_LOPROC]; \
\
while (n--) { \
if (sp->st_shndx == SHN_UNDEF || \
sp->st_shndx == SHN_COMMON) { \
if (ELF64_ST_BIND(sp->st_info) != STB_WEAK) \
- _dl_exit(6); \
+ _dl_exit(7); \
} else if (ELF64_ST_TYPE(sp->st_info) == STT_FUNC) { \
*gotp += __loff; \
} else { \
@@ -94,7 +88,6 @@ do { \
gotp++; \
sp++; \
} \
- __dynld->status |= STAT_GOT_DONE; \
} while (0)
#define GOT_PERMS PROT_READ
diff --git a/libexec/ld.so/powerpc/archdep.h b/libexec/ld.so/powerpc/archdep.h
index caa1c944336..9d4177c9448 100644
--- a/libexec/ld.so/powerpc/archdep.h
+++ b/libexec/ld.so/powerpc/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.17 2015/09/19 20:16:25 kettenis Exp $ */
+/* $OpenBSD: archdep.h,v 1.18 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _POWERPC_ARCHDEP_H_
#define _POWERPC_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 4 /* Arch constraint or otherwise */
#define MACHID EM_PPC /* ELF e_machine ID value checked */
@@ -58,15 +60,7 @@ _dl_dcbf(Elf32_Addr *addr)
}
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
-{
- /* PowerPC does not use REL type relocations */
- _dl_exit(20);
-}
-
-static inline void
-RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
{
if (ELF32_R_TYPE(r->r_info) == RELOC_RELATIVE) {
*p = v + r->r_addend;
diff --git a/libexec/ld.so/sh/archdep.h b/libexec/ld.so/sh/archdep.h
index 00f8aaf87ea..d6f201f6cbe 100644
--- a/libexec/ld.so/sh/archdep.h
+++ b/libexec/ld.so/sh/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.4 2014/12/30 19:26:38 miod Exp $ */
+/* $OpenBSD: archdep.h,v 1.5 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _SH_ARCHDEP_H_
#define _SH_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 4 /* Arch constraint or otherwise */
#define MACHID EM_SH /* ELF e_machine ID value checked */
@@ -57,20 +59,7 @@ _dl_mmap(void *addr, unsigned int len, unsigned int prot,
}
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
-{
- if (ELF_R_TYPE(r->r_info) == R_SH_RELATIVE) {
- *p += v;
- } else {
- /* XXX - printf might not work here, but we give it a shot. */
- _dl_printf("Unknown bootstrap relocation.\n");
- _dl_exit(6);
- }
-}
-
-static inline void
-RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
{
if (ELF_R_TYPE(r->r_info) == R_SH_RELATIVE) {
*p = v + r->r_addend;
diff --git a/libexec/ld.so/sparc/archdep.h b/libexec/ld.so/sparc/archdep.h
index 4e967144cb7..214d6b25b97 100644
--- a/libexec/ld.so/sparc/archdep.h
+++ b/libexec/ld.so/sparc/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.11 2015/07/03 11:15:55 miod Exp $ */
+/* $OpenBSD: archdep.h,v 1.12 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _SPARC_ARCHDEP_H_
#define _SPARC_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_SPARC /* ELF e_machine ID value checked */
@@ -52,15 +54,7 @@ _dl_mmap(void *addr, unsigned int len, unsigned int prot,
}
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
-{
- /* SPARC does not use REL type relocations */
- _dl_exit(20);
-}
-
-static inline void
-RELOC_RELA(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
{
if (ELF_R_TYPE(r->r_info) == R_TYPE(NONE)) {
} else if (ELF_R_TYPE(r->r_info) == R_TYPE(RELATIVE)) {
diff --git a/libexec/ld.so/sparc64/archdep.h b/libexec/ld.so/sparc64/archdep.h
index 27b4036ac18..ce7908625d4 100644
--- a/libexec/ld.so/sparc64/archdep.h
+++ b/libexec/ld.so/sparc64/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.19 2014/11/03 17:50:56 guenther Exp $ */
+/* $OpenBSD: archdep.h,v 1.20 2015/12/06 23:36:12 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -29,6 +29,8 @@
#ifndef _SPARC64_ARCHDEP_H_
#define _SPARC64_ARCHDEP_H_
+#define RELOC_TAG DT_RELA
+
#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_SPARCV9 /* ELF e_machine ID value checked */
@@ -52,15 +54,7 @@ _dl_mmap(void *addr, unsigned int len, unsigned int prot,
}
static inline void
-RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
-{
- /* SPARC64 does not use REL type relocations */
- _dl_exit(20);
-}
-
-static inline void
-RELOC_RELA(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v,
- Elf_Addr *pltgot)
+RELOC_DYN(Elf_RelA *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
{
if (ELF_R_TYPE(r->r_info) == RELOC_RELATIVE) {
*p = v + r->r_addend;