Split out the hppa and mips64 versions of boot.h similar to how I
authorguenther <guenther@openbsd.org>
Sun, 14 Nov 2021 00:45:38 +0000 (00:45 +0000)
committerguenther <guenther@openbsd.org>
Sun, 14 Nov 2021 00:45:38 +0000 (00:45 +0000)
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@

lib/csu/Makefile
lib/csu/boot.h
lib/csu/crt0.c
lib/csu/hppa/boot_md.h [new file with mode: 0644]
lib/csu/mips64/boot_md.h [new file with mode: 0644]

index 475f504..691e0f9 100644 (file)
@@ -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
index 6ec5256..d9831e4 100644 (file)
@@ -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
 
 #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;
index b27dfe5..9af919b 100644 (file)
@@ -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 (file)
index 0000000..1c9fc4b
--- /dev/null
@@ -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 (file)
index 0000000..a8dec2e
--- /dev/null
@@ -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 */