[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] PATCH1 v2 infrastructure for Evaluate breakpoint co
From: |
Anna Neiman |
Subject: |
[Qemu-devel] [PATCH] PATCH1 v2 infrastructure for Evaluate breakpoint cond on target |
Date: |
Wed, 27 Feb 2013 12:16:13 +0200 |
Signed-off-by: Anna Neiman <address@hidden>
---
exec.c | 5 +----
gdbstub.c | 22 +++-------------------
2 files changed, 4 insertions(+), 23 deletions(-)
diff --git a/exec.c b/exec.c
index 4289c87..c7d1284 100644
--- a/exec.c
+++ b/exec.c
@@ -458,10 +458,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env,
CPUBreakpoint *breakpoint)
breakpoint_invalidate(env, breakpoint->pc);
- if (breakpoint->cond_len != 0 && breakpoint->cond_exp != NULL) {
- g_free(breakpoint->cond_exp);
- }
-
+ g_free(breakpoint->cond_exp);
g_free(breakpoint);
#endif
diff --git a/gdbstub.c b/gdbstub.c
index e2dac86..4d33568 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2095,7 +2095,6 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
uint8_t *bp_cond_expr = NULL;
int bp_cond_len = 0;
- int i = 0 ;
#ifdef DEBUG_GDB
printf("command='%s'\n", line_buf);
@@ -2318,14 +2317,8 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
if (*p == ',')
p++;
len = strtoull(p, (char **)&p, 16);
- while (isspace(*p)) {
- p++;
- }
if (ch == 'Z' && *p == ';') {
p++;
- while (isspace(*p)) {
- p++;
- }
if (*p == 'X') {
p++;
bp_cond_len = strtoul(p, (char **)&p, 16);
@@ -2334,20 +2327,11 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
}
if (bp_cond_len > 0) {
int bp_cond_size = sizeof(uint8_t) * bp_cond_len;
- bp_cond_expr = (uint8_t *)g_malloc(bp_cond_size);
+ bp_cond_expr = g_malloc(bp_cond_size);
memset(bp_cond_expr, 0, bp_cond_size);
- for (i = 0 ; i < bp_cond_len ; i++) {
- if (!isxdigit(*p) || !isxdigit(*(p + 1))) {
- bp_cond_len = 0 ;
- g_free(bp_cond_expr);
- bp_cond_expr = NULL;
- error_report("Error in breakpoint condition");
- } else {
- hextomem(bp_cond_expr+i, p, 1);
- p += 2;
- }
- }
+ hextomem(bp_cond_expr, p, bp_cond_len);
+ p += (bp_cond_len << 1);
}
#ifdef DEBUG_GDB
bp_agent_dump_bytecode(bp_cond_len, bp_cond_expr);
--
1.7.9.5
[PATCH] PATCH1 - infrastructure for Evaluate breakpoint condition
on target.OPC_MAX_SIZE - size of translation buffer - was
increased because condition translated bytecode should be
executed in one block
Signed-off-by: Anna Neiman <address@hidden>
---
exec.c | 16 ++++++++++++-
gdbstub.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
include/exec/cpu-all.h | 1 +
include/exec/cpu-defs.h | 20 +++++++++++++++++
include/exec/exec-all.h | 2 +-
target-i386/helper.c | 2 +-
tcg/tcg-op.h | 10 +++++++++
tcg/tcg.h | 6 +++++
8 files changed, 106 insertions(+), 8 deletions(-)
diff --git a/exec.c b/exec.c
index a41bcb8..4289c87 100644
--- a/exec.c
+++ b/exec.c
@@ -398,6 +398,7 @@ void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
/* Add a breakpoint. */
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
+ long cond_len, uint8_t *cond_exp,
CPUBreakpoint **breakpoint)
{
#if defined(TARGET_HAS_ICE)
@@ -407,6 +408,13 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong
pc, int flags,
bp->pc = pc;
bp->flags = flags;
+ bp->cond_len = cond_len;
+ if (cond_exp == NULL || cond_len == 0) {
+ bp->cond_exp = NULL;
+ } else {
+ bp->cond_exp = g_malloc(sizeof(uint8_t) * cond_len);
+ memcpy(bp->cond_exp, cond_exp, sizeof(uint8_t) * cond_len);
+ }
/* keep all GDB-injected breakpoints in front */
if (flags & BP_GDB)
@@ -450,6 +458,11 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env,
CPUBreakpoint *breakpoint)
breakpoint_invalidate(env, breakpoint->pc);
+ if (breakpoint->cond_len != 0 && breakpoint->cond_exp != NULL) {
+ g_free(breakpoint->cond_exp);
+ }
+
+
g_free(breakpoint);
#endif
}
@@ -551,7 +564,8 @@ CPUArchState *cpu_copy(CPUArchState *env)
QTAILQ_INIT(&env->watchpoints);
#if defined(TARGET_HAS_ICE)
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
- cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL);
+ cpu_breakpoint_insert(new_env, bp->pc, bp->flags,
+ bp->cond_len, bp->cond_exp, NULL);
}
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1,
diff --git a/gdbstub.c b/gdbstub.c
index 32dfea9..814f596 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1941,7 +1941,8 @@ static const int xlat_gdb_type[] = {
};
#endif
-static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
+static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type,
+ long cond_len, uint8_t *cond_exp)
{
CPUArchState *env;
int err = 0;
@@ -1953,7 +1954,8 @@ static int gdb_breakpoint_insert(target_ulong addr,
target_ulong len, int type)
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
for (env = first_cpu; env != NULL; env = env->next_cpu) {
- err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
+ err = cpu_breakpoint_insert(env, addr, BP_GDB,
+ cond_len, cond_exp, NULL);
if (err)
break;
}
@@ -2089,6 +2091,10 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
uint8_t *registers;
target_ulong addr, len;
+ uint8_t *bp_cond_expr = NULL;
+ int bp_cond_len = 0;
+ int i = 0 ;
+
#ifdef DEBUG_GDB
printf("command='%s'\n", line_buf);
#endif
@@ -2310,16 +2316,54 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
if (*p == ',')
p++;
len = strtoull(p, (char **)&p, 16);
- if (ch == 'Z')
- res = gdb_breakpoint_insert(addr, len, type);
- else
+ while (isspace(*p)) {
+ p++;
+ }
+ if (ch == 'Z' && *p == ';') {
+ p++;
+ while (isspace(*p)) {
+ p++;
+ }
+ if (*p == 'X') {
+ p++;
+ bp_cond_len = strtoul(p, (char **)&p, 16);
+ if (*p == ',') {
+ p++;
+ }
+ if (bp_cond_len > 0) {
+ int bp_cond_size = sizeof(uint8_t) * bp_cond_len;
+ bp_cond_expr = (uint8_t *)g_malloc(bp_cond_size);
+ memset(bp_cond_expr, 0, bp_cond_size);
+
+ for (i = 0 ; i < bp_cond_len ; i++) {
+ if (!isxdigit(*p) || !isxdigit(*(p + 1))) {
+ bp_cond_len = 0 ;
+ g_free(bp_cond_expr);
+ bp_cond_expr = NULL;
+ error_report("Error in breakpoint condition");
+ } else {
+ hextomem(bp_cond_expr+i, p, 1);
+ p += 2;
+ }
+ }
+ }
+ }
+ }
+ if (ch == 'Z') {
+ res = gdb_breakpoint_insert(addr, len, type,
+ bp_cond_len, bp_cond_expr);
+ } else {
res = gdb_breakpoint_remove(addr, len, type);
+ }
if (res >= 0)
put_packet(s, "OK");
else if (res == -ENOSYS)
put_packet(s, "");
else
put_packet(s, "E22");
+ if (bp_cond_expr != NULL) {
+ g_free(bp_cond_expr);
+ }
break;
case 'H':
type = *p++;
@@ -2445,6 +2489,9 @@ static int gdb_handle_packet(GDBState *s, const char
*line_buf)
#endif /* !CONFIG_USER_ONLY */
if (strncmp(p, "Supported", 9) == 0) {
snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
+
+ /* conditional breakpoint evaluation on target*/
+ pstrcat(buf, sizeof(buf), ";ConditionalBreakpoints+");
#ifdef GDB_CORE_XML
pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
#endif
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 249e046..383c4c1 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -448,6 +448,7 @@ void cpu_exit(CPUArchState *s);
#define BP_CPU 0x20
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
+ long cond_len, uint8_t *cond_exp,
CPUBreakpoint **breakpoint);
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags);
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint
*breakpoint);
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 3dc9656..0bf63c2 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -136,9 +136,13 @@ typedef struct icount_decr_u16 {
typedef struct CPUBreakpoint {
target_ulong pc;
int flags; /* BP_* */
+ int cond_len;
+ uint8_t *cond_exp;
QTAILQ_ENTRY(CPUBreakpoint) entry;
} CPUBreakpoint;
+int bp_has_cond(CPUBreakpoint *bp);
+
typedef struct CPUWatchpoint {
target_ulong vaddr;
target_ulong len_mask;
@@ -146,6 +150,18 @@ typedef struct CPUWatchpoint {
QTAILQ_ENTRY(CPUWatchpoint) entry;
} CPUWatchpoint;
+
+
+typedef double target_double;
+
+typedef union BPAgentStackElementType {
+ target_long l;
+ target_double d;
+} BPAgentStackElementType;
+
+
+#define BP_AGENT_MAX_STACK_SIZE 1024
+
#define CPU_TEMP_BUF_NLONGS 128
#define CPU_COMMON \
/* soft mmu support */ \
@@ -191,6 +207,10 @@ typedef struct CPUWatchpoint {
/* user data */ \
void *opaque; \
\
+ BPAgentStackElementType bp_agent_stack[BP_AGENT_MAX_STACK_SIZE]; \
+ BPAgentStackElementType *bp_agent_stack_current; \
+ /*bp_agent_stack_current is the current location in bp_agent_stack */ \
+ int bp_agent_error; /* error in evaluation - ex., divide by zero*/ \
const char *cpu_model_str;
#endif
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e856191..db5a38c 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -59,7 +59,7 @@ typedef struct TranslationBlock TranslationBlock;
* and up to 4 + N parameters on 64-bit archs
* (N = number of input arguments + output arguments). */
#define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS))
-#define OPC_BUF_SIZE 640
+#define OPC_BUF_SIZE 2560
#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
/* Maximum size a TCG op can expand to. This is complicated because a
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 82a731c..a0d9e93 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -984,7 +984,7 @@ void hw_breakpoint_insert(CPUX86State *env, int index)
switch (hw_breakpoint_type(env->dr[7], index)) {
case DR7_TYPE_BP_INST:
if (hw_breakpoint_enabled(env->dr[7], index)) {
- err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
+ err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU, 0, NULL,
&env->cpu_breakpoint[index]);
}
break;
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index d70b2eb..6c3353c 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -21,6 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
+
+#ifndef __TCG_OP_H__
+#define __TCG_OP_H__
#include "tcg.h"
int gen_new_label(void);
@@ -2946,6 +2950,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv
addr, int mem_index)
TCGV_PTR_TO_NAT(B))
#define tcg_gen_addi_ptr(R, A, B) tcg_gen_addi_i32(TCGV_PTR_TO_NAT(R), \
TCGV_PTR_TO_NAT(A), (B))
+#define tcg_gen_subi_ptr(R, A, B) tcg_gen_subi_i32(TCGV_PTR_TO_NAT(R), \
+ TCGV_PTR_TO_NAT(A), (B))
#define tcg_gen_ext_i32_ptr(R, A) tcg_gen_mov_i32(TCGV_PTR_TO_NAT(R), (A))
#else /* TCG_TARGET_REG_BITS == 32 */
#define tcg_gen_add_ptr(R, A, B) tcg_gen_add_i64(TCGV_PTR_TO_NAT(R), \
@@ -2953,5 +2959,9 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv
addr, int mem_index)
TCGV_PTR_TO_NAT(B))
#define tcg_gen_addi_ptr(R, A, B) tcg_gen_addi_i64(TCGV_PTR_TO_NAT(R), \
TCGV_PTR_TO_NAT(A), (B))
+#define tcg_gen_subi_ptr(R, A, B) tcg_gen_subi_i64(TCGV_PTR_TO_NAT(R), \
+ TCGV_PTR_TO_NAT(A), (B))
#define tcg_gen_ext_i32_ptr(R, A) tcg_gen_ext_i32_i64(TCGV_PTR_TO_NAT(R), (A))
#endif /* TCG_TARGET_REG_BITS != 32 */
+
+#endif /* __TCG_OP_H__ */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index b195396..b367406 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -21,6 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
+#ifndef __TCG_H__
+#define __TCG_H__
+
#include "qemu-common.h"
/* Target word size (must be identical to pointer size). */
@@ -690,4 +694,5 @@ void tcg_register_jit(void *buf, size_t buf_size);
/* Generate TB finalization at the end of block */
void tcg_out_tb_finalize(TCGContext *s);
#endif
+
+#endif /* __TCG_H__*/
--
1.7.9.5
- [Qemu-devel] [PATCH] PATCH1 v2 infrastructure for Evaluate breakpoint cond on target,
Anna Neiman <=