Commit c0ce998e94fadb7fdc83dbc7455372af933f8fa9

Authored by aliguori
1 parent 31280d92

Use sys-queue.h for break/watchpoint managment (Jan Kiszka)

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 <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5799 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-defs.h
... ... @@ -28,6 +28,7 @@
28 28 #include <setjmp.h>
29 29 #include <inttypes.h>
30 30 #include "osdep.h"
  31 +#include "sys-queue.h"
31 32  
32 33 #ifndef TARGET_LONG_BITS
33 34 #error TARGET_LONG_BITS must be defined before including this header
... ... @@ -146,14 +147,14 @@ struct KVMState;
146 147 typedef struct CPUBreakpoint {
147 148 target_ulong pc;
148 149 int flags; /* BP_* */
149   - struct CPUBreakpoint *prev, *next;
  150 + TAILQ_ENTRY(CPUBreakpoint) entry;
150 151 } CPUBreakpoint;
151 152  
152 153 typedef struct CPUWatchpoint {
153 154 target_ulong vaddr;
154 155 target_ulong len_mask;
155 156 int flags; /* BP_* */
156   - struct CPUWatchpoint *prev, *next;
  157 + TAILQ_ENTRY(CPUWatchpoint) entry;
157 158 } CPUWatchpoint;
158 159  
159 160 #define CPU_TEMP_BUF_NLONGS 128
... ... @@ -188,10 +189,10 @@ typedef struct CPUWatchpoint {
188 189 \
189 190 /* from this point: preserved by CPU reset */ \
190 191 /* ice debug support */ \
191   - CPUBreakpoint *breakpoints; \
  192 + TAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
192 193 int singlestep_enabled; \
193 194 \
194   - CPUWatchpoint *watchpoints; \
  195 + TAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
195 196 CPUWatchpoint *watchpoint_hit; \
196 197 \
197 198 struct GDBRegisterState *gdb_regs; \
... ...
cpu-exec.c
... ... @@ -198,7 +198,7 @@ static void cpu_handle_debug_exception(CPUState *env)
198 198 CPUWatchpoint *wp;
199 199  
200 200 if (!env->watchpoint_hit)
201   - for (wp = env->watchpoints; wp != NULL; wp = wp->next)
  201 + TAILQ_FOREACH(wp, &env->watchpoints, entry)
202 202 wp->flags &= ~BP_WATCHPOINT_HIT;
203 203  
204 204 if (debug_excp_handler)
... ...
... ... @@ -537,6 +537,8 @@ void cpu_exec_init(CPUState *env)
537 537 cpu_index++;
538 538 }
539 539 env->cpu_index = cpu_index;
  540 + TAILQ_INIT(&env->breakpoints);
  541 + TAILQ_INIT(&env->watchpoints);
