diff mbox

[MIPS] Support shared library debug with MIPS PIE (glibc)

Message ID 6D39441BF12EF246A7ABCE6654B0235321175F69@LEMAIL01.le.imgtec.org
State New
Headers show

Commit Message

Matthew Fortune June 23, 2015, 3:05 p.m. UTC
Following on from binutils submission of DT_MIPS_RLD_MAP2:

http://sourceware.org/ml/binutils/2015-06/msg00226.html


It is not currently possible to extract dynamic linker maps for MIPS position
independent executables. MIPS does not use the DT_DEBUG tag as MIPS has a
read-only dynamic section and the MIPS specific DT_MIPS_RLD_MAP tag stores an
absolute address of the debug map pointer which is unusable for a PIE.
Following previous discussions we are introducing a new dynamic tag as defined
below.

New dynamic tag:

DT_MIPS_RLD_MAP2 - 0x70000035

Definition:

This member is used by debugging.  It contains a relative offset from the tag's
runtime location of a 32-bit word in the .data section which is supplied by the
compilation environment. The word's contents are not specified and programs
using this value are not ABI - compliant.

Manually tested with pre and post DT_MIPS_RLD_MAP2 executables alongside
Updated GDB.

OK to commit?

Thanks,
Matthew

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

---
 elf/elf.h                 |  6 +++++-
 sysdeps/mips/dl-machine.h | 13 ++++++++++---
 2 files changed, 15 insertions(+), 4 deletions(-)

Comments

Joseph Myers June 23, 2015, 3:14 p.m. UTC | #1
On Tue, 23 Jun 2015, Matthew Fortune wrote:

