Fix DT_MIPS_RLD_MAP_REL
authorvisa <visa@openbsd.org>
Thu, 8 Dec 2022 13:41:06 +0000 (13:41 +0000)
committervisa <visa@openbsd.org>
Thu, 8 Dec 2022 13:41:06 +0000 (13:41 +0000)
Use proper tag-relative values for DT_MIPS_RLD_MAP_REL tags.

This causes an ABI break on mips64. Your system must have latest ld.so
before applying this commit.

OK deraadt@ kettenis@

gnu/usr.bin/binutils-2.17/bfd/elfxx-mips.c
gnu/usr.bin/binutils/gdb/solib-svr4.c

index c505915..958e36c 100644 (file)
@@ -8714,10 +8714,19 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_MIPS_RLD_MAP:
-           case DT_MIPS_RLD_MAP_REL:
              dyn.d_un.d_ptr = mips_elf_hash_table (info)->rld_value;
              break;
 
+           case DT_MIPS_RLD_MAP_REL:
+             {
+               bfd_vma dt_addr;
+
+               dt_addr = (sdyn->output_section->vma + sdyn->output_offset
+                          + (b - sdyn->contents));
+               dyn.d_un.d_val = mips_elf_hash_table (info)->rld_value - dt_addr;
+             }
+             break;
+
            case DT_MIPS_OPTIONS:
              s = (bfd_get_section_by_name
                   (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (output_bfd)));
index 83a761c..63b0e17 100644 (file)
@@ -378,6 +378,8 @@ elf_locate_base (void)
     }
   else /* 64-bit elf */
     {
+      char *bufstart = buf;
+
       for (bufend = buf + dyninfo_sect_size;
           buf < bufend;
           buf += sizeof (Elf64_External_Dyn))
@@ -407,7 +409,7 @@ elf_locate_base (void)
              dyn_ptr = bfd_h_get_64 (exec_bfd, 
                                      (bfd_byte *) x_dynp->d_un.d_ptr);
              if (dyn_tag == DT_MIPS_RLD_MAP_REL)
-               dyn_ptr += (entry_addr - bfd_get_start_address(exec_bfd));
+               dyn_ptr += (relocated_dyninfo_addr + (buf - bufstart));
              if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
                return 0;
              return extract_unsigned_integer (pbuf, pbuf_size);