public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
@ 2015-06-23 15:23 Matthew Fortune
  2015-06-23 15:31 ` Joseph Myers
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Fortune @ 2015-06-23 15:23 UTC (permalink / raw)
  To: gdb-patches

Following on from binutils and glibc submission of DT_MIPS_RLD_MAP2:

http://sourceware.org/ml/binutils/2015-06/msg00226.html
http://sourceware.org/ml/libc-alpha/2015-06/msg00766.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.

Please note that the new DT_MIPS_RLD_MAP2 support will not be enabled unless
the host's elf.h header has the new tag defined in it. For cross compiled GDB
this may mean hacking the solib-svr4.c file to define the macro until such
time as distributions update glibc.

I'm open to suggestions if anyone can see a neater way to achieve this support
in GDB. A number of support functions had to be extended to get the data
required.

Manually tested with pre and post DT_MIPS_RLD_MAP2 executables and verified
that the info sharedlibrary command now works for MIPS PIE.

OK to commit?

Thanks,
Matthew

gdb/gdbserver/

	* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP2.

gdb/

	* solib-svr4.c (read_program_header): Add base_addr argument to
	report the runtime address of the segment.
	(find_program_interpreter): Update read_program_header call to pass
	a NULL pointer for the new argument.
	(scan_dyntag): Add ptr_addr argument to report the runtime address
	of the tag payload.
	(scan_dyntag_auxv): Likewise and use thew new base_addr argument of
	read_program_header to get the base address of the dynamic segment.
	(elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and
	read_program_header.
	(elf_locate_base) [DT_MIPS_RLD_MAP2]: Scan for and handle
	DT_MIPS_RLD_MAP2.

---
 gdb/gdbserver/linux-low.c | 30 +++++++++++++++++++---
 gdb/solib-svr4.c          | 65 +++++++++++++++++++++++++++++++++++------------
 2 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3774d17..6ec6bd8 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -6102,14 +6102,15 @@ get_r_debug (const int pid, const int is_elf64)
       if (is_elf64)
 	{
 	  Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
-#ifdef DT_MIPS_RLD_MAP
+#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP2
 	  union
 	    {
 	      Elf64_Xword map;
 	      unsigned char buf[sizeof (Elf64_Xword)];
 	    }
 	  rld_map;
-
+#endif
+#ifdef DT_MIPS_RLD_MAP
 	  if (dyn->d_tag == DT_MIPS_RLD_MAP)
 	    {
 	      if (linux_read_memory (dyn->d_un.d_val,
@@ -6119,6 +6120,16 @@ get_r_debug (const int pid, const int is_elf64)
 		break;
 	    }
 #endif	/* DT_MIPS_RLD_MAP */
+#ifdef DT_MIPS_RLD_MAP2
+	  if (dyn->d_tag == DT_MIPS_RLD_MAP2)
+	    {
+	      if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr,
+				     rld_map.buf, sizeof (rld_map.buf)) == 0)
+		return rld_map.map;
+	      else
+		break;
+	    }
+#endif	/* DT_MIPS_RLD_MAP2 */
 
 	  if (dyn->d_tag == DT_DEBUG && map == -1)
 	    map = dyn->d_un.d_val;
@@ -6129,14 +6140,15 @@ get_r_debug (const int pid, const int is_elf64)
       else
 	{
 	  Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
-#ifdef DT_MIPS_RLD_MAP
+#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP2
 	  union
 	    {
 	      Elf32_Word map;
 	      unsigned char buf[sizeof (Elf32_Word)];
 	    }
 	  rld_map;
-
+#endif
+#ifdef DT_MIPS_RLD_MAP
 	  if (dyn->d_tag == DT_MIPS_RLD_MAP)
 	    {
 	      if (linux_read_memory (dyn->d_un.d_val,
@@ -6146,6 +6158,16 @@ get_r_debug (const int pid, const int is_elf64)
 		break;
 	    }
 #endif	/* DT_MIPS_RLD_MAP */
+#ifdef DT_MIPS_RLD_MAP2
+	  if (dyn->d_tag == DT_MIPS_RLD_MAP2)
+	    {
+	      if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr,
+				     rld_map.buf, sizeof (rld_map.buf)) == 0)
+		return rld_map.map;
+	      else
+		break;
+	    }
+#endif	/* DT_MIPS_RLD_MAP2 */
 
 	  if (dyn->d_tag == DT_DEBUG && map == -1)
 	    map = dyn->d_un.d_val;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 909dfb7..dd2cdf0 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -443,10 +443,12 @@ static int match_main (const char *);
    Return a pointer to allocated memory holding the program header contents,
    or NULL on failure.  If sucessful, and unless P_SECT_SIZE is NULL, the
    size of those contents is returned to P_SECT_SIZE.  Likewise, the target
-   architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE.  */
+   architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE and
+   the base address of the section is returned in BASE_ADDR.  */
 
 static gdb_byte *
-read_program_header (int type, int *p_sect_size, int *p_arch_size)
+read_program_header (int type, int *p_sect_size, int *p_arch_size,
+		     CORE_ADDR *base_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
@@ -576,6 +578,8 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
     *p_arch_size = arch_size;
   if (p_sect_size)
     *p_sect_size = sect_size;
+  if (base_addr)
+    *base_addr = sect_addr;
 
   return buf;
 }
@@ -605,7 +609,7 @@ find_program_interpreter (void)
 
   /* If we didn't find it, use the target auxillary vector.  */
   if (!buf)
-    buf = read_program_header (PT_INTERP, NULL, NULL);
+    buf = read_program_header (PT_INTERP, NULL, NULL, NULL);
 
   return (char *) buf;
 }
@@ -615,7 +619,8 @@ find_program_interpreter (void)
    found, 1 is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
+scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
+	     CORE_ADDR *ptr_addr)
 {
   int arch_size, step, sect_size;
   long current_dyntag;
@@ -695,13 +700,15 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
 	   {
 	     struct type *ptr_type;
 	     gdb_byte ptr_buf[8];
-	     CORE_ADDR ptr_addr;
+	     CORE_ADDR ptr_addr_1;
 
 	     ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
-	     ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
-	     if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
+	     ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
+	     if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
 	       dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
 	     *ptr = dyn_ptr;
+	     if (ptr_addr)
+	       *ptr_addr = dyn_addr + (buf - bufstart);
 	   }
 	 return 1;
        }
@@ -715,16 +722,19 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
    is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
+scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr,
+		  CORE_ADDR *ptr_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   int sect_size, arch_size, step;
   long current_dyntag;
   CORE_ADDR dyn_ptr;
+  CORE_ADDR base_addr;
   gdb_byte *bufend, *bufstart, *buf;
 
   /* Read in .dynamic section.  */
-  buf = bufstart = read_program_header (PT_DYNAMIC, &sect_size, &arch_size);
+  buf = bufstart = read_program_header (PT_DYNAMIC, &sect_size, &arch_size,
+					&base_addr);
   if (!buf)
     return 0;
 
@@ -761,6 +771,9 @@ scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
 	if (ptr)
 	  *ptr = dyn_ptr;
 
+	if (ptr_addr)
+	  *ptr_addr = base_addr + buf - bufstart;
+
 	xfree (bufstart);
 	return 1;
       }
@@ -786,13 +799,13 @@ static CORE_ADDR
 elf_locate_base (void)
 {
   struct bound_minimal_symbol msymbol;
-  CORE_ADDR dyn_ptr;
+  CORE_ADDR dyn_ptr, dyn_ptr_addr;
 
   /* Look for DT_MIPS_RLD_MAP first.  MIPS executables use this
      instead of DT_DEBUG, although they sometimes contain an unused
      DT_DEBUG.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
-      || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
       gdb_byte *pbuf;
@@ -806,9 +819,29 @@ elf_locate_base (void)
       return extract_typed_address (pbuf, ptr_type);
     }
 
+#ifdef DT_MIPS_RLD_MAP2
+  /* Then check DT_MIPS_RLD_MAP2.  MIPS executables now use this form
+     because of needing to support PIE.  DT_MIPS_RLD_MAP will also exist
+     in non-PIE.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP2, exec_bfd, &dyn_ptr, &dyn_ptr_addr)
+      || scan_dyntag_auxv (DT_MIPS_RLD_MAP2, &dyn_ptr, &dyn_ptr_addr))
+    {
+      struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (ptr_type);
+
+      pbuf = alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP2 contains an offset from the address of the DT slot to
+	 the address of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr + dyn_ptr_addr, pbuf, pbuf_size))
+	return 0;
+      return extract_typed_address (pbuf, ptr_type);
+    }
+#endif /* DT_MIPS_RLD_MAP2 */
+
   /* Find DT_DEBUG.  */
-  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)
-      || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr))
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
     return dyn_ptr;
 
   /* This may be a static executable.  Look for the symbol
@@ -2607,7 +2640,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
       gdb_byte *buf, *buf2;
       int arch_size;
 
-      buf = read_program_header (-1, &phdrs_size, &arch_size);
+      buf = read_program_header (-1, &phdrs_size, &arch_size, NULL);
       buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
       if (buf != NULL && buf2 != NULL)
 	{
@@ -3228,7 +3261,7 @@ elf_lookup_lib_symbol (struct objfile *objfile,
       abfd = objfile->obfd;
     }
 
-  if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
+  if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) != 1)
     return NULL;
 
   return lookup_global_symbol_from_objfile (objfile, name, domain);
-- 
2.2.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-06-23 15:23 [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb) Matthew Fortune
@ 2015-06-23 15:31 ` Joseph Myers
  2015-06-23 15:52   ` Matthew Fortune
                     ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Joseph Myers @ 2015-06-23 15:31 UTC (permalink / raw)
  To: Matthew Fortune; +Cc: gdb-patches

On Tue, 23 Jun 2015, Matthew Fortune wrote:

> Please note that the new DT_MIPS_RLD_MAP2 support will not be enabled unless
> the host's elf.h header has the new tag defined in it. For cross compiled GDB
> this may mean hacking the solib-svr4.c file to define the macro until such
> time as distributions update glibc.

That doesn't make any sense to me.  Hosts (e.g. MinGW) may not have elf.h 
at all.  GDB should get these definitions from the #include "elf/mips.h" 
already in solib-svr4.c (i.e. from toplevel's include/elf/mips.h).  And so 
there should be no #ifdefs there.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-06-23 15:31 ` Joseph Myers
@ 2015-06-23 15:52   ` Matthew Fortune
  2015-06-26 12:45   ` Matthew Fortune
  2015-07-13 10:21   ` Matthew Fortune
  2 siblings, 0 replies; 8+ messages in thread
From: Matthew Fortune @ 2015-06-23 15:52 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gdb-patches

Joseph Myers <joseph@codesourcery.com> writes:
> On Tue, 23 Jun 2015, Matthew Fortune wrote:
> 
> > Please note that the new DT_MIPS_RLD_MAP2 support will not be enabled unless
> > the host's elf.h header has the new tag defined in it. For cross compiled GDB
> > this may mean hacking the solib-svr4.c file to define the macro until such
> > time as distributions update glibc.
> 
> That doesn't make any sense to me.  Hosts (e.g. MinGW) may not have elf.h
> at all.  GDB should get these definitions from the #include "elf/mips.h"
> already in solib-svr4.c (i.e. from toplevel's include/elf/mips.h).  And so
> there should be no #ifdefs there.

Thanks. I got this twisted owing to the gdbserver using the host elf.h and me
keeping the binutils and GDB patches separate when I should have had the
elf/mips.h changes shared between the two.

I'll send an updated patch with the #ifdefs removed and ensure that binutils
commit precedes the GDB commit when approved.

Matthew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-06-23 15:31 ` Joseph Myers
  2015-06-23 15:52   ` Matthew Fortune
@ 2015-06-26 12:45   ` Matthew Fortune
  2015-08-12 10:30     ` Pedro Alves
  2015-07-13 10:21   ` Matthew Fortune
  2 siblings, 1 reply; 8+ messages in thread
