* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED
@ 2004-12-01 13:32 Paul Schlie
0 siblings, 0 replies; 44+ messages in thread
From: Paul Schlie @ 2004-12-01 13:32 UTC (permalink / raw)
To: gdb-patches
> Randolph wrote:
>> >well, first i want to understand the problem. because i'm still not
>> >yet 100% convinced that step_through_delay will work. simply using the
>> >"instruction_nullified" method in hppa-tdep as the "step_through_delay"
>> >method certainly is not working...
>>
>> When doing a stepi? step_through_delay certainly won't help when it
>> comes to doing a backtrace from the nullified instruction.
>
> when doing a step.
A point that may be worth considering is that on architectures which support
jump/branch delay slots, the branch and delay slot is actually logically
executed as single compound instruction, treated by the machine as a unified
whole.
i.e. if an interrupt is received, the machine will break either at the
jump/branch, or at it's target (after logically completing execution of
it's delay slot, conditionally or otherwise, but never in between, as the
control flow through the delay slot is bound to the preceding jump/branch.)
Therefore it's likely ill advised to attempt to logically single step
through a corresponding instruction pair any differently, as although coded
as two separate instructions, execution can't be literally interrupted
between the jump/branch and it's delay slot on most machines, I believe.
^ permalink raw reply [flat|nested] 44+ messages in thread* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED
@ 2004-12-01 16:25 Randolph Chung
0 siblings, 0 replies; 44+ messages in thread
From: Randolph Chung @ 2004-12-01 16:25 UTC (permalink / raw)
To: gdb-patches
In-Reply-To: <BDD32F47.81A3%schlie@comcast.net>
> A point that may be worth considering is that on architectures which support
> jump/branch delay slots, the branch and delay slot is actually logically
> executed as single compound instruction, treated by the machine as a unified
> whole.
i don't think this is true for hppa. for instance you can do a hardware
singlestep into the delay slot of a branch insn by setting the recovery
counter appropriately. this will cause an hardware interruption which
the kernel can translate to a SIGTRAP.
nullification is also a more general concept on hppa which doesn't only
apply to branch instructions. A lot of ALU instructions can also
conditioanlly nullify the next insn, which potentially could belong to a
different line of source code. gcc uses this to implement if-conversion,
for example.
randolph
--
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/
^ permalink raw reply [flat|nested] 44+ messages in thread* [patch/RFA] multiarch INSTRUCTION_NULLIFIED
@ 2004-11-18 0:02 Randolph Chung
2004-11-18 14:26 ` Andrew Cagney
0 siblings, 1 reply; 44+ messages in thread
From: Randolph Chung @ 2004-11-18 0:02 UTC (permalink / raw)
To: gdb-patches
Currently only hppa uses this define, but possibly this will be useful
for other architectures which has conditionally nullified instructions
(ia64?) as well. This gets us one step closer to full multiarch
support..
Tested on hppa-linux with no regressions.
ok?
randolph
2004-11-17 Randolph Chung <tausq@debian.org>
* gdbarch.sh (instruction_nullified): New method.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
* hppa-tdep.c (hppa_instruction_nullified): Remove prototype and make
static. Rewrite to work directly off the passed regcache.
(hppa_gdbarch_init): Set instruction_nullified method.
* infrun.c (INSTRUCTION_NULLIFIED): Delete.
(handle_inferior_event): Replace INSTRUCTION_NULLIFIED with calls to
new gdbarch method.
* config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Delete definition.
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.350
diff -u -p -r1.350 gdbarch.sh
--- gdbarch.sh 31 Oct 2004 21:21:41 -0000 1.350
+++ gdbarch.sh 17 Nov 2004 23:37:57 -0000
@@ -614,6 +614,13 @@ 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 the user so as to avoid
+# confusion. Return non-zero if the processor is about to execute a
+# nullified instruction.
+M::int:instruction_nullified:struct regcache *regcache:regcache
# 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: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.314
diff -u -p -r1.314 gdbarch.c
--- gdbarch.c 31 Oct 2004 21:21:41 -0000 1.314
+++ gdbarch.c 17 Nov 2004 23:37:57 -0000
@@ -212,6 +212,7 @@ 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;
@@ -338,6 +339,7 @@ struct gdbarch startup_gdbarch =
0, /* smash_text_address */
0, /* software_single_step */
0, /* single_step_through_delay */
+ 0, /* instruction_nullified */
0, /* print_insn */
0, /* skip_trampoline_code */
generic_skip_solib_resolver, /* skip_solib_resolver */
@@ -591,6 +593,7 @@ 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, has predicate */
if (current_gdbarch->print_insn == 0)
fprintf_unfiltered (log, "\n\tprint_insn");
/* Skip verify of skip_trampoline_code, invalid_p == 0 */
@@ -1195,6 +1198,12 @@ 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: gdbarch_instruction_nullified_p() = %d\n",
+ gdbarch_instruction_nullified_p (current_gdbarch));
+ 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",
@@ -3366,6 +3375,30 @@ set_gdbarch_single_step_through_delay (s
}
int
+gdbarch_instruction_nullified_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->instruction_nullified != NULL;
+}
+
+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.275
diff -u -p -r1.275 gdbarch.h
--- gdbarch.h 31 Oct 2004 21:21:41 -0000 1.275
+++ gdbarch.h 17 Nov 2004 23:37:57 -0000
@@ -1227,6 +1227,19 @@ 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 the user so as to avoid
+ confusion. Return non-zero if the processor is about to execute a
+ nullified instruction. */
+
+extern int gdbarch_instruction_nullified_p (struct gdbarch *gdbarch);
+
+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: hppa-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.181
diff -u -p -r1.181 hppa-tdep.c
--- hppa-tdep.c 13 Nov 2004 02:15:32 -0000 1.181
+++ hppa-tdep.c 17 Nov 2004 23:37:57 -0000
@@ -71,7 +71,6 @@ const struct objfile_data *hppa_objfile_
/* FIXME: brobecker 2002-11-07: We will likely be able to make the
following functions static, once we hppa is partially multiarched. */
int hppa_pc_requires_run_before_use (CORE_ADDR pc);
-int hppa_instruction_nullified (void);
/* Handle 32/64-bit struct return conventions. */
@@ -2292,14 +2291,19 @@ hppa_pc_requires_run_before_use (CORE_AD
return (!target_has_stack && (pc & 0xFF000000));
}
-int
-hppa_instruction_nullified (void)
+static int
+hppa_instruction_nullified (struct gdbarch *gdbarch,
+ struct regcache *regcache)
{
- /* brobecker 2002/11/07: Couldn't we use a ULONGEST here? It would
- avoid the type cast. I'm leaving it as is for now as I'm doing
- semi-mechanical multiarching-related changes. */
- const int ipsw = (int) read_register (HPPA_IPSW_REGNUM);
- const int flags = (int) read_register (HPPA_FLAGS_REGNUM);
+ ULONGEST tmp, ipsw, flags;
+
+ regcache_cooked_read (regcache, HPPA_IPSW_REGNUM, &tmp);
+ ipsw = extract_unsigned_integer (&tmp, register_size (current_gdbarch,
+ HPPA_IPSW_REGNUM));
+
+ regcache_cooked_read (regcache, HPPA_FLAGS_REGNUM, &tmp);
+ flags = extract_unsigned_integer (&tmp, register_size (current_gdbarch,
+ HPPA_FLAGS_REGNUM));
return ((ipsw & 0x00200000) && !(flags & 0x2));
}
@@ -2570,6 +2574,7 @@ 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.182
diff -u -p -r1.182 infrun.c
--- infrun.c 8 Nov 2004 17:25:23 -0000 1.182
+++ infrun.c 17 Nov 2004 23:37:57 -0000
@@ -163,15 +163,6 @@ static int debug_infrun = 0;
#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
#endif
-/* 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 the user so as to avoid
- confusion. */
-
-#ifndef INSTRUCTION_NULLIFIED
-#define INSTRUCTION_NULLIFIED 0
-#endif
/* We can't step off a permanent breakpoint in the ordinary way, because we
can't remove it. Instead, we have to advance the PC to the next
@@ -1744,11 +1735,11 @@ handle_inferior_event (struct execution_
it so that the user won't be confused when GDB appears to be ready
to execute it. */
- /* if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */
- if (INSTRUCTION_NULLIFIED)
+ if (gdbarch_instruction_nullified_p (current_gdbarch)
+ && gdbarch_instruction_nullified (current_gdbarch, current_regcache))
{
if (debug_infrun)
- printf_unfiltered ("infrun: INSTRUCTION_NULLIFIED\n");
+ printf_unfiltered ("infrun: nullified instruction\n");
registers_changed ();
target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
Index: config/pa/tm-hppa.h
===================================================================
RCS file: /cvs/src/src/gdb/config/pa/tm-hppa.h,v
retrieving revision 1.77
diff -u -p -r1.77 tm-hppa.h
--- config/pa/tm-hppa.h 13 Nov 2004 02:27:04 -0000 1.77
+++ config/pa/tm-hppa.h 17 Nov 2004 23:37:57 -0000
@@ -28,9 +28,3 @@
extern int hppa_pc_requires_run_before_use (CORE_ADDR pc);
#define DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE(pc) hppa_pc_requires_run_before_use (pc)
-
-/* PA specific macro to see if the current instruction is nullified. */
-#ifndef INSTRUCTION_NULLIFIED
-extern int hppa_instruction_nullified (void);
-#define INSTRUCTION_NULLIFIED hppa_instruction_nullified ()
-#endif
--
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/
^ permalink raw reply [flat|nested] 44+ messages in thread* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-18 0:02 Randolph Chung @ 2004-11-18 14:26 ` Andrew Cagney 2004-11-18 16:21 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-11-18 14:26 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: > Currently only hppa uses this define, but possibly this will be useful > for other architectures which has conditionally nullified instructions > (ia64?) as well. This gets us one step closer to full multiarch > support.. > > Tested on hppa-linux with no regressions. I'm wondering about: # 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 and the commented out code: /* If PC is pointing at a nullified instruction, then step beyond it so that the user won't be confused when GDB appears to be ready to execute it. */ /* if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */ I suspect that at one stage it was behaving like single_step_through_delay, but was then changed to perform the same operation unconditionally (i.e., when stopping from a cntrl-c say). GDB trying to helpfully do a few extra steps after a cntrl-c bugs me :-) Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-18 14:26 ` Andrew Cagney @ 2004-11-18 16:21 ` Randolph Chung 2004-11-18 16:56 ` Mark Kettenis 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-11-18 16:21 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > I'm wondering about: > > # 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 I was too, but actually this seems to do something slightly different. single_step_through_delay seems to be asking: "does the current instruction have a delay slot"? This is used to tell gdb that if we wanted to do a step on a branch-insn-with-a-delay-slot, then after we step through the branch insn, we will step one more insn. Is that correct? The comment is confusing because it talks about "executing a delay slot" but at least mips-tdep.c, the only implementation of this method, doesn't test that. It tests "executing a branch insn with a delay slot". The new method i'm adding is a bit different though. The PA has a concept of "nullified" instructions. Based on the result of a previous instruction (which may or may not be a branch insn), the next instruction may be nullified. This is in many ways the precursor to the highly predicated insn model of IA64. By examining the insn at pc (or previous pc) you cannot tell whether the current insn is nullified. You can only tell that by examining processor flags. (Possibly on ia64 you would extract the predicate register from the current insn and examine the contents of that predicate register. I haven't looked at the details.) > I suspect that at one stage it was behaving like > single_step_through_delay, but was then changed to perform the same > operation unconditionally (i.e., when stopping from a cntrl-c say). GDB > trying to helpfully do a few extra steps after a cntrl-c bugs me :-) i was trying to figure out that piece of commented out code too and why it was changed. looked through cvs history but didn't find it. I'm not particularly fond of introducing new almost-arch-specific gdbarch methods either, but this does seem to be doing slightly different things than the existing ones. OTOH this is almost a "cosmetic" feature, so one alternative is to drop the INSTRUCTION_NULLIFIED logic completely.... randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-18 16:21 ` Randolph Chung @ 2004-11-18 16:56 ` Mark Kettenis 2004-11-19 9:25 ` Orjan Friberg 2004-11-23 17:50 ` Randolph Chung 0 siblings, 2 replies; 44+ messages in thread From: Mark Kettenis @ 2004-11-18 16:56 UTC (permalink / raw) To: randolph; +Cc: cagney, gdb-patches Date: Thu, 18 Nov 2004 08:21:08 -0800 From: Randolph Chung <randolph@tausq.org> > I'm wondering about: > > # 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 I was too, but actually this seems to do something slightly different. single_step_through_delay seems to be asking: "does the current instruction have a delay slot"? This is used to tell gdb that if we wanted to do a step on a branch-insn-with-a-delay-slot, then after we step through the branch insn, we will step one more insn. Is that correct? I think the description is misleading. The comment is confusing because it talks about "executing a delay slot" but at least mips-tdep.c, the only implementation of this method, doesn't test that. It tests "executing a branch insn with a delay slot". The problem on MIPS is that if you trap on a delay slot, the processor backs up the PC to the preceding branch instruction. As a result, naively single-stepping will re-execute the branch instruction again and again. Therefore, operating systems and GDB's software single-stepping machinery will step over the delay slot, effectively executing two instructions in a row instead of one. Now if there would be a breakpoint-instruction in the delay slot, this won't work. That's why we had the STEP_SKIPS_DELAY macro that makes sure the single-step is done without any breakpoints inserted. This was replaced by single_step_through_delay which presumably will also be used on a new CRISv32 port. Another problem is when there is a breakpoint in the delay slot. Hitting it would thoroughly confuse GDB since after hitting the breakpoint instruction the PC will not point at the breakpoint, but at the branch instruction. Continuing from that point will hit the breakpoint again and again. I'm not sure the current code handles this correctly. i was trying to figure out that piece of commented out code too and why it was changed. looked through cvs history but didn't find it. I'm not particularly fond of introducing new almost-arch-specific gdbarch methods either, but this does seem to be doing slightly different things than the existing ones. OTOH this is almost a "cosmetic" feature, so one alternative is to drop the INSTRUCTION_NULLIFIED logic completely.... Perhaps that isn't such a bad idea if it doesn't confuse GDB too much. Mark ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-18 16:56 ` Mark Kettenis @ 2004-11-19 9:25 ` Orjan Friberg 2004-11-23 17:50 ` Randolph Chung 1 sibling, 0 replies; 44+ messages in thread From: Orjan Friberg @ 2004-11-19 9:25 UTC (permalink / raw) To: Mark Kettenis; +Cc: randolph, cagney, gdb-patches Mark Kettenis wrote: > That's why we had the STEP_SKIPS_DELAY macro that makes sure the > single-step is done without any breakpoints inserted. This was > replaced by single_step_through_delay which presumably will also be > used on a new CRISv32 port. Yes, CRISv32 basically has the MIPS situation in reverse: if you single-step into a delay slot (belonging to a branch instruction) and single-step again, the branch instruction will be re-executed. As a consequence, if there is a breakpoint at the branch instruction itself, we need to step again before re-inserting it (otherwise we'd just hit it again). (I like to think of single_step_through_delay as "did we just step into a situation where we need to step again".) -- Orjan Friberg Axis Communications ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-18 16:56 ` Mark Kettenis 2004-11-19 9:25 ` Orjan Friberg @ 2004-11-23 17:50 ` Randolph Chung 2004-11-23 19:33 ` Mark Kettenis 2004-11-28 17:26 ` Andrew Cagney 1 sibling, 2 replies; 44+ messages in thread From: Randolph Chung @ 2004-11-23 17:50 UTC (permalink / raw) To: Mark Kettenis; +Cc: cagney, gdb-patches > i was trying to figure out that piece of commented out code too and why > it was changed. looked through cvs history but didn't find it. I'm not > particularly fond of introducing new almost-arch-specific gdbarch > methods either, but this does seem to be doing slightly different things > than the existing ones. OTOH this is almost a "cosmetic" feature, so one > alternative is to drop the INSTRUCTION_NULLIFIED logic completely.... > > Perhaps that isn't such a bad idea if it doesn't confuse GDB too much. i did some more investigations.... turns out this is not a cosmetic piece of code at all :) suppose we have a function that ended with a branch-with-nullify-next instruction back to the caller. if you did a "step" on the branch, and we don't skip the nullified instruction, we would end up on the nullified instruction which actually belongs to the next function. for example: Dump of assembler code for function call_with_trampolines: 0x0001217c <call_with_trampolines+0>: copy r3,r1 0x00012180 <call_with_trampolines+4>: copy sp,r3 0x00012184 <call_with_trampolines+8>: stw,ma r1,40(,sp) 0x00012188 <call_with_trampolines+12>: ldi -28,r19 0x0001218c <call_with_trampolines+16>: fstd fr5,r19(,r3) 0x00012190 <call_with_trampolines+20>: ldi -28,r19 0x00012194 <call_with_trampolines+24>: fldd r19(,r3),fr22 0x00012198 <call_with_trampolines+28>: fcpy,dbl fr22,fr4 0x0001219c <call_with_trampolines+32>: ldo 40(r3),sp 0x000121a0 <call_with_trampolines+36>: ldw,mb -40(,sp),r3 0x000121a4 <call_with_trampolines+40>: bv,n r0(rp) End of assembler dump. (gdb) disassemble 0x121a8 Dump of assembler code for function marker_indirect_call: 0x000121a8 <marker_indirect_call+0>: copy r3,r1 0x000121ac <marker_indirect_call+4>: copy sp,r3 0x000121b0 <marker_indirect_call+8>: stw,ma r1,40(,sp) 0x000121b4 <marker_indirect_call+12>: ldo 40(r3),sp 0x000121b8 <marker_indirect_call+16>: ldw,mb -40(,sp),r3 0x000121bc <marker_indirect_call+20>: bv,n r0(rp) if we are at 0x121a4, and we do a step, it will stop at "marker_indirect_call" instead of back at the caller of "call_with_trampolines". since the insn at 0x121a8 is not actually executed in this call sequence, the correct thing to do is to blindly step past the nullified instruction before we make any decision on what to do. here's an updated patch to multiarch INSTRUCTION_NULLIFIED, with updated comments and a somewhat cleaner interface. comments? ok to check in? 2004-11-23 Randolph Chung <tausq@debian.org> * arch-utils.c (generic_instruction_nullified): New. * arch-utils.h (generic_instruction_nullified): New. * gdbarch.sh (instruction_nullified): New method. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * infrun.c (INSTRUCTION_NULLIFIED): Delete. (handle_inferior_event): Replace INSTRUCTION_NULLIFIED with calls to new gdbarch method. * config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Delete definition. * hppa-tdep.c (hppa_instruction_nullified): Remove prototype and make static. Rewrite to work directly off the passed regcache. (hppa_gdbarch_init): Set instruction_nullified method. Index: arch-utils.c =================================================================== RCS file: /cvs/src/src/gdb/arch-utils.c,v retrieving revision 1.123 diff -u -p -r1.123 arch-utils.c --- arch-utils.c 31 Oct 2004 21:42:32 -0000 1.123 +++ arch-utils.c 23 Nov 2004 17:36:09 -0000 @@ -325,6 +325,13 @@ default_stabs_argument_has_addr (struct return 0; } +int +generic_instruction_nullified (struct gdbarch *gdbarch, + struct regcache *regcache) +{ + return 0; +} + \f /* Functions to manipulate the endianness of the target. */ Index: arch-utils.h =================================================================== RCS file: /cvs/src/src/gdb/arch-utils.h,v retrieving revision 1.76 diff -u -p -r1.76 arch-utils.h --- arch-utils.h 31 Oct 2004 21:42:32 -0000 1.76 +++ arch-utils.h 23 Nov 2004 17:36:09 -0000 @@ -117,6 +117,9 @@ extern int generic_convert_register_p (i extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type); +extern int generic_instruction_nullified (struct gdbarch *gdbarch, + struct regcache *regcache); + /* For compatibility with older architectures, returns (LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid name. */ Index: gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.314 diff -u -p -r1.314 gdbarch.c --- gdbarch.c 31 Oct 2004 21:21:41 -0000 1.314 +++ gdbarch.c 23 Nov 2004 17:36:09 -0000 @@ -212,6 +212,7 @@ 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; @@ -338,6 +339,7 @@ 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 */ @@ -435,6 +437,7 @@ 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; @@ -591,6 +594,7 @@ 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 */ @@ -1195,6 +1199,9 @@ 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", @@ -3366,6 +3373,23 @@ 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.275 diff -u -p -r1.275 gdbarch.h --- gdbarch.h 31 Oct 2004 21:21:41 -0000 1.275 +++ gdbarch.h 23 Nov 2004 17:36:09 -0000 @@ -1227,6 +1227,16 @@ 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.350 diff -u -p -r1.350 gdbarch.sh --- gdbarch.sh 31 Oct 2004 21:21:41 -0000 1.350 +++ gdbarch.sh 23 Nov 2004 17:36:09 -0000 @@ -614,6 +614,12 @@ 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: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.182 diff -u -p -r1.182 infrun.c --- infrun.c 8 Nov 2004 17:25:23 -0000 1.182 +++ infrun.c 23 Nov 2004 17:36:10 -0000 @@ -163,16 +163,6 @@ static int debug_infrun = 0; #define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0 #endif -/* 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 the user so as to avoid - confusion. */ - -#ifndef INSTRUCTION_NULLIFIED -#define INSTRUCTION_NULLIFIED 0 -#endif - /* We can't step off a permanent breakpoint in the ordinary way, because we can't remove it. Instead, we have to advance the PC to the next instruction. This macro should expand to a pointer to a function that @@ -1741,14 +1731,15 @@ handle_inferior_event (struct execution_ } /* If PC is pointing at a nullified instruction, then step beyond - it so that the user won't be confused when GDB appears to be ready - to execute it. */ + 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 (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */ - if (INSTRUCTION_NULLIFIED) + if (gdbarch_instruction_nullified (current_gdbarch, current_regcache)) { if (debug_infrun) - printf_unfiltered ("infrun: INSTRUCTION_NULLIFIED\n"); + printf_unfiltered ("infrun: instruction nullified\n"); registers_changed (); target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); Index: config/pa/tm-hppa.h =================================================================== RCS file: /cvs/src/src/gdb/config/pa/tm-hppa.h,v retrieving revision 1.77 diff -u -p -r1.77 tm-hppa.h --- config/pa/tm-hppa.h 13 Nov 2004 02:27:04 -0000 1.77 +++ config/pa/tm-hppa.h 23 Nov 2004 17:36:10 -0000 @@ -28,9 +28,3 @@ extern int hppa_pc_requires_run_before_use (CORE_ADDR pc); #define DEPRECATED_PC_REQUIRES_RUN_BEFORE_USE(pc) hppa_pc_requires_run_before_use (pc) - -/* PA specific macro to see if the current instruction is nullified. */ -#ifndef INSTRUCTION_NULLIFIED -extern int hppa_instruction_nullified (void); -#define INSTRUCTION_NULLIFIED hppa_instruction_nullified () -#endif Index: hppa-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-tdep.c,v retrieving revision 1.181 diff -u -p -r1.181 hppa-tdep.c --- hppa-tdep.c 13 Nov 2004 02:15:32 -0000 1.181 +++ hppa-tdep.c 23 Nov 2004 17:43:02 -0000 @@ -71,7 +71,6 @@ const struct objfile_data *hppa_objfile_ /* FIXME: brobecker 2002-11-07: We will likely be able to make the following functions static, once we hppa is partially multiarched. */ int hppa_pc_requires_run_before_use (CORE_ADDR pc); -int hppa_instruction_nullified (void); /* Handle 32/64-bit struct return conventions. */ @@ -2292,14 +2291,18 @@ hppa_pc_requires_run_before_use (CORE_AD return (!target_has_stack && (pc & 0xFF000000)); } -int -hppa_instruction_nullified (void) +static int +hppa_instruction_nullified (struct gdbarch *gdbarch, struct regcache *regcache) { - /* brobecker 2002/11/07: Couldn't we use a ULONGEST here? It would - avoid the type cast. I'm leaving it as is for now as I'm doing - semi-mechanical multiarching-related changes. */ - const int ipsw = (int) read_register (HPPA_IPSW_REGNUM); - const int flags = (int) read_register (HPPA_FLAGS_REGNUM); + 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)); } @@ -2570,6 +2573,7 @@ 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); -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-23 17:50 ` Randolph Chung @ 2004-11-23 19:33 ` Mark Kettenis 2004-11-28 17:26 ` Andrew Cagney 1 sibling, 0 replies; 44+ messages in thread From: Mark Kettenis @ 2004-11-23 19:33 UTC (permalink / raw) To: randolph; +Cc: cagney, gdb-patches Date: Tue, 23 Nov 2004 09:49:37 -0800 From: Randolph Chung <randolph@tausq.org> i did some more investigations.... turns out this is not a cosmetic piece of code at all :) suppose we have a function that ended with a branch-with-nullify-next instruction back to the caller. if you did a "step" on the branch, and we don't skip the nullified instruction, we would end up on the nullified instruction which actually belongs to the next function. comments? ok to check in? OK, if you make sure you wrap the lines that are too long. Mark 2004-11-23 Randolph Chung <tausq@debian.org> * arch-utils.c (generic_instruction_nullified): New. * arch-utils.h (generic_instruction_nullified): New. * gdbarch.sh (instruction_nullified): New method. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * infrun.c (INSTRUCTION_NULLIFIED): Delete. (handle_inferior_event): Replace INSTRUCTION_NULLIFIED with calls to new gdbarch method. * config/pa/tm-hppa.h (INSTRUCTION_NULLIFIED): Delete definition. * hppa-tdep.c (hppa_instruction_nullified): Remove prototype and make static. Rewrite to work directly off the passed regcache. (hppa_gdbarch_init): Set instruction_nullified method. ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-23 17:50 ` Randolph Chung 2004-11-23 19:33 ` Mark Kettenis @ 2004-11-28 17:26 ` Andrew Cagney 2004-11-28 18:41 ` Randolph Chung 1 sibling, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-11-28 17:26 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >> i was trying to figure out that piece of commented out code too and why >> it was changed. looked through cvs history but didn't find it. I'm not >> particularly fond of introducing new almost-arch-specific gdbarch >> methods either, but this does seem to be doing slightly different things >> than the existing ones. OTOH this is almost a "cosmetic" feature, so one >> alternative is to drop the INSTRUCTION_NULLIFIED logic completely.... >> >>Perhaps that isn't such a bad idea if it doesn't confuse GDB too much. > > > i did some more investigations.... turns out this is not a cosmetic > piece of code at all :) > > suppose we have a function that ended with a branch-with-nullify-next > instruction back to the caller. if you did a "step" on the branch, and > we don't skip the nullified instruction, we would end up on the > nullified instruction which actually belongs to the next function. > > for example: > > Dump of assembler code for function call_with_trampolines: > 0x0001217c <call_with_trampolines+0>: copy r3,r1 > 0x00012180 <call_with_trampolines+4>: copy sp,r3 > 0x00012184 <call_with_trampolines+8>: stw,ma r1,40(,sp) > 0x00012188 <call_with_trampolines+12>: ldi -28,r19 > 0x0001218c <call_with_trampolines+16>: fstd fr5,r19(,r3) > 0x00012190 <call_with_trampolines+20>: ldi -28,r19 > 0x00012194 <call_with_trampolines+24>: fldd r19(,r3),fr22 > 0x00012198 <call_with_trampolines+28>: fcpy,dbl fr22,fr4 > 0x0001219c <call_with_trampolines+32>: ldo 40(r3),sp > 0x000121a0 <call_with_trampolines+36>: ldw,mb -40(,sp),r3 > 0x000121a4 <call_with_trampolines+40>: bv,n r0(rp) > End of assembler dump. > (gdb) disassemble 0x121a8 > Dump of assembler code for function marker_indirect_call: > 0x000121a8 <marker_indirect_call+0>: copy r3,r1 > 0x000121ac <marker_indirect_call+4>: copy sp,r3 > 0x000121b0 <marker_indirect_call+8>: stw,ma r1,40(,sp) > 0x000121b4 <marker_indirect_call+12>: ldo 40(r3),sp > 0x000121b8 <marker_indirect_call+16>: ldw,mb -40(,sp),r3 > 0x000121bc <marker_indirect_call+20>: bv,n r0(rp) > > if we are at 0x121a4, and we do a step, it will stop at > "marker_indirect_call" instead of back at the caller of > "call_with_trampolines". since the insn at 0x121a8 is not actually > executed in this call sequence, the correct thing to do is to blindly > step past the nullified instruction before we make any decision on what > to do. > > here's an updated patch to multiarch INSTRUCTION_NULLIFIED, with updated > comments and a somewhat cleaner interface. > > comments? ok to check in? I'm still not convinced (it's me and not mark you need to convince here ;-). Is it possible to create a core file with the PC sitting on the nullified instruction, and if such a beast is created, how can GDB correctly handle it - GDB clearly can't single step the core file. If that problem is solved, this method becomes redundant. Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-28 17:26 ` Andrew Cagney @ 2004-11-28 18:41 ` Randolph Chung 2004-11-28 19:55 ` Andrew Cagney 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-11-28 18:41 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > Is it possible to create a core file with the PC sitting on the > nullified instruction, and if such a beast is created, how can GDB > correctly handle it - GDB clearly can't single step the core file. If > that problem is solved, this method becomes redundant. what do you mean? this fix is in the handling of inferior events, so it doesn't apply to core files anyway, right? what case with core files do you think needs to be correctly handled? randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-28 18:41 ` Randolph Chung @ 2004-11-28 19:55 ` Andrew Cagney 2004-11-29 3:30 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-11-28 19:55 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >>Is it possible to create a core file with the PC sitting on the >>nullified instruction, and if such a beast is created, how can GDB >>correctly handle it - GDB clearly can't single step the core file. If >>that problem is solved, this method becomes redundant. > > > what do you mean? this fix is in the handling of inferior events, so > it doesn't apply to core files anyway, right? Right. > what case with core files > do you think needs to be correctly handled? The underlying problem that you described: > i did some more investigations.... turns out this is not a cosmetic > piece of code at all :) > > suppose we have a function that ended with a branch-with-nullify-next > instruction back to the caller. if you did a "step" on the branch, and > we don't skip the nullified instruction, we would end up on the > nullified instruction which actually belongs to the next function. > > for example: > > Dump of assembler code for function call_with_trampolines: > 0x0001217c <call_with_trampolines+0>: copy r3,r1 > 0x00012180 <call_with_trampolines+4>: copy sp,r3 > 0x00012184 <call_with_trampolines+8>: stw,ma r1,40(,sp) > 0x00012188 <call_with_trampolines+12>: ldi -28,r19 > 0x0001218c <call_with_trampolines+16>: fstd fr5,r19(,r3) > 0x00012190 <call_with_trampolines+20>: ldi -28,r19 > 0x00012194 <call_with_trampolines+24>: fldd r19(,r3),fr22 > 0x00012198 <call_with_trampolines+28>: fcpy,dbl fr22,fr4 > 0x0001219c <call_with_trampolines+32>: ldo 40(r3),sp > 0x000121a0 <call_with_trampolines+36>: ldw,mb -40(,sp),r3 > 0x000121a4 <call_with_trampolines+40>: bv,n r0(rp) > End of assembler dump. > (gdb) disassemble 0x121a8 > Dump of assembler code for function marker_indirect_call: > 0x000121a8 <marker_indirect_call+0>: copy r3,r1 > 0x000121ac <marker_indirect_call+4>: copy sp,r3 > 0x000121b0 <marker_indirect_call+8>: stw,ma r1,40(,sp) > 0x000121b4 <marker_indirect_call+12>: ldo 40(r3),sp > 0x000121b8 <marker_indirect_call+16>: ldw,mb -40(,sp),r3 > 0x000121bc <marker_indirect_call+20>: bv,n r0(rp) > > if we are at 0x121a4, and we do a step, it will stop at > "marker_indirect_call" instead of back at the caller of > "call_with_trampolines". since the insn at 0x121a8 is not actually > executed in this call sequence, the correct thing to do is to blindly > step past the nullified instruction before we make any decision on what > to do. If, when resuming the inferior, a double step is required, single_step_through_delay will do the job. However, that doesn't solve the case of GDB encountering a frame (inferior) that, be it through attach, cntrl-c, a signal, or a core file, is already sitting on the above nullified instruction. The corefile case being expecially nasty - trying to get a corefile to step off a nullified instruction won't get you very far :-). I suspect that the code will need to modify ``pc'' so that it either appears to be one instruction behind (the "bv,n") or one instruction ahead (branch destination) of what the registers indicate. It might also be useful to check the SPARC. It has PC/NPC, delay slots, and instruction nullification, so I'd expect similar problems. Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-28 19:55 ` Andrew Cagney @ 2004-11-29 3:30 ` Randolph Chung 2004-11-29 15:12 ` Andrew Cagney 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-11-29 3:30 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > If, when resuming the inferior, a double step is required, > single_step_through_delay will do the job. this is not possible to do in the general case though, because, sitting on the current insn at pc, you cannot necessarily determine if the next insn will be nullified or not. (in the current example, the nullification is always applied, but it can be conditional on some computation being done) > However, that doesn't solve the case of GDB encountering a frame > (inferior) that, be it through attach, cntrl-c, a signal, or a core > file, is already sitting on the above nullified instruction. The > corefile case being expecially nasty - trying to get a corefile to step > off a nullified instruction won't get you very far :-). I suspect that > the code will need to modify ``pc'' so that it either appears to be one > instruction behind (the "bv,n") or one instruction ahead (branch > destination) of what the registers indicate. oh, are you saying that: if we are looking at a corefile, and the current pc is sitting on a nullified insn that belonged to the next function, that we may not be able to do a backtrace correctly? > It might also be useful to check the SPARC. It has PC/NPC, delay slots, > and instruction nullification, so I'd expect similar problems. ok, i'll see if i can find a sparc machine to try to reproduce this problem there. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-29 3:30 ` Randolph Chung @ 2004-11-29 15:12 ` Andrew Cagney 2004-11-30 6:56 ` Randolph Chung 2004-12-01 6:19 ` Randolph Chung 0 siblings, 2 replies; 44+ messages in thread From: Andrew Cagney @ 2004-11-29 15:12 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >>If, when resuming the inferior, a double step is required, >>single_step_through_delay will do the job. > > > this is not possible to do in the general case though, because, sitting > on the current insn at pc, you cannot necessarily determine if the > next insn will be nullified or not. (in the current example, the > nullification is always applied, but it can be conditional on some > computation being done) I'm not sure what you mean. What you describe sounds like the old STEP_SKIPS_DELAY logic - a test on the _next_ instruction. The new logic instead: # 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 checks to see if the _last_ instruction put us into a delay slot. (The MIPS code, which is technically implementing STEP_SKIPS_DELAY, works because when in a delay slot the PC still points at the branch instruction. A fixme would be to change the mips code to instead test the delay-slot bit.). >>However, that doesn't solve the case of GDB encountering a frame >>(inferior) that, be it through attach, cntrl-c, a signal, or a core >>file, is already sitting on the above nullified instruction. The >>corefile case being expecially nasty - trying to get a corefile to step >>off a nullified instruction won't get you very far :-). I suspect that >>the code will need to modify ``pc'' so that it either appears to be one >>instruction behind (the "bv,n") or one instruction ahead (branch >>destination) of what the registers indicate. > > > oh, are you saying that: > if we are looking at a corefile, and the current pc is sitting on a > nullified insn that belonged to the next function, that we may not be > able to do a backtrace correctly? Yes, and more to the point INSTRUCTION_NULLIFIED can't help here. On the other hand, if this case is made to work INSTRUCTION_NULLIFIED is redundant. However, the first question is: can such a corefile be created? Given that GDB can single step an inferior into such a state, I think it can. >>It might also be useful to check the SPARC. It has PC/NPC, delay slots, >>and instruction nullification, so I'd expect similar problems. > > > ok, i'll see if i can find a sparc machine to try to reproduce this > problem there. One thing to check is for isif the SPARC requires padding between functions? -- If you want, add a DEPRECATED_INSTRUCTION_NULLIFIED to the architecture vector and have the PA-RISC use that. While a sideways step, it lets you advance what I'm assuming is the more immediate objective of cleaning out PA's tm*.h files and making it pure multi-arch. Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-29 15:12 ` Andrew Cagney @ 2004-11-30 6:56 ` Randolph Chung 2004-11-30 14:51 ` Andrew Cagney 2004-12-01 6:19 ` Randolph Chung 1 sibling, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-11-30 6:56 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > If you want, add a DEPRECATED_INSTRUCTION_NULLIFIED to the architecture > vector and have the PA-RISC use that. While a sideways step, it lets > you advance what I'm assuming is the more immediate objective of > cleaning out PA's tm*.h files and making it pure multi-arch. well, based on Mark's earlier ok i had checked in the instruction_nullified stuff already. since this doesn't seem to be ok, let me try to fix this properly and see what happens. we are pretty close to getting rid of tm-hppa.h..... but the last one(s) are always the trickiest :) randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-30 6:56 ` Randolph Chung @ 2004-11-30 14:51 ` Andrew Cagney 2004-11-30 16:44 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-11-30 14:51 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >>If you want, add a DEPRECATED_INSTRUCTION_NULLIFIED to the architecture >>vector and have the PA-RISC use that. While a sideways step, it lets >>you advance what I'm assuming is the more immediate objective of >>cleaning out PA's tm*.h files and making it pure multi-arch. > > > well, based on Mark's earlier ok i had checked in the > instruction_nullified stuff already. since this doesn't seem to be ok, > let me try to fix this properly and see what happens. I don't know why Mark did that, this one is certainly ``tricky'' :-) Just rename it. > we are pretty close to getting rid of tm-hppa.h..... but the last one(s) > are always the trickiest :) I know, there's a tradeoff. Hence my suggestion - add it but deprecated so that we know it has to be revisited later (and more importantly other architectures don't try to adopt it :-). Looking over whats remaining, the tricky one looks to be REALTIME.{LO,HI}. Thanks, Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-30 14:51 ` Andrew Cagney @ 2004-11-30 16:44 ` Randolph Chung 2004-11-30 16:59 ` Andrew Cagney 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-11-30 16:44 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches In reference to a message from Andrew Cagney, dated Nov 30: > Randolph Chung wrote: > >>If you want, add a DEPRECATED_INSTRUCTION_NULLIFIED to the architecture > >>vector and have the PA-RISC use that. While a sideways step, it lets > >>you advance what I'm assuming is the more immediate objective of > >>cleaning out PA's tm*.h files and making it pure multi-arch. > > > > > >well, based on Mark's earlier ok i had checked in the > >instruction_nullified stuff already. since this doesn't seem to be ok, > >let me try to fix this properly and see what happens. > > I don't know why Mark did that, this one is certainly ``tricky'' :-) > Just rename it. well, first i want to understand the problem. because i'm still not yet 100% convinced that step_through_delay will work. simply using the "instruction_nullified" method in hppa-tdep as the "step_through_delay" method certainly is not working... randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-30 16:44 ` Randolph Chung @ 2004-11-30 16:59 ` Andrew Cagney 2004-11-30 17:38 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-11-30 16:59 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: > well, first i want to understand the problem. because i'm still not > yet 100% convinced that step_through_delay will work. simply using the > "instruction_nullified" method in hppa-tdep as the "step_through_delay" > method certainly is not working... When doing a stepi? step_through_delay certainly won't help when it comes to doing a backtrace from the nullified instruction. Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-30 16:59 ` Andrew Cagney @ 2004-11-30 17:38 ` Randolph Chung 2004-12-01 21:29 ` Andrew Cagney 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-11-30 17:38 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > >well, first i want to understand the problem. because i'm still not > >yet 100% convinced that step_through_delay will work. simply using the > >"instruction_nullified" method in hppa-tdep as the "step_through_delay" > >method certainly is not working... > > When doing a stepi? step_through_delay certainly won't help when it > comes to doing a backtrace from the nullified instruction. when doing a step. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-30 17:38 ` Randolph Chung @ 2004-12-01 21:29 ` Andrew Cagney 2004-12-01 22:33 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-12-01 21:29 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >>>well, first i want to understand the problem. because i'm still not >>>yet 100% convinced that step_through_delay will work. simply using the >>>"instruction_nullified" method in hppa-tdep as the "step_through_delay" >>>method certainly is not working... >> >>When doing a stepi? step_through_delay certainly won't help when it >>comes to doing a backtrace from the nullified instruction. > > > when doing a step. I was thinking that STEPI might be easier to debug :-) 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 it should fool GDB into thinking that it's one instruction ahead of itself. Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 21:29 ` Andrew Cagney @ 2004-12-01 22:33 ` Randolph Chung 2004-12-01 23:32 ` Andrew Cagney 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-01 22:33 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > 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 <tausq@debian.org> * 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/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 22:33 ` Randolph Chung @ 2004-12-01 23:32 ` Andrew Cagney 2004-12-02 5:24 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Andrew Cagney @ 2004-12-01 23:32 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >>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. > @@ -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; > } On the SPARC architecture you can do things like: branch foo branch bar which leads to more warped combinations such as (assuming I've got my diagram right): f+0: branch x+c f+4: branch x+8 x+0: branch e+4 x+4: branch e+0 x+8: branch x+0 x+c: branch,annulled x+4 and I'm fairly sure that results in: f+0 f+4 [x+c] f+4 x+c [x+8] x+c --- [x+4] --- x+4 [x+8] <-------- {npc+4} x+4 x+8 [e+0] x+8 e+0 [x+0] e+0 x+0 .... and hence the ``---'' anulled instruction at x+8 has a prev-pc of x+c (pc+4) and not x+4 (pc-4). This is why I was thinking that next-pc is better (but the above could be wrong - my sparc is very very rusty :-(). Either way, yes ok (and thanks!) Andrew PS: No it's not a hack, XXX_pc projects the hardware onto an idealized machine, there are always perverse edge cases. PPS: A gdb.arch/ addition to tickle the basic edge case would be a helpful way of capturing this knowledge. ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 23:32 ` Andrew Cagney @ 2004-12-02 5:24 ` Randolph Chung 2004-12-02 14:27 ` Daniel Jacobowitz 2004-12-03 18:11 ` Andrew Cagney 0 siblings, 2 replies; 44+ messages in thread From: Randolph Chung @ 2004-12-02 5:24 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > PPS: A gdb.arch/ addition to tickle the basic edge case would be a > helpful way of capturing this knowledge. how about this... my first gdb testcase, so hopefully i didn't do anything too wrong :) 74 PASSes, 3 FAILs with the old code (assuming the instruction_nullified logic is removed). 77 PASSes with my previous patch. randolph 2004-12-01 Randolph Chung <tausq@debian.org> * gdb.arch/pa-nullify.exp: New file. * gdb.arch/pa-nullify.c: New file. --- /dev/null 2004-08-25 14:59:25.000000000 -0700 +++ pa-nullify.exp 2004-12-01 21:21:13.451861856 -0800 @@ -0,0 +1,217 @@ +# Copyright 2004 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# This file is part of the gdb testsuite. + +# NOTE: this test is specific to how gcc generates code. In particular, we +# are testing for the case where the last insn of a function is a "bv,n r0(%rp)" +# and the insn in the delay slot of that branch belongs to the next function. + +if $tracelevel { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +# Test handling of nullified instructions for the pa target. + +if ![istarget "hppa*-*-*"] then { + verbose "Skipping hppa nullification tests." + return +} + +set testfile "pa-nullify" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +set gcorefile ${objdir}/${subdir}/${testfile}.gcore + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + unsupported "Testcase compile failed." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# In the first test, we do a "step" on a function whose last instruction +# contains a branch-with-nullify. The instruction in the delay slot belongs +# to the next function. We verify that when we step off the first function +# that we end up back at the caller and not at the second instruction. + +gdb_breakpoint foo +gdb_test "run" ".*Breakpoint 1, foo \\(x=1\\).*" "Breakpoint at foo" +gdb_test "step" ".*main \\(.*\\) at .*pa-nullify.c:30.*" "step back to main" + +# In the second test, we do a single step through each instruction of a function +# and verify that we get a proper backtrace, even when we are in a nullified +# instruction that belongs to the next function. We also verify that when +# stepping over a branch-with-nullify insn that we stay on the same insn for +# two steps. + +if { ! [ runto main ] } then { gdb_suppress_tests; } + +send_gdb "print foo\n" +gdb_expect { + -re ".* = {int \\(int\\)} ($hex) <foo>.*$gdb_prompt $" { + set baddr $expect_out(1,string) + verbose "Breakpoint address at $baddr" + pass "print foo = $baddr" + } + default { + fail "print foo" + gdb_suppress_tests + } timeout { + fail "cannot get address of foo (timed out)." + gdb_suppress_tests + } +} + +gdb_breakpoint "*$baddr" + +gdb_test "display /i \$pc" "1: x/i +\\\$pc.*" "display /i \$pc" +gdb_test "continue" ".*Breakpoint \[0-9\], foo \\(x=1\\) at .*pa-nullify.c:23.*" "break at first insn of foo" + +set done 0 +set iter 0 +while { $done == 0 && $iter < 20 } { + send_gdb "backtrace\n" + gdb_expect { + -re ".*foo \\(x=.*\\).* main \\(.*\\).*$gdb_prompt $" { + pass "backtrace from foo" + } + -re "$gdb_prompt $" { + fail "backtrace from foo" + gdb_suppress_tests + } + timeout { + fail "(timeout) backtrace from foo" + gdb_suppress_tests + } + } + + send_gdb "stepi\n" + gdb_expect { + -re ".*: x/i +\\\$pc.*:\[ \t\]+(.*)\r.*$gdb_prompt $" { + set insn $expect_out(1,string) + pass "x/i \$pc = $insn" + } timeout { + fail "(timeout) x/i \$pc" + gdb_suppress_tests + break + } + } + + incr iter + + if { $insn == "bv,n r0(rp)" } { + pass "found bv,n insn" + set done 1 + } +} + +send_gdb "stepi\n" +gdb_expect { + -re ".*bv,n r0\\(rp\\)\r.*$gdb_prompt $" { + pass "restep on nullified instruction" + } + -re ".*bar.*\r.*x/i.*bar.*\r.*$gdb_prompt $" { + fail "step on nullification instruction ended in next function" + } + timeout { + fail "(timeout) restep on nullified instruction" + } +} +incr iter + +# Lastly, we do a single step through each instruction and generate a core file. +# Then, load the core file and verify that we can get a proper backtrace. + +if ![isnative] then { + verbose "skipping core file tests on non-native configuration" + return +} + +send_gdb "undisplay 1\n" + +proc do_core_test { count } { + global gcorefile + global gdb_prompt + global hex + + if { ! [ runto_main ] } then { gdb_suppress_tests; } + + set baddr "0" + send_gdb "print foo\n" + gdb_expect { + -re ".* = {int \\(int\\)} ($hex) <foo>.*$gdb_prompt $" { + set baddr $expect_out(1,string) + verbose "Breakpoint address at $baddr" + pass "print foo = $baddr #$count" + } + default { + fail "print foo #$count" + gdb_suppress_tests + } + timeout { + fail "cannot get address of foo (timed out). #$count" + gdb_suppress_tests + } + } + gdb_breakpoint "*$baddr" + + gdb_test "continue" ".*Breakpoint \[0-9\]*, foo \\(x=1\\) at .*pa-nullify.c:23.*" "break at first insn of foo #$count" + + gdb_test "si $count" + + set gcore_works 0 + set escapedfilename [string_to_regexp $gcorefile] + gdb_test_multiple "gcore $gcorefile" "gcore" { + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass "gcore #$count" + set gcore_works 1 + } + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { + unsupported "gcore" + } + } + + if { $gcore_works } { + gdb_test "core $gcorefile" "Core was generated by.*" \ + "load core file #$count" "A program is being debugged already.*" "y" + + send_gdb "backtrace\n" + gdb_expect { + -re ".*foo \\(x=.*\\).* main \\(.*\\).*$gdb_prompt $" { + pass "backtrace from foo #$count" + } + -re "$gdb_prompt $" { + fail "backtrace from foo #$count" + gdb_suppress_tests + } + timeout { + fail "(timeout) backtrace from foo in gcore #$count" + gdb_suppress_tests + } + } + } +} + +for { set i 1 } { $i <= $iter } {incr i} { + do_core_test $i +} --- /dev/null 2004-08-25 14:59:25.000000000 -0700 +++ pa-nullify.c 2004-12-01 21:19:51.324347136 -0800 @@ -0,0 +1,30 @@ +/* PA nullification test program. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +int foo(int x) +{ return x; } + +void bar(void) { } + +int main(int argc, char **argv) +{ + return foo(argc); +} -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-02 5:24 ` Randolph Chung @ 2004-12-02 14:27 ` Daniel Jacobowitz 2004-12-03 18:11 ` Andrew Cagney 1 sibling, 0 replies; 44+ messages in thread From: Daniel Jacobowitz @ 2004-12-02 14:27 UTC (permalink / raw) To: Randolph Chung; +Cc: Andrew Cagney, gdb-patches On Wed, Dec 01, 2004 at 09:24:18PM -0800, Randolph Chung wrote: > > PPS: A gdb.arch/ addition to tickle the basic edge case would be a > > helpful way of capturing this knowledge. > > how about this... my first gdb testcase, so hopefully i didn't do > anything too wrong :) Can you do this without source-level debugging? Since the test is in gdb.arch, the most robust thing to do would be to write the nullified branch in assembly. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-02 5:24 ` Randolph Chung 2004-12-02 14:27 ` Daniel Jacobowitz @ 2004-12-03 18:11 ` Andrew Cagney 2004-12-03 18:15 ` Randolph Chung 2004-12-03 21:40 ` Randolph Chung 1 sibling, 2 replies; 44+ messages in thread From: Andrew Cagney @ 2004-12-03 18:11 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: >>PPS: A gdb.arch/ addition to tickle the basic edge case would be a >>helpful way of capturing this knowledge. > > > how about this... my first gdb testcase, so hopefully i didn't do > anything too wrong :) > > 74 PASSes, 3 FAILs with the old code (assuming the instruction_nullified > logic is removed). 77 PASSes with my previous patch. > > randolph > > > 2004-12-01 Randolph Chung <tausq@debian.org> > > * gdb.arch/pa-nullify.exp: New file. > * gdb.arch/pa-nullify.c: New file. > +send_gdb "print foo\n" > +gdb_expect { > + -re ".* = {int \\(int\\)} ($hex) <foo>.*$gdb_prompt $" { > + set baddr $expect_out(1,string) > + verbose "Breakpoint address at $baddr" > + pass "print foo = $baddr" > + } > + default { > + fail "print foo" > + gdb_suppress_tests > + } timeout { > + fail "cannot get address of foo (timed out)." > + gdb_suppress_tests > + } > +} I'd use gdb_test_multiple: it's more robust and handles more cases when things go wrong; and we're trying to eliminate the old style (yes, there is no marker to warn you of this, sigh). It should be a drop-in replacement and easy to fix. Anyway, more relevant, and as daniel asked, can it be done in assember? A starting point for that might be the gdb.asm test case which uses assembly source code. Andrew > +gdb_breakpoint "*$baddr" > + > +gdb_test "display /i \$pc" "1: x/i +\\\$pc.*" "display /i \$pc" > +gdb_test "continue" ".*Breakpoint \[0-9\], foo \\(x=1\\) at .*pa-nullify.c:23.*" "break at first insn of foo" > + > +set done 0 > +set iter 0 > +while { $done == 0 && $iter < 20 } { > + send_gdb "backtrace\n" > + gdb_expect { > + -re ".*foo \\(x=.*\\).* main \\(.*\\).*$gdb_prompt $" { > + pass "backtrace from foo" > + } > + -re "$gdb_prompt $" { > + fail "backtrace from foo" > + gdb_suppress_tests > + } > + timeout { > + fail "(timeout) backtrace from foo" > + gdb_suppress_tests > + } > + } > + > + send_gdb "stepi\n" > + gdb_expect { > + -re ".*: x/i +\\\$pc.*:\[ \t\]+(.*)\r.*$gdb_prompt $" { > + set insn $expect_out(1,string) > + pass "x/i \$pc = $insn" > + } timeout { > + fail "(timeout) x/i \$pc" > + gdb_suppress_tests > + break > + } > + } > + > + incr iter > + > + if { $insn == "bv,n r0(rp)" } { > + pass "found bv,n insn" > + set done 1 > + } > +} > + > +send_gdb "stepi\n" > +gdb_expect { > + -re ".*bv,n r0\\(rp\\)\r.*$gdb_prompt $" { > + pass "restep on nullified instruction" > + } > + -re ".*bar.*\r.*x/i.*bar.*\r.*$gdb_prompt $" { > + fail "step on nullification instruction ended in next function" > + } > + timeout { > + fail "(timeout) restep on nullified instruction" > + } > +} > +incr iter > + > +# Lastly, we do a single step through each instruction and generate a core file. > +# Then, load the core file and verify that we can get a proper backtrace. > + > +if ![isnative] then { > + verbose "skipping core file tests on non-native configuration" > + return > +} > + > +send_gdb "undisplay 1\n" > + > +proc do_core_test { count } { > + global gcorefile > + global gdb_prompt > + global hex > + > + if { ! [ runto_main ] } then { gdb_suppress_tests; } > + > + set baddr "0" > + send_gdb "print foo\n" > + gdb_expect { > + -re ".* = {int \\(int\\)} ($hex) <foo>.*$gdb_prompt $" { > + set baddr $expect_out(1,string) > + verbose "Breakpoint address at $baddr" > + pass "print foo = $baddr #$count" > + } > + default { > + fail "print foo #$count" > + gdb_suppress_tests > + } > + timeout { > + fail "cannot get address of foo (timed out). #$count" > + gdb_suppress_tests > + } > + } > + gdb_breakpoint "*$baddr" > + > + gdb_test "continue" ".*Breakpoint \[0-9\]*, foo \\(x=1\\) at .*pa-nullify.c:23.*" "break at first insn of foo #$count" > + > + gdb_test "si $count" > + > + set gcore_works 0 > + set escapedfilename [string_to_regexp $gcorefile] > + gdb_test_multiple "gcore $gcorefile" "gcore" { > + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { > + pass "gcore #$count" > + set gcore_works 1 > + } > + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { > + unsupported "gcore" > + } > + } > + > + if { $gcore_works } { > + gdb_test "core $gcorefile" "Core was generated by.*" \ > + "load core file #$count" "A program is being debugged already.*" "y" > + > + send_gdb "backtrace\n" > + gdb_expect { > + -re ".*foo \\(x=.*\\).* main \\(.*\\).*$gdb_prompt $" { > + pass "backtrace from foo #$count" > + } > + -re "$gdb_prompt $" { > + fail "backtrace from foo #$count" > + gdb_suppress_tests > + } > + timeout { > + fail "(timeout) backtrace from foo in gcore #$count" > + gdb_suppress_tests > + } > + } > + } > +} > + > +for { set i 1 } { $i <= $iter } {incr i} { > + do_core_test $i > +} > --- /dev/null 2004-08-25 14:59:25.000000000 -0700 > +++ pa-nullify.c 2004-12-01 21:19:51.324347136 -0800 > @@ -0,0 +1,30 @@ > +/* PA nullification test program. > + > + Copyright 2004 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place - Suite 330, > + Boston, MA 02111-1307, USA. */ > + > +int foo(int x) > +{ return x; } > + > +void bar(void) { } > + > +int main(int argc, char **argv) > +{ > + return foo(argc); > +} > ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 18:11 ` Andrew Cagney @ 2004-12-03 18:15 ` Randolph Chung 2004-12-03 18:57 ` Daniel Jacobowitz 2004-12-03 21:40 ` Randolph Chung 1 sibling, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-03 18:15 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > Anyway, more relevant, and as daniel asked, can it be done in assember? > A starting point for that might be the gdb.asm test case which uses > assembly source code. i'm working on it, but getting stuck with a weird problem... i'm seeing a case where i do: proc get_addr_of_sym { sym } { set addr 0 global gdb_prompt global expect_out send_gdb "print $sym\n" gdb_expect 60 { -re ".*($hex) <$sym>.*$gdb_prompt $" { set addr $expect_out(1,string) pass "got address of $sym = $addr" } timeout { fail "cannot get address of $sym (timed out)." gdb_suppress_tests } } return $addr } set foo [get_addr_of_sym "foo"] set bar [get_addr_of_sym "bar"] i always get a FAIL on that, and from looking at the log (with --debug) it seems like the gdb_expect is returning immediately without checking for results from the previous send_gdb command.... viz: send: sending "print foo\n" to { exp11 }^M FAIL: gdb.arch/pa-nullify.exp: cannot get address of foo (timed out). send: sending "print bar\n" to { exp11 }^M FAIL: gdb.arch/pa-nullify.exp: cannot get address of bar (timed out). am i doing something obviously wrong? randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 18:15 ` Randolph Chung @ 2004-12-03 18:57 ` Daniel Jacobowitz 2004-12-03 19:57 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Daniel Jacobowitz @ 2004-12-03 18:57 UTC (permalink / raw) To: Randolph Chung; +Cc: Andrew Cagney, gdb-patches On Fri, Dec 03, 2004 at 10:15:05AM -0800, Randolph Chung wrote: > > Anyway, more relevant, and as daniel asked, can it be done in assember? > > A starting point for that might be the gdb.asm test case which uses > > assembly source code. > > i'm working on it, but getting stuck with a weird problem... i'm seeing > a case where i do: > > proc get_addr_of_sym { sym } { > set addr 0 > global gdb_prompt > global expect_out Not sure but I don't think you need to declare expect_out as a global. > send_gdb "print $sym\n" > gdb_expect 60 { > -re ".*($hex) <$sym>.*$gdb_prompt $" { > set addr $expect_out(1,string) > pass "got address of $sym = $addr" > } > timeout { > fail "cannot get address of $sym (timed out)." > gdb_suppress_tests > } > } > > return $addr > } > > set foo [get_addr_of_sym "foo"] > set bar [get_addr_of_sym "bar"] > > i always get a FAIL on that, and from looking at the log (with --debug) > it seems like the gdb_expect is returning immediately without checking > for results from the previous send_gdb command.... > > viz: > send: sending "print foo\n" to { exp11 }^M > FAIL: gdb.arch/pa-nullify.exp: cannot get address of foo (timed out). > send: sending "print bar\n" to { exp11 }^M > FAIL: gdb.arch/pa-nullify.exp: cannot get address of bar (timed out). > > am i doing something obviously wrong? First, as Andrew mentioned, don't use gdb_expect this way. Use gdb_test_multiple. Secondly, there are two possible causes of this. One is a syntax error, in either the regular expression or the code for the matching case. That will invoke the "timeout" handler. The other is that you've gotten out of sync somehow; doesn't look too likely from the above. Try putting "exp_internal 1" in front of it to see what expect thinks it is doing. I just saw the bug: try "global hex" and see if that helps. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 18:57 ` Daniel Jacobowitz @ 2004-12-03 19:57 ` Randolph Chung 0 siblings, 0 replies; 44+ messages in thread From: Randolph Chung @ 2004-12-03 19:57 UTC (permalink / raw) To: Andrew Cagney, gdb-patches > I just saw the bug: try "global hex" and see if that helps. yes, thanks. i hate tcl... randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 18:11 ` Andrew Cagney 2004-12-03 18:15 ` Randolph Chung @ 2004-12-03 21:40 ` Randolph Chung 2004-12-03 21:58 ` Andrew Cagney 1 sibling, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-03 21:40 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > Anyway, more relevant, and as daniel asked, can it be done in assember? > A starting point for that might be the gdb.asm test case which uses > assembly source code. ok, how about this. it's in asm and it only tests the relevant edge cases... 2004-12-03 Randolph Chung <tausq@debian.org> testsuite/ * gdb.arch/pa-nullify.exp: New file. * gdb.arch/pa-nullify.s: New file. --- /dev/null 2004-08-25 14:59:25.000000000 -0700 +++ pa-nullify.s 2004-12-02 08:40:46.342945888 -0800 @@ -0,0 +1,59 @@ + .LEVEL 1.1 + .text + .align 4 +.globl foo + .type foo, @function +foo: + .PROC + .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 + .ENTRY + copy %r3,%r1 + copy %r30,%r3 + stwm %r1,64(%r30) + stw %r26,-36(%r3) + ldw -36(%r3),%r19 + copy %r19,%r28 + ldo 64(%r3),%r30 + ldwm -64(%r30),%r3 + bv,n %r0(%r2) + .EXIT + .PROCEND + +.globl bar + .type bar, @function +bar: + .PROC + .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 + .ENTRY + copy %r3,%r1 + copy %r30,%r3 + stwm %r1,64(%r30) + ldo 64(%r3),%r30 + ldwm -64(%r30),%r3 + bv,n %r0(%r2) + .EXIT + .PROCEND + +.globl main + .type main, @function +main: + .PROC + .CALLINFO FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3 + .ENTRY + stw %r2,-20(%r30) + copy %r3,%r1 + copy %r30,%r3 + stwm %r1,64(%r30) + stw %r26,-36(%r3) + stw %r25,-40(%r3) + ldw -36(%r3),%r26 + bl foo,%r2 + nop + copy %r28,%r19 + copy %r19,%r28 + ldw -20(%r3),%r2 + ldo 64(%r3),%r30 + ldwm -64(%r30),%r3 + bv,n %r0(%r2) + .EXIT + .PROCEND --- /dev/null 2004-08-25 14:59:25.000000000 -0700 +++ pa-nullify.exp 2004-12-03 12:16:52.044063224 -0800 @@ -0,0 +1,151 @@ +# Copyright 2004 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# This file is part of the gdb testsuite. + +if $tracelevel { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +# Test handling of nullified instructions for the pa target. + +if ![istarget "hppa*-*-*"] then { + verbose "Skipping hppa nullification tests." + return +} + +set testfile "pa-nullify" +set srcfile ${testfile}.s +set binfile ${objdir}/${subdir}/${testfile} +set gcorefile ${objdir}/${subdir}/${testfile}.gcore + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } { + unsupported "Testcase compile failed." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# In the first test, we do a "step" on a function whose last instruction +# contains a branch-with-nullify. The instruction in the delay slot belongs +# to the next function. We verify that when we step off the first function +# that we end up back at the caller and not at the second instruction. + +gdb_breakpoint foo +gdb_test "run" ".*Breakpoint 1, .* in foo.*" "Breakpoint at foo" + +set test "stepi till main" +gdb_test_multiple "stepi" "${test}" { + -re ".*in foo.*$gdb_prompt $" { + send_gdb "stepi\n" + exp_continue -continue_timer + } + -re ".*in bar.*$gdb_prompt $" { + fail "stepped into bar" + } + -re ".*in main.*$gdb_prompt $" { + pass "stepped into main" + } +} + +# In the second test, we verify that we can get a proper backtrace +# even when we are in a nullified instruction that belongs to the next function. +# We also verify that when stepping over a branch-with-nullify insn that we +# stay on the same insn for two steps. + +proc get_addr_of_sym { sym } { + set addr 0 + global gdb_prompt + global hex + + send_gdb "print $sym\n" + gdb_test_multiple "print $sym" "Get address of $sym" { + -re ".*($hex) <$sym>.*$gdb_prompt $" { + set addr $expect_out(1,string) + pass "got address of $sym = $addr" + } + } + + return $addr +} + +if { ! [ runto_main ] } then { gdb_suppress_tests; } + +set foo [get_addr_of_sym "foo"] +set bar [get_addr_of_sym "bar"] +set foo_last [expr $bar - 4] + +gdb_breakpoint "*$foo_last" + +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" +gdb_test "backtrace" ".*in foo.*in main.*" "Backtrace from last insn in foo" +gdb_test "stepi" ".*in foo.*" "stepi to nullified instruction stays in foo" +gdb_test "backtrace" ".*in foo.*in main.*" "Backtrace from nullified insn" +gdb_test "stepi" ".*in main.*" "stepi to main" + +# In the third test, we verify that backtraces from nullified instructions +# work even in coredumps + +proc gen_core { test } { + global gcorefile + global gdb_prompt + set gcore_works 0 + set escapedfilename [string_to_regexp $gcorefile] + + gdb_test_multiple "gcore $gcorefile" "gcore" { + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass "$test: gcore" + set gcore_works 1 + } + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { + unsupported "gcore" + } + } + + return $gcore_works +} + +proc test_core_bt { test } { + global gcorefile + + gdb_test "core $gcorefile" "Core was generated by.*" \ + "$test: load core file" "A program is being debugged already.*" "y" + + gdb_test "backtrace" ".*in foo.*in main.*" "$test: backtrace in gcore" +} + +set test "core at last insn in foo" +if { ! [ runto_main ] } then { gdb_suppress_tests; } +gdb_breakpoint "*$foo_last" +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" +if [gen_core $test] { + test_core_bt $test +} + +set test "core at nullified insn" +if { ! [ runto_main ] } then { gdb_suppress_tests; } +gdb_breakpoint "*$foo_last" +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" +gdb_test "stepi" ".*in foo.*" +if [gen_core $test] { + test_core_bt $test +} ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 21:40 ` Randolph Chung @ 2004-12-03 21:58 ` Andrew Cagney 2004-12-03 22:52 ` Daniel Jacobowitz ` (2 more replies) 0 siblings, 3 replies; 44+ messages in thread From: Andrew Cagney @ 2004-12-03 21:58 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb-patches Randolph Chung wrote: Just some nits, fix that, and assuming daniel doesn't notice anything (for a day or til monday?), commit it. > +gdb_breakpoint foo > +gdb_test "run" ".*Breakpoint 1, .* in foo.*" "Breakpoint at foo" The leading .* in the pattern you've picked up from the existing code isn't actually needed (well at least I'm 99% certain of this as I've been stripping them out my self and it makes things more efficient) (the trailing .*s are needed :-): > + -re ".*in foo.*$gdb_prompt $" { ditto here and for others. Can you strip them out and check things are ok (i'd do it incrementally first :-). > + send_gdb "stepi\n" Good one ... > + exp_continue -continue_timer I can never remember to do this :-( > + } > + -re ".*in bar.*$gdb_prompt $" { > + fail "stepped into bar" The pass / fail messages should all be identical (except perhaps for a fail where a trailing comment in paren can be added). So: fail "$test (stepped into bar)" > + } > + -re ".*in main.*$gdb_prompt $" { > + pass "stepped into main" and just: pass "$test" check for the same problem elsewhere. > + gdb_test_multiple "print $sym" "Get address of $sym" { > + -re ".*($hex) <$sym>.*$gdb_prompt $" { > + set addr $expect_out(1,string) > + pass "got address of $sym = $addr" > + } > + } Remove the address from the test result (I'm always being slapped for doing that one ;-). It can make the comparison of subsequent runs, or runs on different systems, harder. > + return $addr > +} > + > +if { ! [ runto_main ] } then { gdb_suppress_tests; } > + > +set foo [get_addr_of_sym "foo"] > +set bar [get_addr_of_sym "bar"] > +set foo_last [expr $bar - 4] > + > +gdb_breakpoint "*$foo_last" > + > +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" > +gdb_test "backtrace" ".*in foo.*in main.*" "Backtrace from last insn in foo" > +gdb_test "stepi" ".*in foo.*" "stepi to nullified instruction stays in foo" > +gdb_test "backtrace" ".*in foo.*in main.*" "Backtrace from nullified insn" > +gdb_test "stepi" ".*in main.*" "stepi to main" > + > +# In the third test, we verify that backtraces from nullified instructions > +# work even in coredumps > + > +proc gen_core { test } { > + global gcorefile > + global gdb_prompt > + set gcore_works 0 > + set escapedfilename [string_to_regexp $gcorefile] > + > + gdb_test_multiple "gcore $gcorefile" "gcore" { > + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { > + pass "$test: gcore" > + set gcore_works 1 > + } > + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { > + unsupported "gcore" > + } > + } I'd kfail this. Not supporting gcore is a bug. If, on your system, gcore doesn't work then it might be better to steal code from bigcore.exp that uses SIGABRT to generate the core file. Your call though. Anyway, given the follow-on code, I guess it's working for you. Finally, as a quick sanity check, can you take the gdb.sum output from just this test and check it for duplicate test names (sort < gdb.sum | uniq -d). They should be unique. Thanks! Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 21:58 ` Andrew Cagney @ 2004-12-03 22:52 ` Daniel Jacobowitz 2004-12-04 0:00 ` Randolph Chung 2004-12-04 0:55 ` Randolph Chung 2 siblings, 0 replies; 44+ messages in thread From: Daniel Jacobowitz @ 2004-12-03 22:52 UTC (permalink / raw) To: Andrew Cagney; +Cc: Randolph Chung, gdb-patches On Fri, Dec 03, 2004 at 04:09:50PM -0500, Andrew Cagney wrote: > Randolph Chung wrote: > > Just some nits, fix that, and assuming daniel doesn't notice anything > (for a day or til monday?), commit it. > > >+gdb_breakpoint foo > >+gdb_test "run" ".*Breakpoint 1, .* in foo.*" "Breakpoint at foo" > > The leading .* in the pattern you've picked up from the existing code > isn't actually needed (well at least I'm 99% certain of this as I've > been stripping them out my self and it makes things more efficient) (the > trailing .*s are needed :-): That's right. gdb_test_multiple does: return [gdb_test_multiple $command $message { -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" { Hmm, that initial bit is completely pointless... > >+ } > >+ -re ".*in bar.*$gdb_prompt $" { > >+ fail "stepped into bar" > > The pass / fail messages should all be identical (except perhaps for a > fail where a trailing comment in paren can be added). So: > > fail "$test (stepped into bar)" > > >+ } > >+ -re ".*in main.*$gdb_prompt $" { > >+ pass "stepped into main" > > and just: > > pass "$test" > > check for the same problem elsewhere. > > >+ gdb_test_multiple "print $sym" "Get address of $sym" { > >+ -re ".*($hex) <$sym>.*$gdb_prompt $" { > >+ set addr $expect_out(1,string) > >+ pass "got address of $sym = $addr" > >+ } > >+ } > > Remove the address from the test result (I'm always being slapped for > doing that one ;-). It can make the comparison of subsequent runs, or > runs on different systems, harder. [And make the different test name strings match, as earlier.] These were the only problems I saw, too. Fix them and it's OK with me. > I'd kfail this. Not supporting gcore is a bug. Or just fail it for now. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 21:58 ` Andrew Cagney 2004-12-03 22:52 ` Daniel Jacobowitz @ 2004-12-04 0:00 ` Randolph Chung 2004-12-04 0:55 ` Randolph Chung 2 siblings, 0 replies; 44+ messages in thread From: Randolph Chung @ 2004-12-04 0:00 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > I'd kfail this. Not supporting gcore is a bug. > > If, on your system, gcore doesn't work then it might be better to steal > code from bigcore.exp that uses SIGABRT to generate the core file. Your > call though. mmm ok, i'll have to look. gcore doesn't work on hpux i think. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-03 21:58 ` Andrew Cagney 2004-12-03 22:52 ` Daniel Jacobowitz 2004-12-04 0:00 ` Randolph Chung @ 2004-12-04 0:55 ` Randolph Chung 2004-12-04 11:27 ` Mark Kettenis 2 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-04 0:55 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches I've committed the following. randolph 2004-12-03 Randolph Chung <tausq@debian.org> * 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. testsuite/ * gdb.arch/pa-nullify.exp: New file. * gdb.arch/pa-nullify.s: New file. 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 3 Dec 2004 23:57:54 -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 3 Dec 2004 23:57:55 -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 3 Dec 2004 23:57:55 -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 3 Dec 2004 23:57:56 -0000 @@ -1042,6 +1042,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 +1051,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 +2197,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 +2317,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 +2583,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 3 Dec 2004 23:57:58 -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. */ Index: testsuite/gdb.arch/pa-nullify.exp =================================================================== RCS file: testsuite/gdb.arch/pa-nullify.exp diff -N testsuite/gdb.arch/pa-nullify.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.arch/pa-nullify.exp 3 Dec 2004 23:58:01 -0000 @@ -0,0 +1,152 @@ +# Copyright 2004 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# This file is part of the gdb testsuite. + +if $tracelevel { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +# Test handling of nullified instructions for the pa target. + +if ![istarget "hppa*-*-*"] then { + verbose "Skipping hppa nullification tests." + return +} + +set testfile "pa-nullify" +set srcfile ${testfile}.s +set binfile ${objdir}/${subdir}/${testfile} +set gcorefile ${objdir}/${subdir}/${testfile}.gcore + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } { + unsupported "Testcase compile failed." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# In the first test, we do a "step" on a function whose last instruction +# contains a branch-with-nullify. The instruction in the delay slot belongs +# to the next function. We verify that when we step off the first function +# that we end up back at the caller and not at the second instruction. + +gdb_breakpoint foo +gdb_test "run" "Breakpoint 1, .* in foo.*" "Breakpoint at foo" + +set test "stepi till main" +gdb_test_multiple "stepi" "${test}" { + -re ".*in foo.*$gdb_prompt $" { + send_gdb "stepi\n" + exp_continue -continue_timer + } + -re ".*in bar.*$gdb_prompt $" { + fail $test + } + -re ".*in main.*$gdb_prompt $" { + pass $test + } +} + +# In the second test, we verify that we can get a proper backtrace +# even when we are in a nullified instruction that belongs to the next function. +# We also verify that when stepping over a branch-with-nullify insn that we +# stay on the same insn for two steps. + +proc get_addr_of_sym { sym } { + set addr 0 + global gdb_prompt + global hex + + set test "get address of $sym" + send_gdb "print $sym\n" + gdb_test_multiple "print $sym" $test { + -re ".*($hex) <$sym>.*$gdb_prompt $" { + set addr $expect_out(1,string) + pass $test + } + } + + return $addr +} + +if { ! [ runto_main ] } then { gdb_suppress_tests; } + +set foo [get_addr_of_sym "foo"] +set bar [get_addr_of_sym "bar"] +set foo_last [expr $bar - 4] + +gdb_breakpoint "*$foo_last" + +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" +gdb_test "backtrace" "in foo.*in main.*" "Backtrace from last insn in foo" +gdb_test "stepi" "in foo.*" "stepi to nullified instruction stays in foo" +gdb_test "backtrace" "in foo.*in main.*" "Backtrace from nullified insn" +gdb_test "stepi" "in main.*" "stepi to main" + +# In the third test, we verify that backtraces from nullified instructions +# work even in coredumps + +proc gen_core { test } { + global gcorefile + global gdb_prompt + set gcore_works 0 + set escapedfilename [string_to_regexp $gcorefile] + + gdb_test_multiple "gcore $gcorefile" "$test: gcore" { + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass "$test: gcore" + set gcore_works 1 + } + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { + fail "$test: gcore" + } + } + + return $gcore_works +} + +proc test_core_bt { test } { + global gcorefile + + gdb_test "core $gcorefile" "Core was generated by.*" \ + "$test: load core file" "A program is being debugged already.*" "y" + + gdb_test "backtrace" ".*in foo.*in main.*" "$test: backtrace in gcore" +} + +set test "core at last insn in foo" +if { ! [ runto_main ] } then { gdb_suppress_tests; } +gdb_breakpoint "*$foo_last" +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" "$test: continue to breakpoint" +if [gen_core $test] { + test_core_bt $test +} + +set test "core at nullified insn" +if { ! [ runto_main ] } then { gdb_suppress_tests; } +gdb_breakpoint "*$foo_last" +gdb_test "continue" "Breakpoint \[0-9\]*,.* in foo.*" "$test: continue to breakpoint" +gdb_test "stepi" ".*in foo.*" "$test: step to nullified instruction" +if [gen_core $test] { + test_core_bt $test +} Index: testsuite/gdb.arch/pa-nullify.s =================================================================== RCS file: testsuite/gdb.arch/pa-nullify.s diff -N testsuite/gdb.arch/pa-nullify.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.arch/pa-nullify.s 3 Dec 2004 23:58:01 -0000 @@ -0,0 +1,59 @@ + .LEVEL 1.1 + .text + .align 4 +.globl foo + .type foo, @function +foo: + .PROC + .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 + .ENTRY + copy %r3,%r1 + copy %r30,%r3 + stwm %r1,64(%r30) + stw %r26,-36(%r3) + ldw -36(%r3),%r19 + copy %r19,%r28 + ldo 64(%r3),%r30 + ldwm -64(%r30),%r3 + bv,n %r0(%r2) + .EXIT + .PROCEND + +.globl bar + .type bar, @function +bar: + .PROC + .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 + .ENTRY + copy %r3,%r1 + copy %r30,%r3 + stwm %r1,64(%r30) + ldo 64(%r3),%r30 + ldwm -64(%r30),%r3 + bv,n %r0(%r2) + .EXIT + .PROCEND + +.globl main + .type main, @function +main: + .PROC + .CALLINFO FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3 + .ENTRY + stw %r2,-20(%r30) + copy %r3,%r1 + copy %r30,%r3 + stwm %r1,64(%r30) + stw %r26,-36(%r3) + stw %r25,-40(%r3) + ldw -36(%r3),%r26 + bl foo,%r2 + nop + copy %r28,%r19 + copy %r19,%r28 + ldw -20(%r3),%r2 + ldo 64(%r3),%r30 + ldwm -64(%r30),%r3 + bv,n %r0(%r2) + .EXIT + .PROCEND ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-04 0:55 ` Randolph Chung @ 2004-12-04 11:27 ` Mark Kettenis 0 siblings, 0 replies; 44+ messages in thread From: Mark Kettenis @ 2004-12-04 11:27 UTC (permalink / raw) To: randolph; +Cc: cagney, gdb-patches Date: Fri, 3 Dec 2004 16:00:18 -0800 From: Randolph Chung <randolph@tausq.org> I've committed the following. Hmm. There is a bit of an inconsistency with signed/unsigned in the code: 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; Here you declare `ipsw' as ULONGEST (which is unsigned) but then use frame_unwind_register_signed to read it. Also, AFAIK, addresses aren't signed on hppa (or at least aren't sign-extended) so there one should also use frame_unwind_register_unsigned (but that problem was already there). These kind of things might cause problems in certain 32x64-bit situations. Mark ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-11-29 15:12 ` Andrew Cagney 2004-11-30 6:56 ` Randolph Chung @ 2004-12-01 6:19 ` Randolph Chung 2004-12-01 17:11 ` Daniel Jacobowitz 1 sibling, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-01 6:19 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches > >this is not possible to do in the general case though, because, sitting > >on the current insn at pc, you cannot necessarily determine if the > >next insn will be nullified or not. (in the current example, the > >nullification is always applied, but it can be conditional on some > >computation being done) > > I'm not sure what you mean. What you describe sounds like the old > STEP_SKIPS_DELAY logic - a test on the _next_ instruction. The new > logic instead: > > # 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 > > checks to see if the _last_ instruction put us into a delay slot. mmm... maybe i'm not reading the code correctly, but i still don't see how this will work for the hppa case. this predicate is used in two places: in proceed(), this only applies for the first insn at a "continue" or a "step"/"next", right? so in any case it doesn't do anything if you are stepping through a series of instructions and the first one is not a branch/delay slot insn. in handle_inferior_event(), the condition being checked is: if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected && gdbarch_single_step_through_delay_p (current_gdbarch) && currently_stepping (ecs)) trap_expected will not be set when you are doing a "step" with single stepping. possibly this works on mips because it uses software single step? but on hppa we have hardware single step, and as far as i can tell trap_expected is not set as we are stepping through instructions to get to the next line when doing a "step". this condition again seems to be more for the case when you hit a breakpoint at a branch insn with a delay slot and you want to determine how to single step off that branch. in the hppa case we have no breakpoints in this case. i experimented with another proposal which is to adjust the pc when we are at a nullified instruction. i modified target_read_pc () to return the previous (or next) pc when we are at a nullified instruction. this fixes some of the failures but causes new failures with the "recurse.exp" test. i need to investigate that some more. but teaching target_read_pc() to lie about the current pc seems to be suboptimal. lastly a comment about sparc -- i think the sparc case is simpler because it doesn't have conditional nullification. so looking at a particular insn you can always determine if the next insn will be nullified or not. this is not always the case for hppa. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 6:19 ` Randolph Chung @ 2004-12-01 17:11 ` Daniel Jacobowitz 2004-12-01 17:17 ` Randolph Chung 2004-12-01 21:25 ` Andrew Cagney 0 siblings, 2 replies; 44+ messages in thread From: Daniel Jacobowitz @ 2004-12-01 17:11 UTC (permalink / raw) To: Randolph Chung; +Cc: Andrew Cagney, gdb-patches On Tue, Nov 30, 2004 at 10:19:24PM -0800, Randolph Chung wrote: > i experimented with another proposal which is to adjust the pc when we > are at a nullified instruction. i modified target_read_pc () to return > the previous (or next) pc when we are at a nullified instruction. this > fixes some of the failures but causes new failures with the > "recurse.exp" test. i need to investigate that some more. but teaching > target_read_pc() to lie about the current pc seems to be suboptimal. > > lastly a comment about sparc -- i think the sparc case is simpler > because it doesn't have conditional nullification. so looking at a > particular insn you can always determine if the next insn will be > nullified or not. this is not always the case for hppa. Randolph, Here's an off-the-cuff idea for you. Could you actually skip the nullified instruction, if you had a hook in the right place? That is, when a thread stops, if it is stopped at a nullified instruction, forcibly move it to the next instruction before returning control to GDB. This is probably not feasible if you have to use single-stepping to end up in the right place. If you can compute the right place and adjust registers, though, it shouldn't be hard. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:11 ` Daniel Jacobowitz @ 2004-12-01 17:17 ` Randolph Chung 2004-12-01 17:19 ` Daniel Jacobowitz 2004-12-01 21:25 ` Andrew Cagney 1 sibling, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-01 17:17 UTC (permalink / raw) To: Andrew Cagney, gdb-patches > Here's an off-the-cuff idea for you. Could you actually skip the > nullified instruction, if you had a hook in the right place? That is, > when a thread stops, if it is stopped at a nullified instruction, > forcibly move it to the next instruction before returning control to > GDB. this is exactly what the instruction_nullified method that i added do :) randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:17 ` Randolph Chung @ 2004-12-01 17:19 ` Daniel Jacobowitz 2004-12-01 17:25 ` Randolph Chung 0 siblings, 1 reply; 44+ messages in thread From: Daniel Jacobowitz @ 2004-12-01 17:19 UTC (permalink / raw) To: Randolph Chung; +Cc: Andrew Cagney, gdb-patches On Wed, Dec 01, 2004 at 09:17:12AM -0800, Randolph Chung wrote: > > Here's an off-the-cuff idea for you. Could you actually skip the > > nullified instruction, if you had a hook in the right place? That is, > > when a thread stops, if it is stopped at a nullified instruction, > > forcibly move it to the next instruction before returning control to > > GDB. > > this is exactly what the instruction_nullified method that i added do :) Could you do this at the end of the to_wait hook, if I provided a way for the native target to override to_wait? Oh, I guess it's an architecture property, not a target property, so you'd need to do it for remote stubs too. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:19 ` Daniel Jacobowitz @ 2004-12-01 17:25 ` Randolph Chung 2004-12-01 17:28 ` Daniel Jacobowitz 0 siblings, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-01 17:25 UTC (permalink / raw) To: Andrew Cagney, gdb-patches > > this is exactly what the instruction_nullified method that i added do :) > > Could you do this at the end of the to_wait hook, if I provided a way > for the native target to override to_wait? Oh, I guess it's an > architecture property, not a target property, so you'd need to do it > for remote stubs too. probably yes; but why is this better? randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:25 ` Randolph Chung @ 2004-12-01 17:28 ` Daniel Jacobowitz 2004-12-01 17:30 ` Randolph Chung 2004-12-01 17:35 ` Randolph Chung 0 siblings, 2 replies; 44+ messages in thread From: Daniel Jacobowitz @ 2004-12-01 17:28 UTC (permalink / raw) To: Randolph Chung; +Cc: Andrew Cagney, gdb-patches On Wed, Dec 01, 2004 at 09:25:30AM -0800, Randolph Chung wrote: > > > this is exactly what the instruction_nullified method that i added do :) > > > > Could you do this at the end of the to_wait hook, if I provided a way > > for the native target to override to_wait? Oh, I guess it's an > > architecture property, not a target property, so you'd need to do it > > for remote stubs too. > > probably yes; but why is this better? Only better if it allowed to remove all reference to this target-specific problem from core GDB. Which it doesn't sound like it would. How do you detect that an instruction is nullified, or where the next instruction executed will be? Is there a bit in some status register? -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:28 ` Daniel Jacobowitz @ 2004-12-01 17:30 ` Randolph Chung 2004-12-01 17:35 ` Randolph Chung 1 sibling, 0 replies; 44+ messages in thread From: Randolph Chung @ 2004-12-01 17:30 UTC (permalink / raw) To: Andrew Cagney, gdb-patches > How do you detect that an instruction is nullified, or where the next > instruction executed will be? Is there a bit in some status register? yes, there's a bit in the processor status word to tell if the current instruction is nullified. the pa has a 2-level instruction pointer. (in gdb we call them pcoqh and pcoqt). pcoqt is the next instruction to be executed. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:28 ` Daniel Jacobowitz 2004-12-01 17:30 ` Randolph Chung @ 2004-12-01 17:35 ` Randolph Chung 2004-12-01 18:14 ` Randolph Chung 1 sibling, 1 reply; 44+ messages in thread From: Randolph Chung @ 2004-12-01 17:35 UTC (permalink / raw) To: Andrew Cagney, gdb-patches > Only better if it allowed to remove all reference to this > target-specific problem from core GDB. Which it doesn't sound like it > would. does anybody know how ia64 works in this area? if you have an if-converted series of instruction and we single step through the region, what happens? randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:35 ` Randolph Chung @ 2004-12-01 18:14 ` Randolph Chung 0 siblings, 0 replies; 44+ messages in thread From: Randolph Chung @ 2004-12-01 18:14 UTC (permalink / raw) To: Andrew Cagney, gdb-patches > does anybody know how ia64 works in this area? if you have an > if-converted series of instruction and we single step through the > region, what happens? it's a bit hard to tell what is happening, because the ia64-gdb seems to be rather broken.... but it seems to have problems stepping through code like this: int foo(int a) { if (a > 10) { x = 1; y = 2; z = 3; } else { x = 11; y = 12; z = 13; } return x + y + z; } with a bit of optimization, gcc turns this into: .loc 1 5 0 cmp4.ge p6, p7 = 10, r32 .loc 1 4 0 addl r8 = @gprel(x#), gp addl r16 = @gprel(y#), gp .mmi addl r15 = @gprel(z#), gp ;; .loc 1 6 0 (p7) addl r8 = @gprel(x#), gp (p7) addl r14 = 1, r0 .mii .loc 1 10 0 (p6) addl r14 = 11, r0 .loc 1 7 0 (p7) addl r16 = @gprel(y#), gp ;; .loc 1 8 0 (p7) addl r15 = @gprel(z#), gp .mii .loc 1 10 0 (p6) st4 [r8] = r14 [...] gdb gets very confused about this :) randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED 2004-12-01 17:11 ` Daniel Jacobowitz 2004-12-01 17:17 ` Randolph Chung @ 2004-12-01 21:25 ` Andrew Cagney 1 sibling, 0 replies; 44+ messages in thread From: Andrew Cagney @ 2004-12-01 21:25 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: Randolph Chung, gdb-patches Daniel Jacobowitz wrote: > On Tue, Nov 30, 2004 at 10:19:24PM -0800, Randolph Chung wrote: > >>i experimented with another proposal which is to adjust the pc when we >>are at a nullified instruction. i modified target_read_pc () to return >>the previous (or next) pc when we are at a nullified instruction. this >>fixes some of the failures but causes new failures with the >>"recurse.exp" test. i need to investigate that some more. but teaching >>target_read_pc() to lie about the current pc seems to be suboptimal. >> >>lastly a comment about sparc -- i think the sparc case is simpler >>because it doesn't have conditional nullification. so looking at a >>particular insn you can always determine if the next insn will be >>nullified or not. this is not always the case for hppa. > > > Randolph, > > Here's an off-the-cuff idea for you. Could you actually skip the > nullified instruction, if you had a hook in the right place? That is, > when a thread stops, if it is stopped at a nullified instruction, > forcibly move it to the next instruction before returning control to > GDB. Read the discussion between Randolf and myself. This doesn't work for core files. > This is probably not feasible if you have to use single-stepping to end > up in the right place. If you can compute the right place and adjust > registers, though, it shouldn't be hard. Andrew ^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2004-12-04 10:53 UTC | newest] Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-12-01 13:32 [patch/RFA] multiarch INSTRUCTION_NULLIFIED Paul Schlie -- strict thread matches above, loose matches on Subject: below -- 2004-12-01 16:25 Randolph Chung 2004-11-18 0:02 Randolph Chung 2004-11-18 14:26 ` Andrew Cagney 2004-11-18 16:21 ` Randolph Chung 2004-11-18 16:56 ` Mark Kettenis 2004-11-19 9:25 ` Orjan Friberg 2004-11-23 17:50 ` Randolph Chung 2004-11-23 19:33 ` Mark Kettenis 2004-11-28 17:26 ` Andrew Cagney 2004-11-28 18:41 ` Randolph Chung 2004-11-28 19:55 ` Andrew Cagney 2004-11-29 3:30 ` Randolph Chung 2004-11-29 15:12 ` Andrew Cagney 2004-11-30 6:56 ` Randolph Chung 2004-11-30 14:51 ` Andrew Cagney 2004-11-30 16:44 ` Randolph Chung 2004-11-30 16:59 ` Andrew Cagney 2004-11-30 17:38 ` Randolph Chung 2004-12-01 21:29 ` Andrew Cagney 2004-12-01 22:33 ` Randolph Chung 2004-12-01 23:32 ` Andrew Cagney 2004-12-02 5:24 ` Randolph Chung 2004-12-02 14:27 ` Daniel Jacobowitz 2004-12-03 18:11 ` Andrew Cagney 2004-12-03 18:15 ` Randolph Chung 2004-12-03 18:57 ` Daniel Jacobowitz 2004-12-03 19:57 ` Randolph Chung 2004-12-03 21:40 ` Randolph Chung 2004-12-03 21:58 ` Andrew Cagney 2004-12-03 22:52 ` Daniel Jacobowitz 2004-12-04 0:00 ` Randolph Chung 2004-12-04 0:55 ` Randolph Chung 2004-12-04 11:27 ` Mark Kettenis 2004-12-01 6:19 ` Randolph Chung 2004-12-01 17:11 ` Daniel Jacobowitz 2004-12-01 17:17 ` Randolph Chung 2004-12-01 17:19 ` Daniel Jacobowitz 2004-12-01 17:25 ` Randolph Chung 2004-12-01 17:28 ` Daniel Jacobowitz 2004-12-01 17:30 ` Randolph Chung 2004-12-01 17:35 ` Randolph Chung 2004-12-01 18:14 ` Randolph Chung 2004-12-01 21:25 ` Andrew Cagney
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox