gdb/gdb-6.6-bz237572-ppc-atomic...

1161 lines
42 KiB
Diff
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=235186
2007-01-10 Daniel Jacobowitz <dan@codesourcery.com>
* infrun.c (singlestep_pc): New variable.
(resume): Set singlestep_pc.
(context_switch): Add a debugging message. Flush the frame cache.
(handle_inferior_event): Add debugging messages. Handle thread
hops when a software single step has completed. Let context_switch
handle flushing the frame cache.
--- ./gdb/infrun.c 9 Jan 2007 17:58:51 -0000 1.218
+++ ./gdb/infrun.c 10 Jan 2007 20:10:23 -0000 1.219
@@ -469,6 +469,9 @@ static int singlestep_breakpoints_insert
/* The thread we inserted single-step breakpoints for. */
static ptid_t singlestep_ptid;
+/* PC when we started this single-step. */
+static CORE_ADDR singlestep_pc;
+
/* If another thread hit the singlestep breakpoint, we save the original
thread here so that we can resume single-stepping it later. */
static ptid_t saved_singlestep_ptid;
@@ -563,6 +566,7 @@ resume (int step, enum target_signal sig
`wait_for_inferior' */
singlestep_breakpoints_inserted_p = 1;
singlestep_ptid = inferior_ptid;
+ singlestep_pc = read_pc ();
}
/* If there were any forks/vforks/execs that were caught and are
@@ -1126,6 +1130,14 @@ context_switch (struct execution_control
be lost. This may happen as a result of the target module
mishandling thread creation. */
+ if (debug_infrun)
+ {
+ fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
+ target_pid_to_str (inferior_ptid));
+ fprintf_unfiltered (gdb_stdlog, "to %s\n",
+ target_pid_to_str (ecs->ptid));
+ }
+
if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
{ /* Perform infrun state context switch: */
/* Save infrun state for the old thread. */
@@ -1149,6 +1161,7 @@ context_switch (struct execution_control
&ecs->current_line, &ecs->current_symtab);
}
inferior_ptid = ecs->ptid;
+ flush_cached_frames ();
}
static void
@@ -1609,6 +1622,14 @@ handle_inferior_event (struct execution_
}
else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
+ /* We have not context switched yet, so this should be true
+ no matter which thread hit the singlestep breakpoint. */
+ gdb_assert (ptid_equal (inferior_ptid, singlestep_ptid));
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: software single step "
+ "trap for %s\n",
+ target_pid_to_str (ecs->ptid));
+
ecs->random_signal = 0;
/* The call to in_thread_list is necessary because PTIDs sometimes
change when we go from single-threaded to multi-threaded. If
@@ -1617,9 +1638,46 @@ handle_inferior_event (struct execution_
if (!ptid_equal (singlestep_ptid, ecs->ptid)
&& in_thread_list (singlestep_ptid))
{
- thread_hop_needed = 1;
- stepping_past_singlestep_breakpoint = 1;
- saved_singlestep_ptid = singlestep_ptid;
+ /* If the PC of the thread we were trying to single-step
+ has changed, discard this event (which we were going
+ to ignore anyway), and pretend we saw that thread
+ trap. This prevents us continuously moving the
+ single-step breakpoint forward, one instruction at a
+ time. If the PC has changed, then the thread we were
+ trying to single-step has trapped or been signalled,
+ but the event has not been reported to GDB yet.
+
+ There might be some cases where this loses signal
+ information, if a signal has arrived at exactly the
+ same time that the PC changed, but this is the best
+ we can do with the information available. Perhaps we
+ should arrange to report all events for all threads
+ when they stop, or to re-poll the remote looking for
+ this particular thread (i.e. temporarily enable
+ schedlock). */
+ if (read_pc_pid (singlestep_ptid) != singlestep_pc)
+ {
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
+ " but expected thread advanced also\n");
+
+ /* The current context still belongs to
+ singlestep_ptid. Don't swap here, since that's
+ the context we want to use. Just fudge our
+ state and continue. */
+ ecs->ptid = singlestep_ptid;
+ stop_pc = read_pc_pid (ecs->ptid);
+ }
+ else
+ {
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: unexpected thread\n");
+
+ thread_hop_needed = 1;
+ stepping_past_singlestep_breakpoint = 1;
+ saved_singlestep_ptid = singlestep_ptid;
+ }
}
}
@@ -1702,8 +1760,6 @@ handle_inferior_event (struct execution_
if (deprecated_context_hook)
deprecated_context_hook (pid_to_thread_id (ecs->ptid));
-
- flush_cached_frames ();
}
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
2007-04-12 Luis Machado <luisgpm@br.ibm.com>
* gdbarch.sh (software_single_step): Change the return type
from void to int and reformatted some comments to <= 80
columns.
* gdbarch.c, gdbarch.h: Regenerated.
* alpha-tdep.c (alpha_software_single_step): Likewise.
* alpha-tdep.h (alpha_software_single_step): Likewise.
* arm-tdep.c (arm_software_single_step): Likewise.
* cris-tdep.c (cris_software_single_step): Likewise.
* mips-tdep.c (mips_software_single_step): Likewise.
* mips-tdep.h (mips_software_single_step): Likewise.
* rs6000-tdep.c (rs6000_software_single_step): Likewise.
* rs6000-tdep.h (rs6000_software_single_step): Likewise.
* sparc-tdep.c (sparc_software_single_step): Likewise.
* sparc-tdep.h (sparc_software_single_step): Likewise.
[REMOVED] * spu-tdep.c (spu_software_single_step): Likewise.
* infrun.c (resume): Check the return value from SOFTWARE_SINGLE_STEP
and act accordingly.
--- ./gdb/alpha-tdep.c 27 Feb 2007 20:17:18 -0000 1.162
+++ ./gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163
@@ -1518,7 +1518,7 @@ alpha_next_pc (CORE_ADDR pc)
return (pc + ALPHA_INSN_SIZE);
}
-void
+int
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
static CORE_ADDR next_pc;
@@ -1536,6 +1536,7 @@ alpha_software_single_step (enum target_
remove_single_step_breakpoints ();
write_pc (next_pc);
}
+ return 1;
}
--- ./gdb/alpha-tdep.h 9 Jan 2007 17:58:49 -0000 1.27
+++ ./gdb/alpha-tdep.h 12 Apr 2007 14:52:19 -0000 1.28
@@ -107,7 +107,7 @@ struct gdbarch_tdep
};
extern unsigned int alpha_read_insn (CORE_ADDR pc);
-extern void alpha_software_single_step (enum target_signal, int);
+extern int alpha_software_single_step (enum target_signal, int);
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);
--- ./gdb/arm-tdep.c 30 Mar 2007 22:50:33 -0000 1.225
+++ ./gdb/arm-tdep.c 12 Apr 2007 14:52:19 -0000 1.226
@@ -1907,7 +1907,7 @@ arm_get_next_pc (CORE_ADDR pc)
single_step() is also called just after the inferior stops. If we
had set up a simulated single-step, we undo our damage. */
-static void
+static int
arm_software_single_step (enum target_signal sig, int insert_bpt)
{
/* NOTE: This may insert the wrong breakpoint instruction when
@@ -1922,6 +1922,8 @@ arm_software_single_step (enum target_si
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
#include "bfd-in2.h"
--- ./gdb/cris-tdep.c 27 Feb 2007 20:17:18 -0000 1.138
+++ ./gdb/cris-tdep.c 12 Apr 2007 14:52:19 -0000 1.139
@@ -2119,7 +2119,7 @@ find_step_target (inst_env_type *inst_en
digs through the opcodes in order to find all possible targets.
Either one ordinary target or two targets for branches may be found. */
-static void
+static int
cris_software_single_step (enum target_signal ignore, int insert_breakpoints)
{
inst_env_type inst_env;
@@ -2152,6 +2152,8 @@ cris_software_single_step (enum target_s
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Calculates the prefix value for quick offset addressing mode. */
--- ./gdb/gdbarch.c 28 Feb 2007 17:34:58 -0000 1.338
+++ ./gdb/gdbarch.c 12 Apr 2007 14:52:19 -0000 1.339
@@ -3289,14 +3289,14 @@ gdbarch_software_single_step_p (struct g
return gdbarch->software_single_step != NULL;
}
-void
+int
gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->software_single_step != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n");
- gdbarch->software_single_step (sig, insert_breakpoints_p);
+ return gdbarch->software_single_step (sig, insert_breakpoints_p);
}
void
--- ./gdb/gdbarch.h 8 Feb 2007 21:00:29 -0000 1.294
+++ ./gdb/gdbarch.h 12 Apr 2007 14:52:19 -0000 1.295
@@ -1144,14 +1144,19 @@ extern void set_gdbarch_smash_text_addre
#define SMASH_TEXT_ADDRESS(addr) (gdbarch_smash_text_address (current_gdbarch, addr))
#endif
-/* FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
- the target needs software single step. An ISA method to implement it.
+/* FIXME/cagney/2001-01-18: This should be split in two. A target method that
+ indicates if the target needs software single step. An ISA method to
+ implement it.
- FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
- using the breakpoint system instead of blatting memory directly (as with rs6000).
+ FIXME/cagney/2001-01-18: This should be replaced with something that inserts
+ breakpoints using the breakpoint system instead of blatting memory directly
+ (as with rs6000).
- FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
- single step. If not, then implement single step using breakpoints. */
+ FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
+ target can single step. If not, then implement single step using breakpoints.
+
+ A return value of 1 means that the software_single_step breakpoints
+ were inserted; 0 means they were not. */
#if defined (SOFTWARE_SINGLE_STEP)
/* Legacy for systems yet to multi-arch SOFTWARE_SINGLE_STEP */
@@ -1168,8 +1173,8 @@ extern int gdbarch_software_single_step_
#define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch))
#endif
-typedef void (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
-extern void gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
+typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
+extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
#if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP)
#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
--- ./gdb/gdbarch.sh 28 Feb 2007 17:35:00 -0000 1.376
+++ ./gdb/gdbarch.sh 12 Apr 2007 14:52:19 -0000 1.377
@@ -614,15 +614,22 @@ f:=:CORE_ADDR:addr_bits_remove:CORE_ADDR
# It is not at all clear why SMASH_TEXT_ADDRESS is not folded into
# ADDR_BITS_REMOVE.
f:=:CORE_ADDR:smash_text_address:CORE_ADDR addr:addr::core_addr_identity::0
-# FIXME/cagney/2001-01-18: This should be split in two. A target method that indicates if
-# the target needs software single step. An ISA method to implement it.
+
+# FIXME/cagney/2001-01-18: This should be split in two. A target method that
+# indicates if the target needs software single step. An ISA method to
+# implement it.
+#
+# FIXME/cagney/2001-01-18: This should be replaced with something that inserts
+# breakpoints using the breakpoint system instead of blatting memory directly
+# (as with rs6000).
#
-# FIXME/cagney/2001-01-18: This should be replaced with something that inserts breakpoints
-# using the breakpoint system instead of blatting memory directly (as with rs6000).
+# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
+# target can single step. If not, then implement single step using breakpoints.
#
-# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the target can
-# single step. If not, then implement single step using breakpoints.
-F:=:void:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+# A return value of 1 means that the software_single_step breakpoints
+# were inserted; 0 means they were not.
+F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+
# 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
--- ./gdb/infrun.c 29 Mar 2007 07:35:39 -0000 1.225
+++ ./gdb/infrun.c 12 Apr 2007 14:52:19 -0000 1.226
@@ -548,14 +548,16 @@ resume (int step, enum target_signal sig
if (SOFTWARE_SINGLE_STEP_P () && step)
{
/* Do it the hard way, w/temp breakpoints */
- SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
- /* ...and don't ask hardware to do it. */
- step = 0;
- /* and do not pull these breakpoints until after a `wait' in
- `wait_for_inferior' */
- singlestep_breakpoints_inserted_p = 1;
- singlestep_ptid = inferior_ptid;
- singlestep_pc = read_pc ();
+ if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ))
+ {
+ /* ...and don't ask hardware to do it. */
+ step = 0;
+ /* and do not pull these breakpoints until after a `wait' in
+ `wait_for_inferior' */
+ singlestep_breakpoints_inserted_p = 1;
+ singlestep_ptid = inferior_ptid;
+ singlestep_pc = read_pc ();
+ }
}
/* If there were any forks/vforks/execs that were caught and are
@@ -1378,7 +1380,7 @@ handle_inferior_event (struct execution_
(LONGEST) ecs->ws.value.integer));
gdb_flush (gdb_stdout);
target_mourn_inferior ();
- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
stop_print_frame = 0;
stop_stepping (ecs);
return;
@@ -1398,7 +1400,7 @@ handle_inferior_event (struct execution_
target_mourn_inferior ();
print_stop_reason (SIGNAL_EXITED, stop_signal);
- singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P() */
+ singlestep_breakpoints_inserted_p = 0; /* SOFTWARE_SINGLE_STEP_P() */
stop_stepping (ecs);
return;
@@ -1569,7 +1571,7 @@ handle_inferior_event (struct execution_
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
/* Pull the single step breakpoints out of the target. */
- SOFTWARE_SINGLE_STEP (0, 0);
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
ecs->random_signal = 0;
@@ -1678,7 +1680,7 @@ handle_inferior_event (struct execution_
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
- SOFTWARE_SINGLE_STEP (0, 0);
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
}
@@ -1749,7 +1751,7 @@ handle_inferior_event (struct execution_
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
- SOFTWARE_SINGLE_STEP (0, 0);
+ (void) SOFTWARE_SINGLE_STEP (0, 0);
singlestep_breakpoints_inserted_p = 0;
}
--- ./gdb/mips-tdep.c 30 Mar 2007 22:50:33 -0000 1.407
+++ ./gdb/mips-tdep.c 12 Apr 2007 14:52:19 -0000 1.408
@@ -2204,7 +2204,7 @@ mips_addr_bits_remove (CORE_ADDR addr)
single_step is also called just after the inferior stops. If we had
set up a simulated single-step, we undo our damage. */
-void
+int
mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
CORE_ADDR pc, next_pc;
@@ -2218,6 +2218,8 @@ mips_software_single_step (enum target_s
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
/* Test whether the PC points to the return instruction at the
--- ./gdb/mips-tdep.h 30 Mar 2007 22:50:33 -0000 1.20
+++ ./gdb/mips-tdep.h 12 Apr 2007 14:52:20 -0000 1.21
@@ -100,7 +100,7 @@ enum
};
/* Single step based on where the current instruction will take us. */
-extern void mips_software_single_step (enum target_signal, int);
+extern int mips_software_single_step (enum target_signal, int);
/* Tell if the program counter value in MEMADDR is in a MIPS16
function. */
--- ./gdb/rs6000-tdep.c 10 Apr 2007 16:02:41 -0000 1.270
+++ ./gdb/rs6000-tdep.c 12 Apr 2007 14:52:20 -0000 1.271
@@ -722,7 +722,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
/* AIX does not support PT_STEP. Simulate it. */
-void
+int
rs6000_software_single_step (enum target_signal signal,
int insert_breakpoints_p)
{
@@ -761,6 +761,7 @@ rs6000_software_single_step (enum target
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
+ return 1;
}
--- ./gdb/rs6000-tdep.h 27 Feb 2007 23:04:28 -0000 1.3
+++ ./gdb/rs6000-tdep.h 12 Apr 2007 14:52:20 -0000 1.4
@@ -21,8 +21,8 @@
#include "defs.h"
-extern void rs6000_software_single_step (enum target_signal signal,
- int insert_breakpoints_p);
+extern int rs6000_software_single_step (enum target_signal signal,
+ int insert_breakpoints_p);
/* Hook in rs6000-tdep.c for determining the TOC address when
calling functions in the inferior. */
--- ./gdb/sparc-tdep.c 11 Apr 2007 07:10:08 -0000 1.179
+++ ./gdb/sparc-tdep.c 12 Apr 2007 14:52:20 -0000 1.180
@@ -1329,7 +1329,7 @@ sparc_step_trap (unsigned long insn)
return 0;
}
-void
+int
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
struct gdbarch *arch = current_gdbarch;
@@ -1359,6 +1359,8 @@ sparc_software_single_step (enum target_
}
else
remove_single_step_breakpoints ();
+
+ return 1;
}
static void
--- ./gdb/sparc-tdep.h 9 Jan 2007 17:58:58 -0000 1.12
+++ ./gdb/sparc-tdep.h 12 Apr 2007 14:52:20 -0000 1.13
@@ -167,8 +167,8 @@ extern struct sparc_frame_cache *
-extern void sparc_software_single_step (enum target_signal sig,
- int insert_breakpoints_p);
+extern int sparc_software_single_step (enum target_signal sig,
+ int insert_breakpoints_p);
extern void sparc_supply_rwindow (struct regcache *regcache,
CORE_ADDR sp, int regnum);
2007-04-14 Ulrich Weigand <uweigand@de.ibm.com>
* alpha-tdep.c (alpha_software_single_step): Do not call write_pc
when removing single-step breakpoints.
--- ./gdb/alpha-tdep.c 12 Apr 2007 14:52:19 -0000 1.163
+++ ./gdb/alpha-tdep.c 14 Apr 2007 16:17:39 -0000 1.164
@@ -1521,7 +1521,7 @@ alpha_next_pc (CORE_ADDR pc)
int
alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
- static CORE_ADDR next_pc;
+ CORE_ADDR next_pc;
CORE_ADDR pc;
if (insert_breakpoints_p)
@@ -1534,7 +1534,6 @@ alpha_software_single_step (enum target_
else
{
remove_single_step_breakpoints ();
- write_pc (next_pc);
}
return 1;
}
2007-04-14 Ulrich Weigand <uweigand@de.ibm.com>
* gdbarch.sh (software_single_step): Remove "insert_breakpoints_p" and
"sig" arguments, add "regcache" argument.
* gdbarch.c, gdbarch.h: Regenerate.
* infrun.c (resume): Update SOFTWARE_SINGLE_STEP call arguments.
(handle_inferior_event): Call remove_single_step_breakpoints directly
instead of calling SOFTWARE_SINGLE_STEP to remove breakpoints.
* alpha-tdep.c (alpha_software_single_step): Update argument list.
Remove handling of !insert_breakpoints_p case.
* arm-tdep.c (arm_software_single_step): Likewise.
* cris-tdep.c (cris_software_single_step): Likewise.
* mips-tdep.c (mips_software_single_step): Likewise.
* rs6000-tdep.c (rs6000_software_single_step): Likewise.
* sparc-tdep.c (sparc_software_single_step): Likewise.
[REMOVED] * spu-tdep.c (spu_software_single_step): Likewise.
* alpha-tdep.h (alpha_software_single_step): Update prototype.
* mips-tdep.h (mips_software_single_step): Likewise.
* rs6000-tdep.h (rs6000_software_single_step): Likewise.
* sparc-tdep.h (sparc_software_single_step): Likewise.
--- ./gdb/alpha-tdep.c 14 Apr 2007 16:17:39 -0000 1.164
+++ ./gdb/alpha-tdep.c 14 Apr 2007 18:10:54 -0000 1.165
@@ -1391,10 +1391,7 @@ fp_register_sign_bit (LONGEST reg)
/* alpha_software_single_step() is called just before we want to resume
the inferior, if we want to single-step it but there is no hardware
or kernel single-step support (NetBSD on Alpha, for example). We find
- the target of the coming instruction and breakpoint it.
-
- single_step is also called just after the inferior stops. If we had
- set up a simulated single-step, we undo our damage. */
+ the target of the coming instruction and breakpoint it. */
static CORE_ADDR
alpha_next_pc (CORE_ADDR pc)
@@ -1519,22 +1516,14 @@ alpha_next_pc (CORE_ADDR pc)
}
int
-alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+alpha_software_single_step (struct regcache *regcache)
{
- CORE_ADDR next_pc;
- CORE_ADDR pc;
+ CORE_ADDR pc, next_pc;
- if (insert_breakpoints_p)
- {
- pc = read_pc ();
- next_pc = alpha_next_pc (pc);
+ pc = read_pc ();
+ next_pc = alpha_next_pc (pc);
- insert_single_step_breakpoint (next_pc);
- }
- else
- {
- remove_single_step_breakpoints ();
- }
+ insert_single_step_breakpoint (next_pc);
return 1;
}
--- ./gdb/alpha-tdep.h 12 Apr 2007 14:52:19 -0000 1.28
+++ ./gdb/alpha-tdep.h 14 Apr 2007 18:10:54 -0000 1.29
@@ -107,7 +107,7 @@ struct gdbarch_tdep
};
extern unsigned int alpha_read_insn (CORE_ADDR pc);
-extern int alpha_software_single_step (enum target_signal, int);
+extern int alpha_software_single_step (struct regcache *regcache);
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);
--- ./gdb/arm-tdep.c 12 Apr 2007 14:52:19 -0000 1.226
+++ ./gdb/arm-tdep.c 14 Apr 2007 18:10:54 -0000 1.227
@@ -1902,26 +1902,17 @@ arm_get_next_pc (CORE_ADDR pc)
/* single_step() is called just before we want to resume the inferior,
if we want to single-step it but there is no hardware or kernel
single-step support. We find the target of the coming instruction
- and breakpoint it.
-
- single_step() is also called just after the inferior stops. If we
- had set up a simulated single-step, we undo our damage. */
+ and breakpoint it. */
static int
-arm_software_single_step (enum target_signal sig, int insert_bpt)
+arm_software_single_step (struct regcache *regcache)
{
/* NOTE: This may insert the wrong breakpoint instruction when
single-stepping over a mode-changing instruction, if the
CPSR heuristics are used. */
- if (insert_bpt)
- {
- CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
-
- insert_single_step_breakpoint (next_pc);
- }
- else
- remove_single_step_breakpoints ();
+ CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
+ insert_single_step_breakpoint (next_pc);
return 1;
}
--- ./gdb/cris-tdep.c 12 Apr 2007 14:52:19 -0000 1.139
+++ ./gdb/cris-tdep.c 14 Apr 2007 18:10:54 -0000 1.140
@@ -2120,38 +2120,33 @@ find_step_target (inst_env_type *inst_en
Either one ordinary target or two targets for branches may be found. */
static int
-cris_software_single_step (enum target_signal ignore, int insert_breakpoints)
+cris_software_single_step (struct regcache *regcache)
{
inst_env_type inst_env;
- if (insert_breakpoints)
- {
- /* Analyse the present instruction environment and insert
- breakpoints. */
- int status = find_step_target (&inst_env);
- if (status == -1)
- {
- /* Could not find a target. Things are likely to go downhill
- from here. */
- warning (_("CRIS software single step could not find a step target."));
- }
- else
- {
- /* Insert at most two breakpoints. One for the next PC content
- and possibly another one for a branch, jump, etc. */
- CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM];
- insert_single_step_breakpoint (next_pc);
- if (inst_env.branch_found
- && (CORE_ADDR) inst_env.branch_break_address != next_pc)
- {
- CORE_ADDR branch_target_address
- = (CORE_ADDR) inst_env.branch_break_address;
- insert_single_step_breakpoint (branch_target_address);
- }
- }
+ /* Analyse the present instruction environment and insert
+ breakpoints. */
+ int status = find_step_target (&inst_env);
+ if (status == -1)
+ {
+ /* Could not find a target. Things are likely to go downhill
+ from here. */
+ warning (_("CRIS software single step could not find a step target."));
}
else
- remove_single_step_breakpoints ();
+ {
+ /* Insert at most two breakpoints. One for the next PC content
+ and possibly another one for a branch, jump, etc. */
+ CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM];
+ insert_single_step_breakpoint (next_pc);
+ if (inst_env.branch_found
+ && (CORE_ADDR) inst_env.branch_break_address != next_pc)
+ {
+ CORE_ADDR branch_target_address
+ = (CORE_ADDR) inst_env.branch_break_address;
+ insert_single_step_breakpoint (branch_target_address);
+ }
+ }
return 1;
}
--- ./gdb/gdbarch.c 12 Apr 2007 14:52:19 -0000 1.339
+++ ./gdb/gdbarch.c 14 Apr 2007 18:10:54 -0000 1.340
@@ -1522,8 +1522,8 @@ gdbarch_dump (struct gdbarch *current_gd
#ifdef SOFTWARE_SINGLE_STEP
fprintf_unfiltered (file,
"gdbarch_dump: %s # %s\n",
- "SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p)",
- XSTRING (SOFTWARE_SINGLE_STEP (sig, insert_breakpoints_p)));
+ "SOFTWARE_SINGLE_STEP(regcache)",
+ XSTRING (SOFTWARE_SINGLE_STEP (regcache)));
#endif
fprintf_unfiltered (file,
"gdbarch_dump: software_single_step = <0x%lx>\n",
@@ -3290,13 +3290,13 @@ gdbarch_software_single_step_p (struct g
}
int
-gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p)
+gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->software_single_step != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n");
- return gdbarch->software_single_step (sig, insert_breakpoints_p);
+ return gdbarch->software_single_step (regcache);
}
void
--- ./gdb/gdbarch.h 12 Apr 2007 14:52:19 -0000 1.295
+++ ./gdb/gdbarch.h 14 Apr 2007 18:10:54 -0000 1.296
@@ -1173,14 +1173,14 @@ extern int gdbarch_software_single_step_
#define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch))
#endif
-typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p);
-extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p);
+typedef int (gdbarch_software_single_step_ftype) (struct regcache *regcache);
+extern int gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache);
extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
#if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP)
#error "Non multi-arch definition of SOFTWARE_SINGLE_STEP"
#endif
#if !defined (SOFTWARE_SINGLE_STEP)
-#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p))
+#define SOFTWARE_SINGLE_STEP(regcache) (gdbarch_software_single_step (current_gdbarch, regcache))
#endif
/* Return non-zero if the processor is executing a delay slot and a
--- ./gdb/gdbarch.sh 12 Apr 2007 14:52:19 -0000 1.377
+++ ./gdb/gdbarch.sh 14 Apr 2007 18:10:54 -0000 1.378
@@ -628,7 +628,7 @@ f:=:CORE_ADDR:smash_text_address:CORE_AD
#
# A return value of 1 means that the software_single_step breakpoints
# were inserted; 0 means they were not.
-F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p
+F:=:int:software_single_step:struct regcache *regcache:regcache
# Return non-zero if the processor is executing a delay slot and a
# further single-step is needed before the instruction finishes.
--- ./gdb/infrun.c 13 Apr 2007 13:29:42 -0000 1.227
+++ ./gdb/infrun.c 14 Apr 2007 18:10:54 -0000 1.228
@@ -548,7 +548,7 @@ resume (int step, enum target_signal sig
if (SOFTWARE_SINGLE_STEP_P () && step)
{
/* Do it the hard way, w/temp breakpoints */
- if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ ))
+ if (SOFTWARE_SINGLE_STEP (current_regcache))
{
/* ...and don't ask hardware to do it. */
step = 0;
@@ -1571,7 +1571,7 @@ handle_inferior_event (struct execution_
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
/* Pull the single step breakpoints out of the target. */
- (void) SOFTWARE_SINGLE_STEP (0, 0);
+ remove_single_step_breakpoints ();
singlestep_breakpoints_inserted_p = 0;
ecs->random_signal = 0;
@@ -1680,7 +1680,7 @@ handle_inferior_event (struct execution_
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
- (void) SOFTWARE_SINGLE_STEP (0, 0);
+ remove_single_step_breakpoints ();
singlestep_breakpoints_inserted_p = 0;
}
@@ -1751,7 +1751,7 @@ handle_inferior_event (struct execution_
if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
{
/* Pull the single step breakpoints out of the target. */
- (void) SOFTWARE_SINGLE_STEP (0, 0);
+ remove_single_step_breakpoints ();
singlestep_breakpoints_inserted_p = 0;
}
--- ./gdb/mips-tdep.c 12 Apr 2007 14:52:19 -0000 1.408
+++ ./gdb/mips-tdep.c 14 Apr 2007 18:10:54 -0000 1.409
@@ -2199,26 +2199,17 @@ mips_addr_bits_remove (CORE_ADDR addr)
/* mips_software_single_step() is called just before we want to resume
the inferior, if we want to single-step it but there is no hardware
or kernel single-step support (MIPS on GNU/Linux for example). We find
- the target of the coming instruction and breakpoint it.
-
- single_step is also called just after the inferior stops. If we had
- set up a simulated single-step, we undo our damage. */
+ the target of the coming instruction and breakpoint it. */
int
-mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+mips_software_single_step (struct regcache *regcache)
{
CORE_ADDR pc, next_pc;
- if (insert_breakpoints_p)
- {
- pc = read_register (mips_regnum (current_gdbarch)->pc);
- next_pc = mips_next_pc (pc);
-
- insert_single_step_breakpoint (next_pc);
- }
- else
- remove_single_step_breakpoints ();
+ pc = read_register (mips_regnum (current_gdbarch)->pc);
+ next_pc = mips_next_pc (pc);
+ insert_single_step_breakpoint (next_pc);
return 1;
}
--- ./gdb/mips-tdep.h 12 Apr 2007 14:52:20 -0000 1.21
+++ ./gdb/mips-tdep.h 14 Apr 2007 18:10:54 -0000 1.22
@@ -100,7 +100,7 @@ enum
};
/* Single step based on where the current instruction will take us. */
-extern int mips_software_single_step (enum target_signal, int);
+extern int mips_software_single_step (struct regcache *regcache);
/* Tell if the program counter value in MEMADDR is in a MIPS16
function. */
--- ./gdb/rs6000-tdep.c 12 Apr 2007 14:52:20 -0000 1.271
+++ ./gdb/rs6000-tdep.c 14 Apr 2007 18:10:54 -0000 1.272
@@ -723,8 +723,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
/* AIX does not support PT_STEP. Simulate it. */
int
-rs6000_software_single_step (enum target_signal signal,
- int insert_breakpoints_p)
+rs6000_software_single_step (struct regcache *regcache)
{
CORE_ADDR dummy;
int breakp_sz;
@@ -734,30 +733,25 @@ rs6000_software_single_step (enum target
CORE_ADDR breaks[2];
int opcode;
- if (insert_breakpoints_p)
- {
- loc = read_pc ();
+ loc = read_pc ();
- insn = read_memory_integer (loc, 4);
+ insn = read_memory_integer (loc, 4);
- breaks[0] = loc + breakp_sz;
- opcode = insn >> 26;
- breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
+ breaks[0] = loc + breakp_sz;
+ opcode = insn >> 26;
+ breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
- /* Don't put two breakpoints on the same address. */
- if (breaks[1] == breaks[0])
- breaks[1] = -1;
+ /* Don't put two breakpoints on the same address. */
+ if (breaks[1] == breaks[0])
+ breaks[1] = -1;
- for (ii = 0; ii < 2; ++ii)
- {
- /* ignore invalid breakpoint. */
- if (breaks[ii] == -1)
- continue;
- insert_single_step_breakpoint (breaks[ii]);
- }
+ for (ii = 0; ii < 2; ++ii)
+ {
+ /* ignore invalid breakpoint. */
+ if (breaks[ii] == -1)
+ continue;
+ insert_single_step_breakpoint (breaks[ii]);
}
- else
- remove_single_step_breakpoints ();
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
--- ./gdb/rs6000-tdep.h 12 Apr 2007 14:52:20 -0000 1.4
+++ ./gdb/rs6000-tdep.h 14 Apr 2007 18:10:54 -0000 1.5
@@ -21,8 +21,7 @@
#include "defs.h"
-extern int rs6000_software_single_step (enum target_signal signal,
- int insert_breakpoints_p);
+extern int rs6000_software_single_step (struct regcache *regcache);
/* Hook in rs6000-tdep.c for determining the TOC address when
calling functions in the inferior. */
--- ./gdb/sparc-tdep.c 12 Apr 2007 14:52:20 -0000 1.180
+++ ./gdb/sparc-tdep.c 14 Apr 2007 18:10:54 -0000 1.181
@@ -1330,35 +1330,30 @@ sparc_step_trap (unsigned long insn)
}
int
-sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+sparc_software_single_step (struct regcache *regcache)
{
struct gdbarch *arch = current_gdbarch;
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
CORE_ADDR npc, nnpc;
- if (insert_breakpoints_p)
- {
- CORE_ADDR pc, orig_npc;
+ CORE_ADDR pc, orig_npc;
- pc = sparc_address_from_register (tdep->pc_regnum);
- orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
+ pc = sparc_address_from_register (tdep->pc_regnum);
+ orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);
- /* Analyze the instruction at PC. */
- nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
- if (npc != 0)
- insert_single_step_breakpoint (npc);
-
- if (nnpc != 0)
- insert_single_step_breakpoint (nnpc);
-
- /* Assert that we have set at least one breakpoint, and that
- they're not set at the same spot - unless we're going
- from here straight to NULL, i.e. a call or jump to 0. */
- gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
- gdb_assert (nnpc != npc || orig_npc == 0);
- }
- else
- remove_single_step_breakpoints ();
+ /* Analyze the instruction at PC. */
+ nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
+ if (npc != 0)
+ insert_single_step_breakpoint (npc);
+
+ if (nnpc != 0)
+ insert_single_step_breakpoint (nnpc);
+
+ /* Assert that we have set at least one breakpoint, and that
+ they're not set at the same spot - unless we're going
+ from here straight to NULL, i.e. a call or jump to 0. */
+ gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
+ gdb_assert (nnpc != npc || orig_npc == 0);
return 1;
}
--- ./gdb/sparc-tdep.h 12 Apr 2007 14:52:20 -0000 1.13
+++ ./gdb/sparc-tdep.h 14 Apr 2007 18:10:54 -0000 1.14
@@ -167,8 +167,7 @@ extern struct sparc_frame_cache *
-extern int sparc_software_single_step (enum target_signal sig,
- int insert_breakpoints_p);
+extern int sparc_software_single_step (struct regcache *regcache);
extern void sparc_supply_rwindow (struct regcache *regcache,
CORE_ADDR sp, int regnum);
2007-05-11 Ulrich Weigand <uweigand@de.ibm.com>
* breakpoint.c (single_step_breakpoint_inserted_here_p): New function.
(breakpoint_inserted_here_p): Call it.
(software_breakpoint_inserted_here_p): Likewise.
--- ./gdb/breakpoint.c 3 May 2007 17:42:25 -0000 1.247
+++ ./gdb/breakpoint.c 11 May 2007 12:44:34 -0000 1.248
@@ -202,6 +202,8 @@ static void tcatch_command (char *arg, i
static void ep_skip_leading_whitespace (char **s);
+static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
+
/* Prototypes for exported functions. */
/* If FALSE, gdb will not use hardware support for watchpoints, even
@@ -1841,6 +1843,10 @@ breakpoint_inserted_here_p (CORE_ADDR pc
}
}
+ /* Also check for software single-step breakpoints. */
+ if (single_step_breakpoint_inserted_here_p (pc))
+ return 1;
+
return 0;
}
@@ -1872,6 +1878,10 @@ software_breakpoint_inserted_here_p (COR
}
}
+ /* Also check for software single-step breakpoints. */
+ if (single_step_breakpoint_inserted_here_p (pc))
+ return 1;
+
return 0;
}
@@ -7951,6 +7961,23 @@ remove_single_step_breakpoints (void)
}
}
+/* Check whether a software single-step breakpoint is inserted at PC. */
+
+static int
+single_step_breakpoint_inserted_here_p (CORE_ADDR pc)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ {
+ struct bp_target_info *bp_tgt = single_step_breakpoints[i];
+ if (bp_tgt && bp_tgt->placed_address == pc)
+ return 1;
+ }
+
+ return 0;
+}
+
/* This help string is used for the break, hbreak, tbreak and thbreak commands.
It is defined as a macro to prevent duplication.
2007-05-08 Paul Gilliam <pgilliam@us.ibm.com>
Luis Machado <luisgpm@br.ibm.com>
* rs6000-tdep.c: (LWARX_MASK, LWARX_INSTRUCTION, LDARX_INSTRUCTION,
STWCX_MASK, STWCX_INSTRUCTION, STDCX_INSTRUCTION, BC_MASK,
BC_INSTRUCTION): Define.
(deal_with_atomic_sequence): New function.
(rs6000_software_single_step): Call deal_with_atomic_sequence.
(rs6000_gdbarch_init): Install deal_with_atomic_sequence as
gdbarch_software_single_step routine.
--- ./gdb/rs6000-tdep.c 7 May 2007 01:25:07 -0000 1.274
+++ ./gdb/rs6000-tdep.c 8 May 2007 12:49:12 -0000 1.275
@@ -707,7 +707,95 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp
}
-/* AIX does not support PT_STEP. Simulate it. */
+/* Instruction masks used during single-stepping of atomic sequences. */
+#define LWARX_MASK 0xfc0007fe
+#define LWARX_INSTRUCTION 0x7c000028
+#define LDARX_INSTRUCTION 0x7c0000A8
+#define STWCX_MASK 0xfc0007ff
+#define STWCX_INSTRUCTION 0x7c00012d
+#define STDCX_INSTRUCTION 0x7c0001ad
+#define BC_MASK 0xfc000000
+#define BC_INSTRUCTION 0x40000000
+
+/* Checks for an atomic sequence of instructions beginning with a LWARX/LDARX
+ instruction and ending with a STWCX/STDCX instruction. If such a sequence
+ is found, attempt to step through it. A breakpoint is placed at the end of
+ the sequence. */
+
+static int
+deal_with_atomic_sequence (struct regcache *regcache)
+{
+ CORE_ADDR pc = read_pc ();
+ CORE_ADDR breaks[2] = {-1, -1};
+ CORE_ADDR loc = pc;
+ CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination. */
+ int insn = read_memory_integer (loc, PPC_INSN_SIZE);
+ int insn_count;
+ int index;
+ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
+ const int atomic_sequence_length = 16; /* Instruction sequence length. */
+ const int opcode = BC_INSTRUCTION; /* Branch instruction's OPcode. */
+ int bc_insn_count = 0; /* Conditional branch instruction count. */
+
+ /* Assume all atomic sequences start with a lwarx/ldarx instruction. */
+ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
+ && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
+ return 0;
+
+ /* Assume that no atomic sequence is longer than "atomic_sequence_length"
+ instructions. */
+ for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
+ {
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* Assume that there is at most one conditional branch in the atomic
+ sequence. If a conditional branch is found, put a breakpoint in
+ its destination address. */
+ if ((insn & BC_MASK) == BC_INSTRUCTION)
+ {
+ if (bc_insn_count >= 1)
+ return 0; /* More than one conditional branch found, fallback
+ to the standard single-step code. */
+
+ branch_bp = branch_dest (opcode, insn, pc, breaks[0]);
+
+ if (branch_bp != -1)
+ {
+ breaks[1] = branch_bp;
+ bc_insn_count++;
+ last_breakpoint++;
+ }
+ }
+
+ if ((insn & STWCX_MASK) == STWCX_INSTRUCTION
+ || (insn & STWCX_MASK) == STDCX_INSTRUCTION)
+ break;
+ }
+
+ /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */
+ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
+ && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
+ return 0;
+
+ loc += PPC_INSN_SIZE;
+ insn = read_memory_integer (loc, PPC_INSN_SIZE);
+
+ /* Insert a breakpoint right after the end of the atomic sequence. */
+ breaks[0] = loc;
+
+ /* Check for duplicated breakpoints. */
+ if (last_breakpoint && (breaks[1] == breaks[0]))
+ last_breakpoint = 0;
+
+ /* Effectively inserts the breakpoints. */
+ for (index = 0; index <= last_breakpoint; index++)
+ insert_single_step_breakpoint (breaks[index]);
+
+ return 1;
+}
+
+/* AIX does not support PT_STEP. Simulate it. */
int
rs6000_software_single_step (struct regcache *regcache)
@@ -724,6 +812,9 @@ rs6000_software_single_step (struct regc
insn = read_memory_integer (loc, 4);
+ if (deal_with_atomic_sequence (regcache))
+ return 1;
+
breaks[0] = loc + breakp_sz;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
@@ -3448,6 +3539,9 @@ rs6000_gdbarch_init (struct gdbarch_info
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);
+ /* Handles single stepping of atomic sequences. */
+ set_gdbarch_software_single_step (gdbarch, deal_with_atomic_sequence);
+
/* Handle the 64-bit SVR4 minimal-symbol convention of using "FN"
for the descriptor and ".FN" for the entry-point -- a user
specifying "break FN" will unexpectedly end up with a breakpoint