From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31503 invoked by alias); 1 Dec 2004 22:33:11 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 31307 invoked from network); 1 Dec 2004 22:32:46 -0000 Received: from unknown (HELO arwen.tausq.org) (64.81.244.109) by sourceware.org with SMTP; 1 Dec 2004 22:32:46 -0000 Received: by arwen.tausq.org (Postfix, from userid 1000) id 00E2343810; Wed, 1 Dec 2004 14:32:43 -0800 (PST) Date: Wed, 01 Dec 2004 22:33:00 -0000 From: Randolph Chung To: Andrew Cagney Cc: gdb-patches@sources.redhat.com Subject: Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED Message-ID: <20041201223243.GK6359@tausq.org> Reply-To: Randolph Chung References: <20041128184141.GG6359@tausq.org> <41AA2D08.3030304@gnu.org> <20041129033013.GJ6359@tausq.org> <41AB3C1D.80509@gnu.org> <20041130065620.GT6359@tausq.org> <41AC88B2.5070501@gnu.org> <20041130164401.GV6359@tausq.org> <41ACA6BE.5080603@gnu.org> <20041130173841.GW6359@tausq.org> <41AE3759.3030503@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <41AE3759.3030503@gnu.org> X-GPG: for GPG key, see http://www.tausq.org/gpg.txt User-Agent: Mutt/1.5.6+20040722i X-SW-Source: 2004-12/txt/msg00033.txt.bz2 > Anyway, trying modifying gdbarch_read_pc and unwind_pc (I suspect you > need to modify both - which is a bug) to read something like: > > if (instruction nullified) > return next-pc > else > return this-pc i did s/next-pc/prev-pc/ instead... still seems a bit hacky to me, but it does seem to work. so is this ok? randolph 2004-12-01 Randolph Chung * gdbarch.sh (instruction_nullified): Delete. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * hppa-tdep.c (hppa_target_read_pc): Adjust pc if instruction is nullified. (hppa_unwind_pc): Likewise. (hppa_instruction_nullified): Delete. (hppa_gdbarch_init): Don't set instruction_nullified method. * infrun.c (infwait_states): Remove infwait_nullified_state. (handle_inferior_event): Remove handling of infwait_nullified_state. Remove handling of nullified instructions. Index: gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.315 diff -u -p -r1.315 gdbarch.c --- gdbarch.c 23 Nov 2004 21:05:18 -0000 1.315 +++ gdbarch.c 1 Dec 2004 22:13:12 -0000 @@ -212,7 +212,6 @@ struct gdbarch gdbarch_smash_text_address_ftype *smash_text_address; gdbarch_software_single_step_ftype *software_single_step; gdbarch_single_step_through_delay_ftype *single_step_through_delay; - gdbarch_instruction_nullified_ftype *instruction_nullified; gdbarch_print_insn_ftype *print_insn; gdbarch_skip_trampoline_code_ftype *skip_trampoline_code; gdbarch_skip_solib_resolver_ftype *skip_solib_resolver; @@ -339,7 +338,6 @@ struct gdbarch startup_gdbarch = 0, /* smash_text_address */ 0, /* software_single_step */ 0, /* single_step_through_delay */ - generic_instruction_nullified, /* instruction_nullified */ 0, /* print_insn */ 0, /* skip_trampoline_code */ generic_skip_solib_resolver, /* skip_solib_resolver */ @@ -437,7 +435,6 @@ gdbarch_alloc (const struct gdbarch_info current_gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity; current_gdbarch->addr_bits_remove = core_addr_identity; current_gdbarch->smash_text_address = core_addr_identity; - current_gdbarch->instruction_nullified = generic_instruction_nullified; current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code; current_gdbarch->skip_solib_resolver = generic_skip_solib_resolver; current_gdbarch->in_solib_return_trampoline = generic_in_solib_return_trampoline; @@ -594,7 +591,6 @@ verify_gdbarch (struct gdbarch *current_ /* Skip verify of smash_text_address, invalid_p == 0 */ /* Skip verify of software_single_step, has predicate */ /* Skip verify of single_step_through_delay, has predicate */ - /* Skip verify of instruction_nullified, invalid_p == 0 */ if (current_gdbarch->print_insn == 0) fprintf_unfiltered (log, "\n\tprint_insn"); /* Skip verify of skip_trampoline_code, invalid_p == 0 */ @@ -1199,9 +1195,6 @@ gdbarch_dump (struct gdbarch *current_gd fprintf_unfiltered (file, "gdbarch_dump: inner_than = <0x%lx>\n", (long) current_gdbarch->inner_than); - fprintf_unfiltered (file, - "gdbarch_dump: instruction_nullified = <0x%lx>\n", - (long) current_gdbarch->instruction_nullified); #ifdef TARGET_INT_BIT fprintf_unfiltered (file, "gdbarch_dump: TARGET_INT_BIT # %s\n", @@ -3373,23 +3366,6 @@ set_gdbarch_single_step_through_delay (s } int -gdbarch_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache) -{ - gdb_assert (gdbarch != NULL); - gdb_assert (gdbarch->instruction_nullified != NULL); - if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_instruction_nullified called\n"); - return gdbarch->instruction_nullified (gdbarch, regcache); -} - -void -set_gdbarch_instruction_nullified (struct gdbarch *gdbarch, - gdbarch_instruction_nullified_ftype instruction_nullified) -{ - gdbarch->instruction_nullified = instruction_nullified; -} - -int gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, struct disassemble_info *info) { gdb_assert (gdbarch != NULL); Index: gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.276 diff -u -p -r1.276 gdbarch.h --- gdbarch.h 23 Nov 2004 21:05:19 -0000 1.276 +++ gdbarch.h 1 Dec 2004 22:13:12 -0000 @@ -1227,16 +1227,6 @@ typedef int (gdbarch_single_step_through extern int gdbarch_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame); extern void set_gdbarch_single_step_through_delay (struct gdbarch *gdbarch, gdbarch_single_step_through_delay_ftype *single_step_through_delay); -/* On some systems, the PC may be left pointing at an instruction that won't - actually be executed. This is usually indicated by a bit in the PSW. If - we find ourselves in such a state, then we step the target beyond the - nullified instruction before returning control to gdb. - Return non-zero if the processor is about to execute a nullified instruction. */ - -typedef int (gdbarch_instruction_nullified_ftype) (struct gdbarch *gdbarch, struct regcache *regcache); -extern int gdbarch_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache); -extern void set_gdbarch_instruction_nullified (struct gdbarch *gdbarch, gdbarch_instruction_nullified_ftype *instruction_nullified); - /* FIXME: cagney/2003-08-28: Need to find a better way of selecting the disassembler. Perhaps objdump can handle it? */ Index: gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.351 diff -u -p -r1.351 gdbarch.sh --- gdbarch.sh 23 Nov 2004 21:05:20 -0000 1.351 +++ gdbarch.sh 1 Dec 2004 22:13:12 -0000 @@ -614,12 +614,6 @@ F:=:void:software_single_step:enum targe # Return non-zero if the processor is executing a delay slot and a # further single-step is needed before the instruction finishes. M::int:single_step_through_delay:struct frame_info *frame:frame -# On some systems, the PC may be left pointing at an instruction that won't -# actually be executed. This is usually indicated by a bit in the PSW. If -# we find ourselves in such a state, then we step the target beyond the -# nullified instruction before returning control to gdb. -# Return non-zero if the processor is about to execute a nullified instruction. -m::int:instruction_nullified:struct regcache *regcache:regcache::generic_instruction_nullified::0 # FIXME: cagney/2003-08-28: Need to find a better way of selecting the # disassembler. Perhaps objdump can handle it? f:TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, struct disassemble_info *info:vma, info::0: Index: hppa-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-tdep.c,v retrieving revision 1.183 diff -u -p -r1.183 hppa-tdep.c --- hppa-tdep.c 1 Dec 2004 06:54:56 -0000 1.183 +++ hppa-tdep.c 1 Dec 2004 22:13:12 -0000 @@ -1042,6 +1080,8 @@ static CORE_ADDR hppa_target_read_pc (ptid_t ptid) { int flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid); + ULONGEST ipsw = read_register_pid (HPPA_IPSW_REGNUM, ptid); + CORE_ADDR pc; /* The following test does not belong here. It is OS-specific, and belongs in native code. */ @@ -1049,7 +1089,17 @@ hppa_target_read_pc (ptid_t ptid) if (flags & 2) return read_register_pid (31, ptid) & ~0x3; - return read_register_pid (HPPA_PCOQ_HEAD_REGNUM, ptid) & ~0x3; + pc = read_register_pid (HPPA_PCOQ_HEAD_REGNUM, ptid) & ~0x3; + + /* If the current instruction is nullified, then we are effectively + still executing the previous instruction. Pretend we are still + there. This is needed when single stepping; if the nullified instruction + is on a different line, we don't want gdb to think we've stepped onto + that line. */ + if (ipsw & 0x00200000) + pc -= 4; + + return pc; } /* Write out the PC. If currently in a syscall, then also write the new @@ -2185,7 +2235,21 @@ hppa_unwind_dummy_id (struct gdbarch *gd static CORE_ADDR hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - return frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3; + ULONGEST ipsw; + CORE_ADDR pc; + + ipsw = frame_unwind_register_signed (next_frame, HPPA_IPSW_REGNUM); + pc = frame_unwind_register_signed (next_frame, HPPA_PCOQ_HEAD_REGNUM) & ~3; + + /* If the current instruction is nullified, then we are effectively + still executing the previous instruction. Pretend we are still + there. This is needed when single stepping; if the nullified instruction + is on a different line, we don't want gdb to think we've stepped onto + that line. */ + if (ipsw & 0x00200000) + pc -= 4; + + return pc; } /* Instead of this nasty cast, add a method pvoid() that prints out a @@ -2291,22 +2355,6 @@ hppa_pc_requires_run_before_use (CORE_AD return (!target_has_stack && (pc & 0xFF000000)); } -static int -hppa_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache) -{ - ULONGEST tmp, ipsw, flags; - - regcache_cooked_read (regcache, HPPA_IPSW_REGNUM, &tmp); - ipsw = extract_unsigned_integer (&tmp, - register_size (gdbarch, HPPA_IPSW_REGNUM)); - - regcache_cooked_read (regcache, HPPA_FLAGS_REGNUM, &tmp); - flags = extract_unsigned_integer (&tmp, - register_size (gdbarch, HPPA_FLAGS_REGNUM)); - - return ((ipsw & 0x00200000) && !(flags & 0x2)); -} - /* Return the GDB type object for the "standard" data type of data in register N. */ @@ -2573,7 +2623,6 @@ hppa_gdbarch_init (struct gdbarch_info i set_gdbarch_breakpoint_from_pc (gdbarch, hppa_breakpoint_from_pc); set_gdbarch_pseudo_register_read (gdbarch, hppa_pseudo_register_read); - set_gdbarch_instruction_nullified (gdbarch, hppa_instruction_nullified); /* Frame unwind methods. */ set_gdbarch_unwind_dummy_id (gdbarch, hppa_unwind_dummy_id); Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.183 diff -u -p -r1.183 infrun.c --- infrun.c 23 Nov 2004 21:05:23 -0000 1.183 +++ infrun.c 1 Dec 2004 22:13:12 -0000 @@ -870,7 +870,6 @@ enum infwait_states { infwait_normal_state, infwait_thread_hop_state, - infwait_nullified_state, infwait_nonstep_watch_state }; @@ -1263,12 +1262,6 @@ handle_inferior_event (struct execution_ stepped_after_stopped_by_watchpoint = 0; break; - case infwait_nullified_state: - if (debug_infrun) - printf_unfiltered ("infrun: infwait_nullified_state\n"); - stepped_after_stopped_by_watchpoint = 0; - break; - case infwait_nonstep_watch_state: if (debug_infrun) printf_unfiltered ("infrun: infwait_nonstep_watch_state\n"); @@ -1730,30 +1723,6 @@ handle_inferior_event (struct execution_ singlestep_breakpoints_inserted_p = 0; } - /* If PC is pointing at a nullified instruction, then step beyond - it before deciding what to do. This is required when we are stepping - through a function where the last instruction is a branch with a - nullified instruction in the delay slot that belongs to the next - line (which may be in a different function altogether). */ - - if (gdbarch_instruction_nullified (current_gdbarch, current_regcache)) - { - if (debug_infrun) - printf_unfiltered ("infrun: instruction nullified\n"); - registers_changed (); - target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); - - /* We may have received a signal that we want to pass to - the inferior; therefore, we must not clobber the waitstatus - in WS. */ - - ecs->infwait_state = infwait_nullified_state; - ecs->waiton_ptid = ecs->ptid; - ecs->wp = &(ecs->tmpstatus); - prepare_to_wait (ecs); - return; - } - /* It may not be necessary to disable the watchpoint to stop over it. For example, the PA can (with some kernel cooperation) single step over a watchpoint without disabling the watchpoint. */ -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/