From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11376 invoked by alias); 12 Dec 2012 14:24:07 -0000 Received: (qmail 11362 invoked by uid 22791); 12 Dec 2012 14:24:04 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=BAYES_00,RCVD_IN_HOSTKARMA_YE,TW_BJ X-Spam-Check-By: sourceware.org Received: from na3sys009aob106.obsmtp.com (HELO na3sys009aog106.obsmtp.com) (74.125.149.76) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 12 Dec 2012 14:23:55 +0000 Received: from mx20.qnx.com ([72.1.200.103]) (using TLSv1) by na3sys009aob106.postini.com ([74.125.148.12]) with SMTP ID DSNKUMiTex1CClIV6ZCXdxzldOER7NPGngo8@postini.com; Wed, 12 Dec 2012 06:23:55 PST Received: by mx20.qnx.com (Postfix, from userid 500) id 9FA3D20E57; Wed, 12 Dec 2012 09:23:54 -0500 (EST) Received: from exhts.ott.qnx.com (exhts1 [10.222.2.110]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mx20.qnx.com (Postfix) with ESMTPS id 202F520E05 for ; Wed, 12 Dec 2012 09:23:54 -0500 (EST) Received: from [10.222.96.215] (10.222.96.215) by exhts1.ott.qnx.com (10.222.2.25) with Microsoft SMTP Server id 14.2.318.1; Wed, 12 Dec 2012 09:23:53 -0500 Message-ID: <50C8937A.1090905@qnx.com> Date: Wed, 12 Dec 2012 14:24:00 -0000 From: Aleksandar Ristovski User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: "gdb-patches@sourceware.org" Subject: [patch] gdbarch_syscall_pc_increment Content-Type: multipart/mixed; boundary="------------050100050403050704060207" 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-12/txt/msg00387.txt.bz2 --------------050100050403050704060207 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 602 Hello all, This patch fixes stepping over system call instruction on architectures that use software single stepping and also may increment PC upon return from the system call to communicate error. (e.g. this is what we do on Neutrino). Note: I could only test this on Neutrino. Thanks, Aleksandar ChangeLog: * gdbarch.sh (syscall_pc_increment): New function. * gdbarch.h, gdbarch.c: Regenerated. * arm-tdep.c (arm_software_single_step): Use gdbarch_syscall_pc_increment and if provided, insert second single step breakpoint at the incremented address. --------------050100050403050704060207 Content-Type: text/x-patch; name="gdbarch_syscall_pc_increment-201212111513.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gdbarch_syscall_pc_increment-201212111513.patch" Content-length: 6822 Index: gdb/gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.550 diff -u -p -r1.550 gdbarch.sh --- gdb/gdbarch.sh 21 Nov 2012 00:29:54 -0000 1.550 +++ gdb/gdbarch.sh 11 Dec 2012 20:13:20 -0000 @@ -798,6 +798,10 @@ M:void:record_special_symbol:struct objf # Get architecture-specific system calls information from registers. M:LONGEST:get_syscall_number:ptid_t ptid:ptid +# Return number of bytes the architecture may increment PC after +# syscall. +M:int:syscall_pc_increment:const struct frame_info *frame:frame + # SystemTap related fields and functions. # Prefix used to mark an integer constant on the architecture's assembly Index: gdb/gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.449 diff -u -p -r1.449 gdbarch.h --- gdb/gdbarch.h 21 Nov 2012 00:29:54 -0000 1.449 +++ gdb/gdbarch.h 11 Dec 2012 20:13:20 -0000 @@ -611,7 +611,7 @@ extern void set_gdbarch_addr_bits_remove FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can single step. If not, then implement single step using breakpoints. - A return value of 1 means that the software_single_step breakpoints + A return value of 1 means that the software_single_step breakpoints were inserted; 0 means they were not. */ extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch); @@ -998,6 +998,15 @@ typedef LONGEST (gdbarch_get_syscall_num extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid); extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number); +/* Return number of bytes the architecture may increment PC after + syscall. */ + +extern int gdbarch_syscall_pc_increment_p (struct gdbarch *gdbarch); + +typedef int (gdbarch_syscall_pc_increment_ftype) (struct gdbarch *gdbarch, const struct frame_info *frame); +extern int gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, const struct frame_info *frame); +extern void set_gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, gdbarch_syscall_pc_increment_ftype *syscall_pc_increment); + /* SystemTap related fields and functions. Prefix used to mark an integer constant on the architecture's assembly For example, on x86 integer constants are written as: Index: gdb/gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.501 diff -u -p -r1.501 gdbarch.c --- gdb/gdbarch.c 21 Nov 2012 00:29:54 -0000 1.501 +++ gdb/gdbarch.c 11 Dec 2012 20:13:20 -0000 @@ -263,6 +263,7 @@ struct gdbarch gdbarch_get_siginfo_type_ftype *get_siginfo_type; gdbarch_record_special_symbol_ftype *record_special_symbol; gdbarch_get_syscall_number_ftype *get_syscall_number; + gdbarch_syscall_pc_increment_ftype *syscall_pc_increment; const char * stap_integer_prefix; const char * stap_integer_suffix; const char * stap_register_prefix; @@ -431,6 +432,7 @@ struct gdbarch startup_gdbarch = 0, /* get_siginfo_type */ 0, /* record_special_symbol */ 0, /* get_syscall_number */ + 0, /* syscall_pc_increment */ 0, /* stap_integer_prefix */ 0, /* stap_integer_suffix */ 0, /* stap_register_prefix */ @@ -731,6 +733,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of get_siginfo_type, has predicate. */ /* Skip verify of record_special_symbol, has predicate. */ /* Skip verify of get_syscall_number, has predicate. */ + /* Skip verify of syscall_pc_increment, has predicate. */ /* Skip verify of stap_integer_prefix, invalid_p == 0 */ /* Skip verify of stap_integer_suffix, invalid_p == 0 */ /* Skip verify of stap_register_prefix, invalid_p == 0 */ @@ -1345,6 +1348,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s "gdbarch_dump: static_transform_name = <%s>\n", host_address_to_string (gdbarch->static_transform_name)); fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_syscall_pc_increment_p() = %d\n", + gdbarch_syscall_pc_increment_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: syscall_pc_increment = <%s>\n", + host_address_to_string (gdbarch->syscall_pc_increment)); + fprintf_unfiltered (file, "gdbarch_dump: target_desc = %s\n", host_address_to_string (gdbarch->target_desc)); fprintf_unfiltered (file, @@ -3890,6 +3899,30 @@ set_gdbarch_get_syscall_number (struct g gdbarch->get_syscall_number = get_syscall_number; } +int +gdbarch_syscall_pc_increment_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->syscall_pc_increment != NULL; +} + +int +gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, const struct frame_info *frame) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->syscall_pc_increment != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_syscall_pc_increment called\n"); + return gdbarch->syscall_pc_increment (gdbarch, frame); +} + +void +set_gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, + gdbarch_syscall_pc_increment_ftype syscall_pc_increment) +{ + gdbarch->syscall_pc_increment = syscall_pc_increment; +} + const char * gdbarch_stap_integer_prefix (struct gdbarch *gdbarch) { Index: gdb/arm-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/arm-tdep.c,v retrieving revision 1.373 diff -u -p -r1.373 arm-tdep.c --- gdb/arm-tdep.c 21 Nov 2012 00:29:54 -0000 1.373 +++ gdb/arm-tdep.c 11 Dec 2012 20:13:21 -0000 @@ -5242,6 +5242,31 @@ arm_software_single_step (struct frame_i next_pc = arm_get_next_pc (frame, get_frame_pc (frame)); arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc); + if (gdbarch_syscall_pc_increment_p (gdbarch)) + { + /* Some OS-es will increment pc to differentiate success vs + * error returning from a sys call. */ + const int inc = gdbarch_syscall_pc_increment (gdbarch, frame); + const enum bfd_endian byte_order_for_code + = gdbarch_byte_order_for_code (gdbarch); + const LONGEST this_pc = get_frame_pc (frame); + LONGEST insn, mask, match; + + if (arm_frame_is_thumb (frame)) + { + mask = 0xff000000; + match = 0xdf000000; + } + else + { + mask = 0x0f000000; + match = 0x0f000000; + } + if (safe_read_memory_integer (this_pc, 4, byte_order_for_code, &insn) + && (insn & mask) == match) + arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc + inc); + } + return 1; } --------------050100050403050704060207--