This switches cpu_break/watchpoint_* to TAILQ wrappers, simplifying the
code and also fixing a use after release issue in
cpu_break/watchpoint_remove_all.
Signed-off-by: Jan Kiszka <[EMAIL PROTECTED]>
---
qemu/cpu-defs.h | 9 ++--
qemu/cpu-exec.c | 2 -
qemu/exec.c | 84 ++++++++++++-----------------------------
qemu/target-alpha/translate.c | 4 +-
qemu/target-arm/translate.c | 4 +-
qemu/target-cris/translate.c | 4 +-
qemu/target-i386/helper.c | 2 -
qemu/target-i386/translate.c | 4 +-
qemu/target-m68k/translate.c | 4 +-
qemu/target-mips/translate.c | 4 +-
qemu/target-ppc/translate.c | 4 +-
qemu/target-sh4/translate.c | 4 +-
qemu/target-sparc/translate.c | 4 +-
13 files changed, 49 insertions(+), 84 deletions(-)
diff --git a/qemu/cpu-defs.h b/qemu/cpu-defs.h
index 902d2b4..695fbab 100644
--- a/qemu/cpu-defs.h
+++ b/qemu/cpu-defs.h
@@ -29,6 +29,7 @@
#include <inttypes.h>
#include <pthread.h>
#include "osdep.h"
+#include "sys-queue.h"
#ifndef TARGET_LONG_BITS
#error TARGET_LONG_BITS must be defined before including this header
@@ -147,14 +148,14 @@ struct KVMState;
typedef struct CPUBreakpoint {
target_ulong pc;
int flags; /* BP_* */
- struct CPUBreakpoint *prev, *next;
+ TAILQ_ENTRY(CPUBreakpoint) entry;
} CPUBreakpoint;
typedef struct CPUWatchpoint {
target_ulong vaddr;
target_ulong len_mask;
int flags; /* BP_* */
- struct CPUWatchpoint *prev, *next;
+ TAILQ_ENTRY(CPUWatchpoint) entry;
} CPUWatchpoint;
/* forward decleration */
@@ -203,10 +204,10 @@ struct KVMCPUState {
\
/* from this point: preserved by CPU reset */ \
/* ice debug support */ \
- CPUBreakpoint *breakpoints; \
+ TAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
int singlestep_enabled; \
\
- CPUWatchpoint *watchpoints; \
+ TAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
CPUWatchpoint *watchpoint_hit; \
\
struct GDBRegisterState *gdb_regs; \
diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c
index 5377172..d5eb16c 100644
--- a/qemu/cpu-exec.c
+++ b/qemu/cpu-exec.c
@@ -202,7 +202,7 @@ static void cpu_handle_debug_exception(CPUState *env)
CPUWatchpoint *wp;
if (!env->watchpoint_hit)
- for (wp = env->watchpoints; wp != NULL; wp = wp->next)
+ TAILQ_FOREACH(wp, &env->watchpoints, entry)
wp->flags &= ~BP_WATCHPOINT_HIT;
if (debug_excp_handler)
diff --git a/qemu/exec.c b/qemu/exec.c
index 8122d88..c1ce098 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -548,6 +548,8 @@ void cpu_exec_init(CPUState *env)
cpu_index++;
}
env->cpu_index = cpu_index;
+ TAILQ_INIT(&env->breakpoints);
+ TAILQ_INIT(&env->watchpoints);
#ifdef __WIN32
env->thread_id = GetCurrentProcessId();
#else
@@ -1318,7 +1320,7 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong
addr, target_ulong len,
int flags, CPUWatchpoint **watchpoint)
{
target_ulong len_mask = ~(len - 1);
- CPUWatchpoint *wp, *prev_wp;
+ CPUWatchpoint *wp;
/* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
if ((len != 1 && len != 2 && len != 4 && len != 8) || (addr & ~len_mask)) {
@@ -1335,25 +1337,10 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong
addr, target_ulong len,
wp->flags = flags;
/* keep all GDB-injected watchpoints in front */
- if (!(flags & BP_GDB) && env->watchpoints) {
- prev_wp = env->watchpoints;
- while (prev_wp->next != NULL && (prev_wp->next->flags & BP_GDB))
- prev_wp = prev_wp->next;
- } else {
- prev_wp = NULL;
- }
-
- /* Insert new watchpoint */
- if (prev_wp) {
- wp->next = prev_wp->next;
- prev_wp->next = wp;
- } else {
- wp->next = env->watchpoints;
- env->watchpoints = wp;
- }
- if (wp->next)
- wp->next->prev = wp;
- wp->prev = prev_wp;
+ if (flags & BP_GDB)
+ TAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
+ else
+ TAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
tlb_flush_page(env, addr);
@@ -1369,7 +1356,7 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong
addr, target_ulong len,
target_ulong len_mask = ~(len - 1);
CPUWatchpoint *wp;
- for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
+ TAILQ_FOREACH(wp, &env->watchpoints, entry) {
if (addr == wp->vaddr && len_mask == wp->len_mask
&& flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
cpu_watchpoint_remove_by_ref(env, wp);
@@ -1382,12 +1369,7 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong
addr, target_ulong len,
/* Remove a specific watchpoint by reference. */
void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint)
{
- if (watchpoint->next)
- watchpoint->next->prev = watchpoint->prev;
- if (watchpoint->prev)
- watchpoint->prev->next = watchpoint->next;
- else
- env->watchpoints = watchpoint->next;
+ TAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
tlb_flush_page(env, watchpoint->vaddr);
@@ -1397,11 +1379,12 @@ void cpu_watchpoint_remove_by_ref(CPUState *env,
CPUWatchpoint *watchpoint)
/* Remove all matching watchpoints. */
void cpu_watchpoint_remove_all(CPUState *env, int mask)
{
- CPUWatchpoint *wp;
+ CPUWatchpoint *wp, *next;
- for (wp = env->watchpoints; wp != NULL; wp = wp->next)
+ TAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
if (wp->flags & mask)
cpu_watchpoint_remove_by_ref(env, wp);
+ }
}
/* Add a breakpoint. */
@@ -1409,7 +1392,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc,
int flags,
CPUBreakpoint **breakpoint)
{
#if defined(TARGET_HAS_ICE)
- CPUBreakpoint *bp, *prev_bp;
+ CPUBreakpoint *bp;
bp = qemu_malloc(sizeof(*bp));
if (!bp)
@@ -1419,25 +1402,10 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong
pc, int flags,
bp->flags = flags;
/* keep all GDB-injected breakpoints in front */
- if (!(flags & BP_GDB) && env->breakpoints) {
- prev_bp = env->breakpoints;
- while (prev_bp->next != NULL && (prev_bp->next->flags & BP_GDB))
- prev_bp = prev_bp->next;
- } else {
- prev_bp = NULL;
- }
-
- /* Insert new breakpoint */
- if (prev_bp) {
- bp->next = prev_bp->next;
- prev_bp->next = bp;
- } else {
- bp->next = env->breakpoints;
- env->breakpoints = bp;
- }
- if (bp->next)
- bp->next->prev = bp;
- bp->prev = prev_bp;
+ if (flags & BP_GDB)
+ TAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
+ else
+ TAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
if (kvm_enabled())
kvm_update_debugger(env);
@@ -1458,7 +1426,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc,
int flags)
#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == pc && bp->flags == flags) {
cpu_breakpoint_remove_by_ref(env, bp);
return 0;
@@ -1474,12 +1442,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong
pc, int flags)
void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)
{
#if defined(TARGET_HAS_ICE)
- if (breakpoint->next)
- breakpoint->next->prev = breakpoint->prev;
- if (breakpoint->prev)
- breakpoint->prev->next = breakpoint->next;
- else
- env->breakpoints = breakpoint->next;
+ TAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
if (kvm_enabled())
kvm_update_debugger(env);
@@ -1494,11 +1457,12 @@ void cpu_breakpoint_remove_by_ref(CPUState *env,
CPUBreakpoint *breakpoint)
void cpu_breakpoint_remove_all(CPUState *env, int mask)
{
#if defined(TARGET_HAS_ICE)
- CPUBreakpoint *bp;
+ CPUBreakpoint *bp, *next;
- for (bp = env->breakpoints; bp != NULL; bp = bp->next)
+ TAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
if (bp->flags & mask)
cpu_breakpoint_remove_by_ref(env, bp);
+ }
#endif
}
@@ -2029,7 +1993,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
code_address = address;
/* Make accesses to pages with watchpoints go via the
watchpoint trap routines. */
- for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
+ TAILQ_FOREACH(wp, &env->watchpoints, entry) {
if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
iotlb = io_mem_watch + paddr;
/* TODO: The memory case can be optimized by not trapping
@@ -2576,7 +2540,7 @@ static void check_watchpoint(int offset, int len_mask,
int flags)
return;
}
vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
- for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
+ TAILQ_FOREACH(wp, &env->watchpoints, entry) {
if ((vaddr == (wp->vaddr & len_mask) ||
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
wp->flags |= BP_WATCHPOINT_HIT;
diff --git a/qemu/target-alpha/translate.c b/qemu/target-alpha/translate.c
index 3b90f62..7a0e54f 100644
--- a/qemu/target-alpha/translate.c
+++ b/qemu/target-alpha/translate.c
@@ -2363,8 +2363,8 @@ static always_inline void gen_intermediate_code_internal
(CPUState *env,
gen_icount_start();
for (ret = 0; ret == 0;) {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == ctx.pc) {
gen_excp(&ctx, EXCP_DEBUG, 0);
break;
diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c
index 54eb067..f984de7 100644
--- a/qemu/target-arm/translate.c
+++ b/qemu/target-arm/translate.c
@@ -8677,8 +8677,8 @@ static inline void
gen_intermediate_code_internal(CPUState *env,
}
#endif
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == dc->pc) {
gen_set_condexec(dc);
gen_set_pc_im(dc->pc);
diff --git a/qemu/target-cris/translate.c b/qemu/target-cris/translate.c
index ac258a9..242ef9c 100644
--- a/qemu/target-cris/translate.c
+++ b/qemu/target-cris/translate.c
@@ -3189,8 +3189,8 @@ static void check_breakpoint(CPUState *env, DisasContext
*dc)
{
CPUBreakpoint *bp;
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == dc->pc) {
cris_evaluate_flags (dc);
tcg_gen_movi_tl(env_pc, dc->pc);
diff --git a/qemu/target-i386/helper.c b/qemu/target-i386/helper.c
index 4124b72..0d3e3cc 100644
--- a/qemu/target-i386/helper.c
+++ b/qemu/target-i386/helper.c
@@ -1371,7 +1371,7 @@ static void breakpoint_handler(CPUState *env)
cpu_resume_from_signal(env, NULL);
}
} else {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next)
+ TAILQ_FOREACH(bp, &env->breakpoints, entry)
if (bp->pc == env->eip) {
if (bp->flags & BP_CPU) {
check_hw_breakpoints(env, 1);
diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c
index 0de238b..612811b 100644
--- a/qemu/target-i386/translate.c
+++ b/qemu/target-i386/translate.c
@@ -7606,8 +7606,8 @@ static inline void
gen_intermediate_code_internal(CPUState *env,
gen_icount_start();
for(;;) {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == pc_ptr) {
gen_debug(dc, pc_ptr - dc->cs_base);
break;
diff --git a/qemu/target-m68k/translate.c b/qemu/target-m68k/translate.c
index a14f6c5..5c27a7e 100644
--- a/qemu/target-m68k/translate.c
+++ b/qemu/target-m68k/translate.c
@@ -2999,8 +2999,8 @@ gen_intermediate_code_internal(CPUState *env,
TranslationBlock *tb,
do {
pc_offset = dc->pc - pc_start;
gen_throws_exception = NULL;
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == dc->pc) {
gen_exception(dc, dc->pc, EXCP_DEBUG);
dc->is_jmp = DISAS_JUMP;
diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c
index cc7e71c..418b9ef 100644
--- a/qemu/target-mips/translate.c
+++ b/qemu/target-mips/translate.c
@@ -8286,8 +8286,8 @@ gen_intermediate_code_internal (CPUState *env,
TranslationBlock *tb,
#endif
gen_icount_start();
while (ctx.bstate == BS_NONE) {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == ctx.pc) {
save_cpu_state(&ctx, 1);
ctx.bstate = BS_BRANCH;
diff --git a/qemu/target-ppc/translate.c b/qemu/target-ppc/translate.c
index aaec6d8..86b555b 100644
--- a/qemu/target-ppc/translate.c
+++ b/qemu/target-ppc/translate.c
@@ -7470,8 +7470,8 @@ static always_inline void gen_intermediate_code_internal
(CPUState *env,
gen_icount_start();
/* Set env in case of segfault during code fetch */
while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == ctx.nip) {
gen_update_nip(&ctx, ctx.nip);
gen_helper_raise_debug();
diff --git a/qemu/target-sh4/translate.c b/qemu/target-sh4/translate.c
index bbfd745..505b196 100644
--- a/qemu/target-sh4/translate.c
+++ b/qemu/target-sh4/translate.c
@@ -1776,8 +1776,8 @@ gen_intermediate_code_internal(CPUState * env,
TranslationBlock * tb,
max_insns = CF_COUNT_MASK;
gen_icount_start();
while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (ctx.pc == bp->pc) {
/* We have hit a breakpoint - make sure PC is up-to-date */
tcg_gen_movi_i32(cpu_pc, ctx.pc);
diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c
index e94e3c5..07b2624 100644
--- a/qemu/target-sparc/translate.c
+++ b/qemu/target-sparc/translate.c
@@ -4816,8 +4816,8 @@ static inline void
gen_intermediate_code_internal(TranslationBlock * tb,
max_insns = CF_COUNT_MASK;
gen_icount_start();
do {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == dc->pc) {
if (dc->pc != pc_start)
save_state(dc, cpu_cond);
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html