Re-enable DT_MIPS_RLD_MAP_REL tag in ld.so
authorvisa <visa@openbsd.org>
Sun, 25 Dec 2022 09:39:37 +0000 (09:39 +0000)
committervisa <visa@openbsd.org>
Sun, 25 Dec 2022 09:39:37 +0000 (09:39 +0000)
The linker now produces correct values for DT_MIPS_RLD_MAP_REL tags.

The DT_MIPS_RLD_MAP_REL offset is relative to the entry of the original
dynamic tags array. Therefore look up the tag from exe_obj->load_dyn
instead of exe_obj->Dyn.info to get the correct base address.

OK kettenis@ deraadt@

libexec/ld.so/loader.c

index cbe5d83..a784083 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: loader.c,v 1.208 2022/12/18 19:33:11 deraadt Exp $ */
+/*     $OpenBSD: loader.c,v 1.209 2022/12/25 09:39:37 visa Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -625,9 +625,17 @@ _dl_boot(const char **argv, char **envp, const long dyn_loff, long *dl_data)
         */
        map_link = NULL;
 #ifdef __mips__
-       if (exe_obj->Dyn.info[DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM] != 0)
-               map_link = (struct r_debug **)(exe_obj->Dyn.info[
-                   DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM] + exe_loff);
+       for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) {
+               if (dynp->d_tag == DT_MIPS_RLD_MAP_REL) {
+                       map_link = (struct r_debug **)
+                           (dynp->d_un.d_ptr + (Elf_Addr)dynp);
+                       break;
+               } else if (dynp->d_tag == DT_MIPS_RLD_MAP) {
+                       map_link = (struct r_debug **)
+                           (dynp->d_un.d_ptr + exe_loff);
+                       break;
+               }
+       }
 #endif
        if (map_link == NULL) {
                for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) {