This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] gdbserver: Handle DT_MIPS_RLD_MAP dynamic tag


Hi,

 While working on a test case for an unrelated issue I have noticed 
single-stepping over system library calls is broken on the MIPS/Linux 
target when `gdbserver' is used.  On closer inspection I have observed 
`gdbserver' reports no shared libraries loaded.  Further investigation has 
revealed that the newly-added support for the `qXfer:libraries-svr4:read' 
packet does not handle the DT_MIPS_RLD_MAP dynamic tag and therefore 
cannot locate the link map on the MIPS target.

 Such support has been long present in gdb/solib-svr4.c, hence a fix 
turned out rather mechanical; here's a piece of code ported from there 
over to linux-low.c, likewise making no special exception just for the 
MIPS platform and applying to generic code instead.  This change has fixed 
the single-stepping problem observed for me.

 Just to be safe I have regression-tested this change for the 
mips-linux-gnu remote target, o32/big-endian multilib (using an x86 Linux 
host) with 139 failures removed starting from:

(gdb) PASS: gdb.base/break.exp: backtrace from factorial(5.1)
break exit
Function "exit" not defined.
(gdb) FAIL: gdb.base/break.exp: setting breakpoint at exit

and no new ones.  I didn't test the change for any other target, but then 
DT_MIPS_RLD_MAP tags are not expected to appear on non-MIPS binaries, 
hence the "dyn->d_tag == DT_MIPS_RLD_MAP" conditional is not expected to 
trigger there.

 OK to apply?

2012-04-03  Maciej W. Rozycki  <macro@codesourcery.com>

	gdb/gdbserver/
	* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP.

  Maciej

gdb-gdbserver-rld-map.diff
Index: gdb-fsf-trunk-quilt/gdb/gdbserver/linux-low.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/gdbserver/linux-low.c	2012-04-03 13:38:58.575561428 +0100
+++ gdb-fsf-trunk-quilt/gdb/gdbserver/linux-low.c	2012-04-03 13:39:17.315624148 +0100
@@ -5419,7 +5419,9 @@ get_dynamic (const int pid, const int is
 }
 
 /* Return &_r_debug in the inferior, or -1 if not present.  Return value
-   can be 0 if the inferior does not yet have the library list initialized.  */
+   can be 0 if the inferior does not yet have the library list initialized.
+   We look for DT_MIPS_RLD_MAP first.  MIPS executables use this instead of
+   DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too.  */
 
 static CORE_ADDR
 get_r_debug (const int pid, const int is_elf64)
@@ -5437,6 +5439,21 @@ get_r_debug (const int pid, const int is
       if (is_elf64)
 	{
 	  Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
+	  union
+	    {
+	      Elf64_Xword map;
+	      unsigned char buf[sizeof (Elf64_Xword)];
+	    }
+	  rld_map;
+
+	  if (dyn->d_tag == DT_MIPS_RLD_MAP)
+	    {
+	      if (linux_read_memory (dyn->d_un.d_val,
+				     rld_map.buf, sizeof (rld_map.buf)) == 0)
+		return rld_map.map;
+	      else
+		break;
+	    }
 
 	  if (dyn->d_tag == DT_DEBUG)
 	    return dyn->d_un.d_val;
@@ -5447,6 +5464,21 @@ get_r_debug (const int pid, const int is
       else
 	{
 	  Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
+	  union
+	    {
+	      Elf32_Word map;
+	      unsigned char buf[sizeof (Elf32_Word)];
+	    }
+	  rld_map;
+
+	  if (dyn->d_tag == DT_MIPS_RLD_MAP)
+	    {
+	      if (linux_read_memory (dyn->d_un.d_val,
+				     rld_map.buf, sizeof (rld_map.buf)) == 0)
+		return rld_map.map;
+	      else
+		break;
+	    }
 
 	  if (dyn->d_tag == DT_DEBUG)
 	    return dyn->d_un.d_val;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]