Add support for DT_MIPS_RLD_MAP_REL.
authorMatthew Fortune <matthew.fortune@imgtec.com>
Thu, 11 Jun 2015 09:43:48 +0000 (10:43 +0100)
committerMatthew Fortune <matthew.fortune@imgtec.com>
Fri, 26 Jun 2015 11:03:45 +0000 (12:03 +0100)
This tag allows debugging of MIPS position independent executables
and provides access to shared library information.

* elf/elf.h (DT_MIPS_RLD_MAP_REL): New macro.
(DT_MIPS_NUM): Update.
* sysdeps/mips/dl-machine.h (ELF_MACHINE_DEBUG_SETUP): Handle
DT_MIPS_RLD_MAP_REL.

ChangeLog
elf/elf.h
sysdeps/mips/dl-machine.h

index b61ea3c..b502c78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2015-06-26  Matthew Fortune  <matthew.fortune@imgtec.com>
+
+       * elf/elf.h (DT_MIPS_RLD_MAP_REL): New macro.
+       (DT_MIPS_NUM): Update.
+       * sysdeps/mips/dl-machine.h (ELF_MACHINE_DEBUG_SETUP): Handle
+       DT_MIPS_RLD_MAP_REL.
+
 2015-06-25  Joseph Myers  <joseph@codesourcery.com>
 
        [BZ #16559]
index 12feb91..fbadda4 100644 (file)
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1727,7 +1727,11 @@ typedef struct
    PLT is writable.  For a non-writable PLT, this is omitted or has a zero
    value.  */
 #define DT_MIPS_RWPLT        0x70000034
-#define DT_MIPS_NUM         0x35
+/* An alternative description of the classic MIPS RLD_MAP that is usable
+   in a PIE as it stores a relative offset from the address of the tag
+   rather than an absolute address.  */
+#define DT_MIPS_RLD_MAP_REL  0x70000035
+#define DT_MIPS_NUM         0x36
 
 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
 
index d63238a..8738564 100644 (file)
    in l_info array.  */
 #define DT_MIPS(x) (DT_MIPS_##x - DT_LOPROC + DT_NUM)
 
-/* If there is a DT_MIPS_RLD_MAP entry in the dynamic section, fill it in
-   with the run-time address of the r_debug structure  */
+/* If there is a DT_MIPS_RLD_MAP_REL or DT_MIPS_RLD_MAP entry in the dynamic
+   section, fill in the debug map pointer with the run-time address of the
+   r_debug structure.  */
 #define ELF_MACHINE_DEBUG_SETUP(l,r) \
-do { if ((l)->l_info[DT_MIPS (RLD_MAP)]) \
+do { if ((l)->l_info[DT_MIPS (RLD_MAP_REL)]) \
+       { \
+        char *ptr = (char *)(l)->l_info[DT_MIPS (RLD_MAP_REL)]; \
+        ptr += (l)->l_info[DT_MIPS (RLD_MAP_REL)]->d_un.d_val; \
+        *(ElfW(Addr) *)ptr = (ElfW(Addr)) (r); \
+       } \
+     else if ((l)->l_info[DT_MIPS (RLD_MAP)]) \
        *(ElfW(Addr) *)((l)->l_info[DT_MIPS (RLD_MAP)]->d_un.d_ptr) = \
        (ElfW(Addr)) (r); \
    } while (0)