> -/* 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_MAP2 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_MAP2)]) \
> +       { \
> +	 char *ptr = (char *)(l)->l_info[DT_MIPS (RLD_MAP2)]; \
> +	 ptr += (l)->l_info[DT_MIPS (RLD_MAP2)]->d_un.d_val; \
> +	 *(ElfW(Addr) *)ptr = (ElfW(Addr)) (r); \
> +       } \
> +     else if ((l)->l_info[DT_MIPS (RLD_MAP)]) \

What if there are both DT_MIPS_RLD_MAP2 and DT_MIPS_RLD_MAP?  Will that 
never happen?
Matthew Fortune June 23, 2015, 3:20 p.m. UTC | #2
Joseph Myers <joseph@codesourcery.com> writes:
> On Tue, 23 Jun 2015, Matthew Fortune wrote:
> 
> > -/* 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_MAP2 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_MAP2)]) \
> > +       { \
> > +	 char *ptr = (char *)(l)->l_info[DT_MIPS (RLD_MAP2)]; \
> > +	 ptr += (l)->l_info[DT_MIPS (RLD_MAP2)]->d_un.d_val; \
> > +	 *(ElfW(Addr) *)ptr = (ElfW(Addr)) (r); \
> > +       } \
> > +     else if ((l)->l_info[DT_MIPS (RLD_MAP)]) \
> 
> What if there are both DT_MIPS_RLD_MAP2 and DT_MIPS_RLD_MAP?  Will that
> never happen?

That will happen for executables much like MIPS has an unused DT_DEBUG
entry. I figured it would be better to add DT_MIPS_RLD_MAP2 to all
executables allowing this to be the only tag supported by dynamic linkers
that may not care about compatibility with pre-existing executables.

Are you thinking there should be a consistency check that the two tags
lead to the same address? I guess there would be no harm in that but
equally it may not be of much value. What do you think?

Matthew
Joseph Myers June 23, 2015, 3:27 p.m. UTC | #3
On Tue, 23 Jun 2015, Matthew Fortune wrote:

> > What if there are both DT_MIPS_RLD_MAP2 and DT_MIPS_RLD_MAP?  Will that
> > never happen?
> 
> That will happen for executables much like MIPS has an unused DT_DEBUG
> entry. I figured it would be better to add DT_MIPS_RLD_MAP2 to all
> executables allowing this to be the only tag supported by dynamic linkers
> that may not care about compatibility with pre-existing executables.
> 
> Are you thinking there should be a consistency check that the two tags
> lead to the same address? I guess there would be no harm in that but
> equally it may not be of much value. What do you think?

Are you saying that glibc never needs to handle both because if both are 
present they will point to the same address and so new glibc, looking only 
at DT_MIPS_RLD_MAP2, will work fine (for non-PIE) with old GDB?

If so, the patch is OK if the binutils patch is approved.
Matthew Fortune June 23, 2015, 3:30 p.m. UTC | #4
Joseph Myers <joseph@codesourcery.com> writes:
> On Tue, 23 Jun 2015, Matthew Fortune wrote:
> 
> > > What if there are both DT_MIPS_RLD_MAP2 and DT_MIPS_RLD_MAP?  Will
> > > that never happen?
> >
> > That will happen for executables much like MIPS has an unused DT_DEBUG
> > entry. I figured it would be better to add DT_MIPS_RLD_MAP2 to all
> > executables allowing this to be the only tag supported by dynamic
> > linkers that may not care about compatibility with pre-existing
> executables.
> >
> > Are you thinking there should be a consistency check that the two tags
> > lead to the same address? I guess there would be no harm in that but
> > equally it may not be of much value. What do you think?
> 
> Are you saying that glibc never needs to handle both because if both are
> present they will point to the same address and so new glibc, looking
> only at DT_MIPS_RLD_MAP2, will work fine (for non-PIE) with old GDB?

That's right.

Thanks,
Matthew

> If so, the patch is OK if the binutils patch is approved.
> 
> --
> Joseph S. Myers
> joseph@codesourcery.com
Matthew Fortune June 26, 2015, 1:53 p.m. UTC | #5
Matthew Fortune <matthew.fortune@imgtec.com> writes:
> Joseph Myers <joseph@codesourcery.com> writes:
> > On Tue, 23 Jun 2015, Matthew Fortune wrote:
> >
> > > > What if there are both DT_MIPS_RLD_MAP2 and DT_MIPS_RLD_MAP?  Will
> > > > that never happen?
> > >
> > > That will happen for executables much like MIPS has an unused
> > > DT_DEBUG entry. I figured it would be better to add DT_MIPS_RLD_MAP2
> > > to all executables allowing this to be the only tag supported by
> > > dynamic linkers that may not care about compatibility with
> > > pre-existing
> > executables.
> > >
> > > Are you thinking there should be a consistency check that the two
> > > tags lead to the same address? I guess there would be no harm in
> > > that but equally it may not be of much value. What do you think?
> >
> > Are you saying that glibc never needs to handle both because if both
> > are present they will point to the same address and so new glibc,
> > looking only at DT_MIPS_RLD_MAP2, will work fine (for non-PIE) with
> old GDB?
> 
> That's right.
> 
> Thanks,
> Matthew
> 
> > If so, the patch is OK if the binutils patch is approved.

This is now committed. One minor change to match binutils is that the
tag is renamed to DT_MIPS_RLD_MAP_REL.

Thanks,
Matthew
diff mbox

Patch

diff --git a/elf/elf.h b/elf/elf.h
index 12feb91..51446f5 100644
--- 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_MAP2     0x70000035
+#define DT_MIPS_NUM	     0x36
 
 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
 
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
index d63238a..3677b64 100644
--- a/sysdeps/mips/dl-machine.h
+++ b/sysdeps/mips/dl-machine.h
@@ -68,10 +68,17 @@ 
    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_MAP2 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_MAP2)]) \
+       { \
+	 char *ptr = (char *)(l)->l_info[DT_MIPS (RLD_MAP2)]; \
+	 ptr += (l)->l_info[DT_MIPS (RLD_MAP2)]->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)