540 542 *penv = env;
541 543 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
542 544 register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
... ... @@ -1302,7 +1304,7 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
1302 1304 int flags, CPUWatchpoint **watchpoint)
1303 1305 {
1304 1306 target_ulong len_mask = ~(len - 1);
1305   - CPUWatchpoint *wp, *prev_wp;
  1307 + CPUWatchpoint *wp;
1306 1308  
1307 1309 /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
1308 1310 if ((len != 1 && len != 2 && len != 4 && len != 8) || (addr & ~len_mask)) {
... ... @@ -1319,25 +1321,10 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
1319 1321 wp->flags = flags;
1320 1322  
1321 1323 /* keep all GDB-injected watchpoints in front */
1322   - if (!(flags & BP_GDB) && env->watchpoints) {
1323   - prev_wp = env->watchpoints;
1324   - while (prev_wp->next != NULL && (prev_wp->next->flags & BP_GDB))
1325   - prev_wp = prev_wp->next;
1326   - } else {
1327   - prev_wp = NULL;
1328   - }
1329   -
1330   - /* Insert new watchpoint */
1331   - if (prev_wp) {
1332   - wp->next = prev_wp->next;
1333   - prev_wp->next = wp;
1334   - } else {
1335   - wp->next = env->watchpoints;
1336   - env->watchpoints = wp;
1337   - }
1338   - if (wp->next)
1339   - wp->next->prev = wp;
1340   - wp->prev = prev_wp;
  1324 + if (flags & BP_GDB)
  1325 + TAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
  1326 + else
  1327 + TAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
1341 1328  
1342 1329 tlb_flush_page(env, addr);
1343 1330  
... ... @@ -1353,7 +1340,7 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,
1353 1340 target_ulong len_mask = ~(len - 1);
1354 1341 CPUWatchpoint *wp;
1355 1342  
1356   - for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
  1343 + TAILQ_FOREACH(wp, &env->watchpoints, entry) {
1357 1344 if (addr == wp->vaddr && len_mask == wp->len_mask
1358 1345 && flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
1359 1346 cpu_watchpoint_remove_by_ref(env, wp);
... ... @@ -1366,12 +1353,7 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,
1366 1353 /* Remove a specific watchpoint by reference. */
1367 1354 void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint)
1368 1355 {
1369   - if (watchpoint->next)
1370   - watchpoint->next->prev = watchpoint->prev;
1371   - if (watchpoint->prev)
1372   - watchpoint->prev->next = watchpoint->next;
1373   - else
1374   - env->watchpoints = watchpoint->next;
  1356 + TAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
1375 1357  
1376 1358 tlb_flush_page(env, watchpoint->vaddr);
1377 1359  
... ... @@ -1381,11 +1363,12 @@ void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint)
1381 1363 /* Remove all matching watchpoints. */
1382 1364 void cpu_watchpoint_remove_all(CPUState *env, int mask)
1383 1365 {
1384   - CPUWatchpoint *wp;
  1366 + CPUWatchpoint *wp, *next;
1385 1367  
1386   - for (wp = env->watchpoints; wp != NULL; wp = wp->next)
  1368 + TAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
1387 1369 if (wp->flags & mask)
1388 1370 cpu_watchpoint_remove_by_ref(env, wp);
  1371 + }
1389 1372 }
1390 1373  
1391 1374 /* Add a breakpoint. */
... ... @@ -1393,7 +1376,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
1393 1376 CPUBreakpoint **breakpoint)
1394 1377 {
1395 1378 #if defined(TARGET_HAS_ICE)
1396   - CPUBreakpoint *bp, *prev_bp;
  1379 + CPUBreakpoint *bp;
1397 1380  
1398 1381 bp = qemu_malloc(sizeof(*bp));
1399 1382 if (!bp)
... ... @@ -1403,25 +1386,10 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
1403 1386 bp->flags = flags;
1404 1387  
1405 1388 /* keep all GDB-injected breakpoints in front */
1406   - if (!(flags & BP_GDB) && env->breakpoints) {
1407   - prev_bp = env->breakpoints;
1408   - while (prev_bp->next != NULL && (prev_bp->next->flags & BP_GDB))
1409   - prev_bp = prev_bp->next;
1410   - } else {
1411   - prev_bp = NULL;
1412   - }
1413   -
1414   - /* Insert new breakpoint */
1415   - if (prev_bp) {
1416   - bp->next = prev_bp->next;
1417   - prev_bp->next = bp;
1418   - } else {
1419   - bp->next = env->breakpoints;
1420   - env->breakpoints = bp;
1421   - }
1422   - if (bp->next)
1423   - bp->next->prev = bp;
1424   - bp->prev = prev_bp;
  1389 + if (flags & BP_GDB)
  1390 + TAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
  1391 + else
  1392 + TAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
1425 1393  
1426 1394 breakpoint_invalidate(env, pc);
1427 1395  
... ... @@ -1439,7 +1407,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags)
1439 1407 #if defined(TARGET_HAS_ICE)
1440 1408 CPUBreakpoint *bp;
1441 1409  
1442   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  1410 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
1443 1411 if (bp->pc == pc && bp->flags == flags) {
1444 1412 cpu_breakpoint_remove_by_ref(env, bp);
1445 1413 return 0;
... ... @@ -1455,12 +1423,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags)
1455 1423 void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)
1456 1424 {
1457 1425 #if defined(TARGET_HAS_ICE)
1458   - if (breakpoint->next)
1459   - breakpoint->next->prev = breakpoint->prev;
1460   - if (breakpoint->prev)
1461   - breakpoint->prev->next = breakpoint->next;
1462   - else
1463   - env->breakpoints = breakpoint->next;
  1426 + TAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
1464 1427  
1465 1428 breakpoint_invalidate(env, breakpoint->pc);
1466 1429  
... ... @@ -1472,11 +1435,12 @@ void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)
1472 1435 void cpu_breakpoint_remove_all(CPUState *env, int mask)
1473 1436 {
1474 1437 #if defined(TARGET_HAS_ICE)
1475   - CPUBreakpoint *bp;
  1438 + CPUBreakpoint *bp, *next;
1476 1439  
1477   - for (bp = env->breakpoints; bp != NULL; bp = bp->next)
  1440 + TAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
1478 1441 if (bp->flags & mask)
1479 1442 cpu_breakpoint_remove_by_ref(env, bp);
  1443 + }
