From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:34263) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQFZ1-0000N7-Aw for qemu-devel@nongnu.org; Thu, 11 Apr 2013 07:21:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UQFYx-0003tN-Hv for qemu-devel@nongnu.org; Thu, 11 Apr 2013 07:21:11 -0400 Received: from relay1.mentorg.com ([192.94.38.131]:61221) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQFYx-0003ss-Bx for qemu-devel@nongnu.org; Thu, 11 Apr 2013 07:21:07 -0400 Date: Thu, 11 Apr 2013 12:20:57 +0100 From: "Abid, Hafiz" Message-ID: <1365679257.9625.0@abidh-ubunto1104> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; delsp=Yes; format=Flowed Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: gdb@sourceware.org, riku.voipio@iki.fi, macro@codesourcery.com Hi All, I have faced a problem using GDB with user-mode qemu. Although problem =20 was observed for MIPS, I think it is a generic problem. I would =20 appreciate an advice from experts on how best to deal with. Here is the =20 problem description. GDB has ability to call function from the program being debugged =20 (http://sourceware.org/gdb/onlinedocs/gdb/Calling.html#Calling). For =20 MIPS (and on other architectures), it put a breakpoint on the stack =20 that is used as return address of the function. When that breakpoint is =20 hit, GDB knows that function is complete and it can return control to =20 user. This breakpoint on stack causes problem for QEMU. When it runs =20 that instruction from stack, it add write-protection to that page. So =20 after the function call, GDB is not able to write to stack. So any =20 future function call or other operation that need to write to stack =20 will fail. I show an example session below taken mostly from =20 call-sc.exp of GDB testsuite. There are 2 possible solution in my mind. One was to allow writing =20 memory if this page originally had write access. This is a single line =20 fix and a patch is below. Second option was to not add write protection to the page in the first =20 place if i) Page currently has write access. ii) First instruction is a breakpoint. If 2nd looks a better option then I can prepare a patch for it. If =20 there some other approach that will better solve this problem then =20 please let me know. Thanks, Abid GDB session: GNU gdb (GDB) 7.4.50.20120716-cvs Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later =20 This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show =20 copying" and "show warranty" for details. This GDB was configured as "--host=3Di686-pc-linux-gnu =20 --target=3Dmips-linux-gnu". For bug reporting instructions, please see: ... Reading symbols from /home/abidh/work/mips-demo/call_static...done. (gdb) target remote :8000 Remote debugging using :8000 [New Remote target] [Switching to Remote target] __start () at ../ports/sysdeps/mips/start.S:84 84 ../ports/sysdeps/mips/start.S: No such file or directory. (gdb) break main Breakpoint 1 at 0x4011e8: file call.c, line 63. (gdb) c Continuing. Breakpoint 1, main () at call.c:63 63 Fun(foo);=09 (gdb) p /c fun() $1 =3D 49 '1' (gdb) p /c fun() Cannot access memory at address 0x40800258 (gdb) Signed-off-by: Hafiz Abid Qadeer --- exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index fa1e0c3..af5610b 100644 --- a/exec.c +++ b/exec.c @@ -1844,8 +1844,9 @@ int cpu_memory_rw_debug(CPUArchState *env, =20 target_ulong addr, if (!(flags & PAGE_VALID)) return -1; if (is_write) { - if (!(flags & PAGE_WRITE)) + if ((!(flags & PAGE_WRITE)) && (!(flags & =20 PAGE_WRITE_ORG))) { return -1; + } /* XXX: this code should not depend on lock_user */ if (!(p =3D lock_user(VERIFY_WRITE, addr, l, 0))) return -1; --=20 1.7.9.5=