From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15904 invoked by alias); 3 Apr 2012 20:48:11 -0000 Received: (qmail 15894 invoked by uid 22791); 3 Apr 2012 20:48:10 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=AWL,BAYES_00,FROM_12LTRDOM,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,SUBJ_OBFU_PUNCT_FEW,SUBJ_OBFU_PUNCT_MANY X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 03 Apr 2012 20:47:40 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1SFAde-0000uu-VV from Maciej_Rozycki@mentor.com for gdb-patches@sourceware.org; Tue, 03 Apr 2012 13:47:39 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Tue, 3 Apr 2012 13:47:38 -0700 Received: from [172.30.14.14] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Tue, 3 Apr 2012 21:47:36 +0100 Date: Tue, 03 Apr 2012 20:48:00 -0000 From: "Maciej W. Rozycki" To: Subject: [PATCH] gdbserver: Handle DT_MIPS_RLD_MAP dynamic tag Message-ID: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-04/txt/msg00047.txt.bz2 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 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;