-/* $OpenBSD: loader.c,v 1.192 2021/05/25 17:01:36 kn Exp $ */
+/* $OpenBSD: loader.c,v 1.193 2021/11/12 22:28:13 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
void _dl_clean_boot(void);
static inline void unprotect_if_textrel(elf_object_t *_object);
static inline void reprotect_if_textrel(elf_object_t *_object);
+static void _dl_rreloc(elf_object_t *_object);
int _dl_pagesz __relro = 4096;
int _dl_bindnow __relro = 0;
* Do relocation information first, then GOT.
*/
unprotect_if_textrel(object);
+ _dl_rreloc(object);
fails =_dl_md_reloc(object, DT_REL, DT_RELSZ);
fails += _dl_md_reloc(object, DT_RELA, DT_RELASZ);
reprotect_if_textrel(object);
}
}
}
+
+static void
+_dl_rreloc(elf_object_t *object)
+{
+ const Elf_Relr *reloc, *rend;
+ Elf_Addr loff = object->obj_base;
+
+ reloc = object->dyn.relr;
+ rend = (const Elf_Relr *)((char *)reloc + object->dyn.relrsz);
+
+ while (reloc < rend) {
+ Elf_Addr *where;
+
+ where = (Elf_Addr *)(*reloc + loff);
+ *where++ += loff;
+
+ for (reloc++; reloc < rend && (*reloc & 1); reloc++) {
+ Elf_Addr bits = *reloc >> 1;
+
+ Elf_Addr *here = where;
+ while (bits != 0) {
+ if (bits & 1) {
+ *here += loff;
+ }
+ bits >>= 1;
+ here++;
+ }
+ where += (8 * sizeof *reloc) - 1;
+ }
+ }
+}
+
-/* $OpenBSD: resolve.c,v 1.95 2021/06/02 07:29:03 semarie Exp $ */
+/* $OpenBSD: resolve.c,v 1.96 2021/11/12 22:28:13 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
object->Dyn.info[DT_FINI_ARRAY] += obase;
if (object->Dyn.info[DT_PREINIT_ARRAY])
object->Dyn.info[DT_PREINIT_ARRAY] += obase;
+ if (object->Dyn.info[DT_RELR])
+ object->Dyn.info[DT_RELR] += obase;
if (gnu_hash) {
Elf_Word *hashtab = (Elf_Word *)(gnu_hash + obase);
-/* $OpenBSD: resolve.h,v 1.98 2021/06/02 07:29:03 semarie Exp $ */
+/* $OpenBSD: resolve.h,v 1.99 2021/11/12 22:28:13 guenther Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
#endif
/* Number of low tags that are used saved internally (0 .. DT_NUM-1) */
-#define DT_NUM (DT_PREINIT_ARRAYSZ + 1)
+#define DT_NUM (DT_RELR + 1)
struct load_list {
struct load_list *next;
Elf_Addr encoding;
initarrayfunc **preinit_array;
Elf_Addr preinit_arraysz;
+ Elf_Addr unassigned;
+ Elf_Addr relrsz;
+ Elf_Relr *relr;
} u;
} Dyn;
#define dyn Dyn.u