summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2021-11-14 00:45:39 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2021-11-14 00:45:39 +0000
commitde9db51154026eded1f072c9a6dbde43341187f1 (patch)
tree4d538791cacb1f0e944d21fb2f1cf903e3c1da86
parent325ac7d54afee2383b4f67965306b77e3c073d5f (diff)
Split out the hppa and mips64 versions of boot.h similar to how I
split ld.so/boot.c in 2019: * delete extraneous #includes * delete jmprel handling on non-hppa * delete RELOC_GOT() and DT_PROC bits on non-mips64 ok visa@
-rw-r--r--lib/csu/Makefile8
-rw-r--r--lib/csu/boot.h71
-rw-r--r--lib/csu/crt0.c4
-rw-r--r--lib/csu/hppa/boot_md.h200
-rw-r--r--lib/csu/mips64/boot_md.h185
5 files changed, 399 insertions, 69 deletions
diff --git a/lib/csu/Makefile b/lib/csu/Makefile
index 475f504a4a5..691e0f9348d 100644
--- a/lib/csu/Makefile
+++ b/lib/csu/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.35 2020/06/27 18:35:07 kettenis Exp $
+# $OpenBSD: Makefile,v 1.36 2021/11/14 00:45:38 guenther Exp $
OBJS= crt0.o gcrt0.o
OBJS+= crtbegin.o crtend.o
@@ -25,6 +25,12 @@ PICFLAG=
PICFLAG= -fPIC
.endif
+.if exists(${.CURDIR}/${MACHINE_CPU}/boot_md.h)
+CFLAGS+= -DBOOT_H=\"boot_md.h\"
+.else
+CFLAGS+= -DBOOT_H=\"boot.h\"
+.endif
+
RCFLAGS=-DRCRT0
# amd64 can access the stack protector before relocation has occurred.
# Other archs aren't so lucky
diff --git a/lib/csu/boot.h b/lib/csu/boot.h
index 6ec5256bb06..d9831e4dacd 100644
--- a/lib/csu/boot.h
+++ b/lib/csu/boot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.h,v 1.30 2019/05/10 13:29:21 guenther Exp $ */
+/* $OpenBSD: boot.h,v 1.31 2021/11/14 00:45:38 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -36,18 +36,9 @@
#include <sys/types.h>
#include <sys/mman.h>
-#include <sys/exec.h>
-#include <sys/sysctl.h>
-#include <nlist.h>
-#include <link.h>
-#include <dlfcn.h>
+#include <sys/exec_elf.h>
-#include "syscall.h"
#include "archdep.h"
-#include "path.h"
-#include "resolve.h"
-#include "sod.h"
-#include "stdlib.h"
/*
* Use the internal, hidden name for any syscalls we need, to avoid
@@ -58,8 +49,6 @@ REDIRECT_SYSCALL(mprotect);
#ifdef RCRT0
-#define DT_PROC(n) ((n) - DT_LOPROC)
-
#if RELOC_TAG == DT_RELA
typedef Elf_RelA RELOC_TYPE;
#elif RELOC_TAG == DT_REL
@@ -72,13 +61,7 @@ typedef Elf_Rel RELOC_TYPE;
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
};
static void *relro_addr;
@@ -95,12 +78,11 @@ static size_t relro_size;
void _dl_boot_bind(const long, long *, Elf_Dyn *);
void
-_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
+_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynp)
{
struct boot_dyn dynld; /* Resolver data for the loader */
AuxInfo *auxstack;
long *stack;
- Elf_Dyn *dynp;
int n, argc;
char **argv, **envp;
long loff;
@@ -145,50 +127,20 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
* Scan the DYNAMIC section for the loader.
* Cache the data for easier access.
*/
- dynp = dynamicp;
-
_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)
+ 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.dt_proc[dynp->d_tag - DT_LOPROC] =
- dynp->d_un.d_val;
-#endif /* DT_PROCNUM */
dynp++;
}
- rp = dynld.dt_jmprel;
- for (i = 0; i < dynld.dt_pltrelsz; i += sizeof *rp) {
- 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) {
-#ifdef HAVE_JMPREL
- Elf_Addr *ra = (Elf_Addr *)(rp->r_offset + loff);
- RELOC_JMPREL(rp, sp, ra, loff, dynld.dt_pltgot);
-#else
- _dl_exit(6);
-#endif
- }
- rp++;
- }
-
rp = dynld.dt_reloc;
for (i = 0; i < dynld.dt_relocsz; i += sizeof *rp) {
Elf_Addr *ra;
@@ -202,24 +154,11 @@ _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
rp++;
}
- RELOC_GOT(&dynld, loff);
-
- /*
- * we have been fully relocated here, so most things no longer
- * need the loff adjustment
- */
-
- /*
- * No further changes to the PLT and/or GOT are needed so make
- * them read-only.
- */
-
/* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */
phdp = (Elf_Phdr *)dl_data[AUX_phdr];
for (i = 0; i < dl_data[AUX_phnum]; i++, phdp++) {
switch (phdp->p_type) {
-#if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \
- defined(__sparc64__)
+#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc64__)
case PT_LOAD:
if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W))
break;
diff --git a/lib/csu/crt0.c b/lib/csu/crt0.c
index b27dfe5b2d5..9af919be4c1 100644
--- a/lib/csu/crt0.c
+++ b/lib/csu/crt0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crt0.c,v 1.15 2020/10/14 22:11:18 deraadt Exp $ */
+/* $OpenBSD: crt0.c,v 1.16 2021/11/14 00:45:38 guenther Exp $ */
/*
* Copyright (c) 1995 Christopher G. Demetriou
@@ -37,7 +37,7 @@
#include "md_init.h"
#ifdef MD_RCRT0_START
-#include "boot.h"
+# include BOOT_H
#endif
#include "extern.h"
diff --git a/lib/csu/hppa/boot_md.h b/lib/csu/hppa/boot_md.h
new file mode 100644
index 00000000000..1c9fc4b91fd
--- /dev/null
+++ b/lib/csu/hppa/boot_md.h
@@ -0,0 +1,200 @@
+/* $OpenBSD: boot_md.h,v 1.1 2021/11/14 00:45:38 guenther Exp $ */
+
+/*
+ * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * IMPORTANT: any functions below are NOT protected by SSP. Please
+ * do not add anything except what is required to reach GOT with
+ * an adjustment.
+ */
+
+#define _DYN_LOADER
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/exec_elf.h>
+
+#include "archdep.h"
+
+/*
+ * Use the internal, hidden name for any syscalls we need, to avoid
+ * accidental override by application code
+ */
+#define REDIRECT_SYSCALL(x) typeof(x) x asm("_libc_"#x) __dso_hidden
+REDIRECT_SYSCALL(mprotect);
+
+#ifdef RCRT0
+
+#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;
+};
+
+static void *relro_addr;
+static size_t relro_size;
+#define RCRT0_RELRO() \
+ do { \
+ if (relro_addr != NULL && relro_size != 0) \
+ mprotect(relro_addr, relro_size, PROT_READ); \
+ } while (0)
+
+/*
+ * Local decls.
+ */
+void _dl_boot_bind(const long, long *, Elf_Dyn *);
+
+void
+_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynp)
+{
+ struct boot_dyn dynld; /* Resolver data for the loader */
+ AuxInfo *auxstack;
+ long *stack;
+ int n, argc;
+ char **argv, **envp;
+ long loff;
+ RELOC_TYPE *rp;
+ Elf_Phdr *phdp;
+ Elf_Addr i;
+
+ /*
+ * Scan argument and environment vectors. Find dynamic
+ * data vector put after them.
+ */
+ stack = (long *)sp;
+ argc = *stack++;
+ argv = (char **)stack;
+ envp = &argv[argc + 1];
+ stack = (long *)envp;
+ while (*stack++ != 0L)
+ ;
+
+ /*
+ * Zero out dl_data.
+ */
+ for (n = 0; n <= AUX_entry; n++)
+ dl_data[n] = 0;
+
+ /*
+ * Dig out auxiliary data set up by exec call. Move all known
+ * tags to an indexed local table for easy access.
+ */
+ for (auxstack = (AuxInfo *)stack; auxstack->au_id != AUX_null;
+ auxstack++) {
+ if (auxstack->au_id > AUX_entry)
+ continue;
+ dl_data[auxstack->au_id] = auxstack->au_v;
+ }
+ loff = dl_data[AUX_base]; /* XXX assumes ld.so is linked at 0x0 */
+
+ /*
+ * We need to do 'selfreloc' in case the code weren't
+ * loaded at the address it was linked to.
+ *
+ * Scan the DYNAMIC section for the loader.
+ * Cache the data for easier access.
+ */
+ _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;
+ dynp++;
+ }
+
+ rp = dynld.dt_jmprel;
+ for (i = 0; i < dynld.dt_pltrelsz; i += sizeof *rp) {
+ 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) {
+ Elf_Addr *ra = (Elf_Addr *)(rp->r_offset + loff);
+ RELOC_JMPREL(rp, sp, ra, loff, dynld.dt_pltgot);
+ }
+ rp++;
+ }
+
+ 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_DYN(rp, sp, ra, loff);
+ }
+ rp++;
+ }
+
+ /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */
+ phdp = (Elf_Phdr *)dl_data[AUX_phdr];
+ for (i = 0; i < dl_data[AUX_phnum]; i++, phdp++) {
+ switch (phdp->p_type) {
+ case PT_LOAD:
+ if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W))
+ break;
+ mprotect((void *)(phdp->p_vaddr + loff), phdp->p_memsz,
+ PROT_READ);
+ break;
+ case PT_GNU_RELRO:
+ relro_addr = (void *)(phdp->p_vaddr + loff);
+ relro_size = phdp->p_memsz;
+ /*
+ * GNU_RELRO (a) covers the GOT, and (b) comes after
+ * all LOAD sections, so if we found it then we're done
+ */
+ break;
+ }
+ }
+}
+
+#endif /* RCRT0 */
diff --git a/lib/csu/mips64/boot_md.h b/lib/csu/mips64/boot_md.h
new file mode 100644
index 00000000000..a8dec2e6dd7
--- /dev/null
+++ b/lib/csu/mips64/boot_md.h
@@ -0,0 +1,185 @@
+/* $OpenBSD: boot_md.h,v 1.1 2021/11/14 00:45:38 guenther Exp $ */
+
+/*
+ * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * IMPORTANT: any functions below are NOT protected by SSP. Please
+ * do not add anything except what is required to reach GOT with
+ * an adjustment.
+ */
+
+#define _DYN_LOADER
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/exec_elf.h>
+
+#include "archdep.h"
+
+/*
+ * Use the internal, hidden name for any syscalls we need, to avoid
+ * accidental override by application code
+ */
+#define REDIRECT_SYSCALL(x) typeof(x) x asm("_libc_"#x) __dso_hidden
+REDIRECT_SYSCALL(mprotect);
+
+#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;
+ const Elf_Sym *dt_symtab;
+ u_long dt_proc[DT_PROCNUM];
+};
+
+static void *relro_addr;
+static size_t relro_size;
+#define RCRT0_RELRO() \
+ do { \
+ if (relro_addr != NULL && relro_size != 0) \
+ mprotect(relro_addr, relro_size, PROT_READ); \
+ } while (0)
+
+/*
+ * Local decls.
+ */
+void _dl_boot_bind(const long, long *, Elf_Dyn *);
+
+void
+_dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynp)
+{
+ struct boot_dyn dynld; /* Resolver data for the loader */
+ AuxInfo *auxstack;
+ long *stack;
+ int n, argc;
+ char **argv, **envp;
+ long loff;
+ RELOC_TYPE *rp;
+ Elf_Phdr *phdp;
+ Elf_Addr i;
+
+ /*
+ * Scan argument and environment vectors. Find dynamic
+ * data vector put after them.
+ */
+ stack = (long *)sp;
+ argc = *stack++;
+ argv = (char **)stack;
+ envp = &argv[argc + 1];
+ stack = (long *)envp;
+ while (*stack++ != 0L)
+ ;
+
+ /*
+ * Zero out dl_data.
+ */
+ for (n = 0; n <= AUX_entry; n++)
+ dl_data[n] = 0;
+
+ /*
+ * Dig out auxiliary data set up by exec call. Move all known
+ * tags to an indexed local table for easy access.
+ */
+ for (auxstack = (AuxInfo *)stack; auxstack->au_id != AUX_null;
+ auxstack++) {
+ if (auxstack->au_id > AUX_entry)
+ continue;
+ dl_data[auxstack->au_id] = auxstack->au_v;
+ }
+ loff = dl_data[AUX_base]; /* XXX assumes ld.so is linked at 0x0 */
+
+ /*
+ * We need to do 'selfreloc' in case the code weren't
+ * loaded at the address it was linked to.
+ *
+ * Scan the DYNAMIC section for the loader.
+ * Cache the data for easier access.
+ */
+ _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);
+
+ /* Now for the tags that are just sizes or counts */
+ else if (dynp->d_tag == RELOC_TAG+1) /* DT_{RELA,REL}SZ */
+ dynld.dt_relocsz = dynp->d_un.d_val;
+ else if (dynp->d_tag >= DT_LOPROC &&
+ dynp->d_tag < DT_LOPROC + DT_PROCNUM)
+ dynld.dt_proc[dynp->d_tag - DT_LOPROC] =
+ dynp->d_un.d_val;
+ dynp++;
+ }
+
+ 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_DYN(rp, sp, ra, loff);
+ }
+ rp++;
+ }
+
+ RELOC_GOT(&dynld, loff);
+
+ /* apply GNU_RELRO */
+ phdp = (Elf_Phdr *)dl_data[AUX_phdr];
+ for (i = 0; i < dl_data[AUX_phnum]; i++, phdp++) {
+ switch (phdp->p_type) {
+ case PT_GNU_RELRO:
+ relro_addr = (void *)(phdp->p_vaddr + loff);
+ relro_size = phdp->p_memsz;
+ /*
+ * GNU_RELRO (a) covers the GOT, and (b) comes after
+ * all LOAD sections, so if we found it then we're done
+ */
+ break;
+ }
+ }
+}
+
+#endif /* RCRT0 */