From: Matthew Fortune @ 2015-06-26 12:45 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joseph Myers

Joseph Myers <joseph@codesourcery.com> writes:
> On Tue, 23 Jun 2015, Matthew Fortune wrote:
> 
> > Please note that the new DT_MIPS_RLD_MAP2 support will not be enabled
> > unless the host's elf.h header has the new tag defined in it. For
> > cross compiled GDB this may mean hacking the solib-svr4.c file to
> > define the macro until such time as distributions update glibc.
> 
> That doesn't make any sense to me.  Hosts (e.g. MinGW) may not have
> elf.h at all.  GDB should get these definitions from the #include
> "elf/mips.h"
> already in solib-svr4.c (i.e. from toplevel's include/elf/mips.h).  And
> so there should be no #ifdefs there.

Updated version below to match the name of the new tag as committed to
binutils and removed the #ifdefs from solib-svr4.c.

binutils commit: a5499fa Add support for DT_MIPS_RLD_MAP_REL.

OK to commit?

Thanks,
Matthew


This tag allows debugging of MIPS position independent executables
and provides access to shared library information.

gdb/gdbserver/

	* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL.

gdb/

	* solib-svr4.c (read_program_header): Add base_addr argument to
	report the runtime address of the segment.
	(find_program_interpreter): Update read_program_header call to pass
	a NULL pointer for the new argument.
	(scan_dyntag): Add ptr_addr argument to report the runtime address
	of the tag payload.
	(scan_dyntag_auxv): Likewise and use thew new base_addr argument of
	read_program_header to get the base address of the dynamic segment.
	(elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and
	read_program_header.
	(elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL.
---
 gdb/ChangeLog             | 14 +++++++++++
 gdb/gdbserver/ChangeLog   |  4 +++
 gdb/gdbserver/linux-low.c | 30 +++++++++++++++++++---
 gdb/solib-svr4.c          | 63 +++++++++++++++++++++++++++++++++++------------
 4 files changed, 91 insertions(+), 20 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 659f9b7..766c02f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2015-06-26  Matthew Fortune  <matthew.fortune@imgtec.com>
+
+	* solib-svr4.c (read_program_header): Add base_addr argument to
+	report the runtime address of the segment.
+	(find_program_interpreter): Update read_program_header call to pass
+	a NULL pointer for the new argument.
+	(scan_dyntag): Add ptr_addr argument to report the runtime address
+	of the tag payload.
+	(scan_dyntag_auxv): Likewise and use thew new base_addr argument of
+	read_program_header to get the base address of the dynamic segment.
+	(elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and
+	read_program_header.
+	(elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL.
+
 2015-06-25  Gary Benson  <gbenson@redhat.com>
 
 	* solib.c (solib_find_1): Set local variable sysroot to NULL if
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 2528f0f..6e37863 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,7 @@
+2015-06-26  Matthew Fortune  <matthew.fortune@imgtec.com>
+
+	* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL.
+
 2015-06-24  Gary Benson  <gbenson@redhat.com>
 
 	* linux-i386-ipa.c (stdint.h): Do not include.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3774d17..ed18e24 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -6102,14 +6102,15 @@ get_r_debug (const int pid, const int is_elf64)
       if (is_elf64)
 	{
 	  Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
-#ifdef DT_MIPS_RLD_MAP
+#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL
 	  union
 	    {
 	      Elf64_Xword map;
 	      unsigned char buf[sizeof (Elf64_Xword)];
 	    }
 	  rld_map;
-
+#endif
+#ifdef DT_MIPS_RLD_MAP
 	  if (dyn->d_tag == DT_MIPS_RLD_MAP)
 	    {
 	      if (linux_read_memory (dyn->d_un.d_val,
@@ -6119,6 +6120,16 @@ get_r_debug (const int pid, const int is_elf64)
 		break;
 	    }
 #endif	/* DT_MIPS_RLD_MAP */
+#ifdef DT_MIPS_RLD_MAP_REL
+	  if (dyn->d_tag == DT_MIPS_RLD_MAP_REL)
+	    {
+	      if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr,
+				     rld_map.buf, sizeof (rld_map.buf)) == 0)
+		return rld_map.map;
+	      else
+		break;
+	    }
+#endif	/* DT_MIPS_RLD_MAP_REL */
 
 	  if (dyn->d_tag == DT_DEBUG && map == -1)
 	    map = dyn->d_un.d_val;
@@ -6129,14 +6140,15 @@ get_r_debug (const int pid, const int is_elf64)
       else
 	{
 	  Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
-#ifdef DT_MIPS_RLD_MAP
+#if defined DT_MIPS_RLD_MAP || defined DT_MIPS_RLD_MAP_REL
 	  union
 	    {
 	      Elf32_Word map;
 	      unsigned char buf[sizeof (Elf32_Word)];
 	    }
 	  rld_map;
-
+#endif
+#ifdef DT_MIPS_RLD_MAP
 	  if (dyn->d_tag == DT_MIPS_RLD_MAP)
 	    {
 	      if (linux_read_memory (dyn->d_un.d_val,
@@ -6146,6 +6158,16 @@ get_r_debug (const int pid, const int is_elf64)
 		break;
 	    }
 #endif	/* DT_MIPS_RLD_MAP */
+#ifdef DT_MIPS_RLD_MAP_REL
+	  if (dyn->d_tag == DT_MIPS_RLD_MAP_REL)
+	    {
+	      if (linux_read_memory (dyn->d_un.d_val + dynamic_memaddr,
+				     rld_map.buf, sizeof (rld_map.buf)) == 0)
+		return rld_map.map;
+	      else
+		break;
+	    }
+#endif	/* DT_MIPS_RLD_MAP_REL */
 
 	  if (dyn->d_tag == DT_DEBUG && map == -1)
 	    map = dyn->d_un.d_val;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 909dfb7..a71fb82 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -443,10 +443,12 @@ static int match_main (const char *);
    Return a pointer to allocated memory holding the program header contents,
    or NULL on failure.  If sucessful, and unless P_SECT_SIZE is NULL, the
    size of those contents is returned to P_SECT_SIZE.  Likewise, the target
-   architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE.  */
+   architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE and
+   the base address of the section is returned in BASE_ADDR.  */
 
 static gdb_byte *
-read_program_header (int type, int *p_sect_size, int *p_arch_size)
+read_program_header (int type, int *p_sect_size, int *p_arch_size,
+		     CORE_ADDR *base_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
@@ -576,6 +578,8 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size)
     *p_arch_size = arch_size;
   if (p_sect_size)
     *p_sect_size = sect_size;
+  if (base_addr)
+    *base_addr = sect_addr;
 
   return buf;
 }
@@ -605,7 +609,7 @@ find_program_interpreter (void)
 
   /* If we didn't find it, use the target auxillary vector.  */
   if (!buf)
-    buf = read_program_header (PT_INTERP, NULL, NULL);
+    buf = read_program_header (PT_INTERP, NULL, NULL, NULL);
 
   return (char *) buf;
 }
@@ -615,7 +619,8 @@ find_program_interpreter (void)
    found, 1 is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
+scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
+	     CORE_ADDR *ptr_addr)
 {
   int arch_size, step, sect_size;
   long current_dyntag;
@@ -695,13 +700,15 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
 	   {
 	     struct type *ptr_type;
 	     gdb_byte ptr_buf[8];
-	     CORE_ADDR ptr_addr;
+	     CORE_ADDR ptr_addr_1;
 
 	     ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
-	     ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
-	     if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
+	     ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
+	     if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
 	       dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
 	     *ptr = dyn_ptr;
+	     if (ptr_addr)
+	       *ptr_addr = dyn_addr + (buf - bufstart);
 	   }
 	 return 1;
        }
@@ -715,16 +722,19 @@ scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
    is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
+scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr,
+		  CORE_ADDR *ptr_addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   int sect_size, arch_size, step;
   long current_dyntag;
   CORE_ADDR dyn_ptr;
+  CORE_ADDR base_addr;
   gdb_byte *bufend, *bufstart, *buf;
 
   /* Read in .dynamic section.  */
-  buf = bufstart = read_program_header (PT_DYNAMIC, &sect_size, &arch_size);
+  buf = bufstart = read_program_header (PT_DYNAMIC, &sect_size, &arch_size,
+					&base_addr);
   if (!buf)
     return 0;
 
@@ -761,6 +771,9 @@ scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
 	if (ptr)
 	  *ptr = dyn_ptr;
 
+	if (ptr_addr)
+	  *ptr_addr = base_addr + buf - bufstart;
+
 	xfree (bufstart);
 	return 1;
       }
@@ -786,13 +799,13 @@ static CORE_ADDR
 elf_locate_base (void)
 {
   struct bound_minimal_symbol msymbol;
-  CORE_ADDR dyn_ptr;
+  CORE_ADDR dyn_ptr, dyn_ptr_addr;
 
   /* Look for DT_MIPS_RLD_MAP first.  MIPS executables use this
      instead of DT_DEBUG, although they sometimes contain an unused
      DT_DEBUG.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
-      || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
+  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
       gdb_byte *pbuf;
@@ -806,9 +819,27 @@ elf_locate_base (void)
       return extract_typed_address (pbuf, ptr_type);
     }
 
+  /* Then check DT_MIPS_RLD_MAP_REL.  MIPS executables now use this form
+     because of needing to support PIE.  DT_MIPS_RLD_MAP will also exist
+     in non-PIE.  */
+  if (scan_dyntag (DT_MIPS_RLD_MAP_REL, exec_bfd, &dyn_ptr, &dyn_ptr_addr)
+      || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr))
+    {
+      struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+      gdb_byte *pbuf;
+      int pbuf_size = TYPE_LENGTH (ptr_type);
+
+      pbuf = alloca (pbuf_size);
+      /* DT_MIPS_RLD_MAP_REL contains an offset from the address of the
+	 DT slot to the address of the dynamic link structure.  */
+      if (target_read_memory (dyn_ptr + dyn_ptr_addr, pbuf, pbuf_size))
+	return 0;
+      return extract_typed_address (pbuf, ptr_type);
+    }
+
   /* Find DT_DEBUG.  */
-  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)
-      || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr))
+  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
     return dyn_ptr;
 
   /* This may be a static executable.  Look for the symbol
@@ -2607,7 +2638,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
       gdb_byte *buf, *buf2;
       int arch_size;
 
-      buf = read_program_header (-1, &phdrs_size, &arch_size);
+      buf = read_program_header (-1, &phdrs_size, &arch_size, NULL);
       buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
       if (buf != NULL && buf2 != NULL)
 	{
@@ -3228,7 +3259,7 @@ elf_lookup_lib_symbol (struct objfile *objfile,
       abfd = objfile->obfd;
     }
 
-  if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
+  if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL, NULL) != 1)
     return NULL;
 
   return lookup_global_symbol_from_objfile (objfile, name, domain);
-- 
2.2.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-06-23 15:31 ` Joseph Myers
  2015-06-23 15:52   ` Matthew Fortune
  2015-06-26 12:45   ` Matthew Fortune
@ 2015-07-13 10:21   ` Matthew Fortune
  2 siblings, 0 replies; 8+ messages in thread
From: Matthew Fortune @ 2015-07-13 10:21 UTC (permalink / raw)
  To: gdb-patches; +Cc: Joseph Myers

Matthew Fortune <Matthew.Fortune@imgtec.com> writes:
> This tag allows debugging of MIPS position independent executables and
> provides access to shared library information.
> 
> gdb/gdbserver/
> 
> 	* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL.
> 
> gdb/
> 
> 	* solib-svr4.c (read_program_header): Add base_addr argument to
> 	report the runtime address of the segment.
> 	(find_program_interpreter): Update read_program_header call to pass
> 	a NULL pointer for the new argument.
> 	(scan_dyntag): Add ptr_addr argument to report the runtime address
> 	of the tag payload.
> 	(scan_dyntag_auxv): Likewise and use thew new base_addr argument of
> 	read_program_header to get the base address of the dynamic segment.
> 	(elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and
> 	read_program_header.
> 	(elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL.

Ping.

Matthew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-06-26 12:45   ` Matthew Fortune
@ 2015-08-12 10:30     ` Pedro Alves
  2015-08-12 13:43       ` Matthew Fortune
  0 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2015-08-12 10:30 UTC (permalink / raw)
  To: Matthew Fortune, gdb-patches; +Cc: Joseph Myers

On 06/26/2015 01:45 PM, Matthew Fortune wrote:
> Joseph Myers <joseph@codesourcery.com> writes:
>> On Tue, 23 Jun 2015, Matthew Fortune wrote:
>>
>>> Please note that the new DT_MIPS_RLD_MAP2 support will not be enabled
>>> unless the host's elf.h header has the new tag defined in it. For
>>> cross compiled GDB this may mean hacking the solib-svr4.c file to
>>> define the macro until such time as distributions update glibc.
>>
>> That doesn't make any sense to me.  Hosts (e.g. MinGW) may not have
>> elf.h at all.  GDB should get these definitions from the #include
>> "elf/mips.h"
>> already in solib-svr4.c (i.e. from toplevel's include/elf/mips.h).  And
>> so there should be no #ifdefs there.

Thanks Joseph.

> Updated version below to match the name of the new tag as committed to
> binutils and removed the #ifdefs from solib-svr4.c.
> 
> binutils commit: a5499fa Add support for DT_MIPS_RLD_MAP_REL.
> 
> OK to commit?
> 

OK.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-08-12 10:30     ` Pedro Alves
@ 2015-08-12 13:43       ` Matthew Fortune
  2015-08-12 13:59         ` Pedro Alves
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Fortune @ 2015-08-12 13:43 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches; +Cc: Joseph Myers

Pedro Alves <palves@redhat.com> writes:
> On 06/26/2015 01:45 PM, Matthew Fortune wrote:
> > Updated version below to match the name of the new tag as committed to
> > binutils and removed the #ifdefs from solib-svr4.c.
> >
> > binutils commit: a5499fa Add support for DT_MIPS_RLD_MAP_REL.
> >
> > OK to commit?
> >
> 
> OK.

Thanks. Although I can commit this as I have write access I am not on
write-after-approval for GDB. Am I alright to add myself?

Thanks,
Matthew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb)
  2015-08-12 13:43       ` Matthew Fortune
@ 2015-08-12 13:59         ` Pedro Alves
  0 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2015-08-12 13:59 UTC (permalink / raw)
  To: Matthew Fortune, gdb-patches; +Cc: Joseph Myers

On 08/12/2015 02:43 PM, Matthew Fortune wrote:

> Thanks. Although I can commit this as I have write access I am not on
> write-after-approval for GDB. Am I alright to add myself?

Certainly.  Go for it.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-08-12 13:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-23 15:23 [PATCH, MIPS] Support shared library debug with MIPS PIE (gdb) Matthew Fortune
2015-06-23 15:31 ` Joseph Myers
2015-06-23 15:52   ` Matthew Fortune
2015-06-26 12:45   ` Matthew Fortune
2015-08-12 10:30     ` Pedro Alves
2015-08-12 13:43       ` Matthew Fortune
2015-08-12 13:59         ` Pedro Alves
2015-07-13 10:21   ` Matthew Fortune

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).