1480 1444 #endif
1481 1445 }
1482 1446  
... ... @@ -2005,7 +1969,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
2005 1969 code_address = address;
2006 1970 /* Make accesses to pages with watchpoints go via the
2007 1971 watchpoint trap routines. */
2008   - for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
  1972 + TAILQ_FOREACH(wp, &env->watchpoints, entry) {
2009 1973 if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
2010 1974 iotlb = io_mem_watch + paddr;
2011 1975 /* TODO: The memory case can be optimized by not trapping
... ... @@ -2552,7 +2516,7 @@ static void check_watchpoint(int offset, int len_mask, int flags)
2552 2516 return;
2553 2517 }
2554 2518 vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
2555   - for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
  2519 + TAILQ_FOREACH(wp, &env->watchpoints, entry) {
2556 2520 if ((vaddr == (wp->vaddr & len_mask) ||
2557 2521 (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
2558 2522 wp->flags |= BP_WATCHPOINT_HIT;
... ...
target-alpha/translate.c
... ... @@ -2363,8 +2363,8 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
2363 2363  
2364 2364 gen_icount_start();
2365 2365 for (ret = 0; ret == 0;) {
2366   - if (unlikely(env->breakpoints)) {
2367   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  2366 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  2367 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
2368 2368 if (bp->pc == ctx.pc) {
2369 2369 gen_excp(&ctx, EXCP_DEBUG, 0);
2370 2370 break;
... ...
target-arm/translate.c
... ... @@ -8677,8 +8677,8 @@ static inline void gen_intermediate_code_internal(CPUState *env,
8677 8677 }
8678 8678 #endif
8679 8679  
8680   - if (unlikely(env->breakpoints)) {
8681   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  8680 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  8681 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8682 8682 if (bp->pc == dc->pc) {
8683 8683 gen_set_condexec(dc);
8684 8684 gen_set_pc_im(dc->pc);
... ...
target-cris/translate.c
... ... @@ -3189,8 +3189,8 @@ static void check_breakpoint(CPUState *env, DisasContext *dc)
3189 3189 {
3190 3190 CPUBreakpoint *bp;
3191 3191  
3192   - if (unlikely(env->breakpoints)) {
3193   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  3192 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  3193 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
3194 3194 if (bp->pc == dc->pc) {
3195 3195 cris_evaluate_flags (dc);
3196 3196 tcg_gen_movi_tl(env_pc, dc->pc);
... ...
target-i386/helper.c
... ... @@ -1364,7 +1364,7 @@ static void breakpoint_handler(CPUState *env)
1364 1364 cpu_resume_from_signal(env, NULL);
1365 1365 }
1366 1366 } else {
1367   - for (bp = env->breakpoints; bp != NULL; bp = bp->next)
  1367 + TAILQ_FOREACH(bp, &env->breakpoints, entry)
1368 1368 if (bp->pc == env->eip) {
1369 1369 if (bp->flags & BP_CPU) {
1370 1370 check_hw_breakpoints(env, 1);
... ...
target-i386/translate.c
... ... @@ -7606,8 +7606,8 @@ static inline void gen_intermediate_code_internal(CPUState *env,
7606 7606  
7607 7607 gen_icount_start();
7608 7608 for(;;) {
7609   - if (unlikely(env->breakpoints)) {
7610   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  7609 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  7610 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
7611 7611 if (bp->pc == pc_ptr) {
7612 7612 gen_debug(dc, pc_ptr - dc->cs_base);
7613 7613 break;
... ...
target-m68k/translate.c
... ... @@ -2999,8 +2999,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2999 2999 do {
3000 3000 pc_offset = dc->pc - pc_start;
3001 3001 gen_throws_exception = NULL;
3002   - if (unlikely(env->breakpoints)) {
3003   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  3002 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  3003 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
3004 3004 if (bp->pc == dc->pc) {
3005 3005 gen_exception(dc, dc->pc, EXCP_DEBUG);
3006 3006 dc->is_jmp = DISAS_JUMP;
... ...
target-mips/translate.c
... ... @@ -8286,8 +8286,8 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8286 8286 #endif
8287 8287 gen_icount_start();
8288 8288 while (ctx.bstate == BS_NONE) {
8289   - if (unlikely(env->breakpoints)) {
8290   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  8289 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  8290 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8291 8291 if (bp->pc == ctx.pc) {
8292 8292 save_cpu_state(&ctx, 1);
8293 8293 ctx.bstate = BS_BRANCH;
... ...
target-ppc/translate.c
... ... @@ -7562,8 +7562,8 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
7562 7562 gen_icount_start();
7563 7563 /* Set env in case of segfault during code fetch */
7564 7564 while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
7565   - if (unlikely(env->breakpoints)) {
7566   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  7565 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  7566 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
7567 7567 if (bp->pc == ctx.nip) {
7568 7568 gen_update_nip(&ctx, ctx.nip);
7569 7569 gen_helper_raise_debug();
... ...
target-sh4/translate.c
... ... @@ -1776,8 +1776,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1776 1776 max_insns = CF_COUNT_MASK;
1777 1777 gen_icount_start();
1778 1778 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1779   - if (unlikely(env->breakpoints)) {
1780   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  1779 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  1780 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
1781 1781 if (ctx.pc == bp->pc) {
1782 1782 /* We have hit a breakpoint - make sure PC is up-to-date */
1783 1783 tcg_gen_movi_i32(cpu_pc, ctx.pc);
... ...
target-sparc/translate.c
... ... @@ -4816,8 +4816,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4816 4816 max_insns = CF_COUNT_MASK;
4817 4817 gen_icount_start();
4818 4818 do {
4819   - if (unlikely(env->breakpoints)) {
4820   - for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
  4819 + if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
  4820 + TAILQ_FOREACH(bp, &env->breakpoints, entry) {
4821 4821 if (bp->pc == dc->pc) {
4822 4822 if (dc->pc != pc_start)
4823 4823 save_state(dc, cpu_cond);
... ...