diff options
author | eutarass | 2010-08-27 15:47:27 +0000 |
---|---|---|
committer | eutarass | 2010-08-27 15:47:27 +0000 |
commit | 50c911874962d7e46ff451e69a3135c3327edb81 (patch) | |
tree | 733823fbe3b10db792a01c968762ec2ceb392264 | |
parent | 6aabca06a7a2c55a5566c6d4d8c2e39eeb59952c (diff) | |
download | org.eclipse.tcf.agent-50c911874962d7e46ff451e69a3135c3327edb81.tar.gz org.eclipse.tcf.agent-50c911874962d7e46ff451e69a3135c3327edb81.tar.xz org.eclipse.tcf.agent-50c911874962d7e46ff451e69a3135c3327edb81.zip |
TCF Agent:
1. Added support for all register properties that are defined for Registers service.
2. Added SignalDescription property to context execution state object.
-rw-r--r-- | framework/cpudefs.h | 39 | ||||
-rw-r--r-- | services/breakpoints.c | 2 | ||||
-rw-r--r-- | services/registers.c | 124 | ||||
-rw-r--r-- | services/runctrl.c | 16 | ||||
-rw-r--r-- | system/Darwin/context-darwin.c | 9 | ||||
-rw-r--r-- | system/FreeBSD/context-freebsd.c | 9 | ||||
-rw-r--r-- | system/GNU/Linux/context-linux.c | 9 | ||||
-rw-r--r-- | system/Windows/context-win32.c | 12 |
8 files changed, 148 insertions, 72 deletions
diff --git a/framework/cpudefs.h b/framework/cpudefs.h index 297a345b..5068cfcb 100644 --- a/framework/cpudefs.h +++ b/framework/cpudefs.h @@ -38,15 +38,36 @@ typedef uintptr_t ContextAddress; typedef struct RegisterData RegisterData; typedef struct RegisterDefinition RegisterDefinition; +typedef struct NamedRegisterValue NamedRegisterValue; + +struct NamedRegisterValue { + uint8_t * value; + const char * name; + const char * description; +}; struct RegisterDefinition { - const char * name; /* pointer to register name */ - size_t offset; /* offset to entry in REG_SET */ - size_t size; /* register size in bytes */ - int16_t dwarf_id; /* ID of the register in DWARF sections, or -1 */ - int16_t eh_frame_id; /* ID of the register in .eh_frame section, or -1 */ - uint8_t traceable; /* register value can be traced using .eh_frame of .debug_frame */ - uint8_t big_endian; /* 0 - little endian, 1 - big endian */ + const char * name; /* pointer to register name */ + size_t offset; /* offset to entry in REG_SET */ + size_t size; /* register size in bytes */ + int16_t dwarf_id; /* ID of the register in DWARF sections, or -1 */ + int16_t eh_frame_id; /* ID of the register in .eh_frame section, or -1 */ + uint8_t traceable; /* register value can be traced using .eh_frame of .debug_frame */ + uint8_t big_endian; /* 0 - little endian, 1 - big endian */ + uint8_t fp_value; /* true if the register value is a floating-point value */ + uint8_t no_read; /* true if context value can not be read */ + uint8_t no_write; /* true if context value can not be written */ + uint8_t read_once; /* true if reading the context (register) destroys its current value */ + uint8_t write_once; /* true if register value can not be overwritten - every write counts */ + uint8_t side_effects; /* true if writing the context can change values of other registers */ + uint8_t volatile_value;/* true if the register value can change even when target is stopped */ + uint8_t left_to_right; /* true if the lowest numbered bit should be shown to user as the left-most bit */ + int first_bit; /* bit numbering base (0 or 1) to use when showing bits to user */ + int * bits; /* if context is a bit field, contains the field bit numbers in the parent context */ + NamedRegisterValue ** values; /* predefined names (mnemonics) for some of register values */ + ContextAddress memory_address;/* the address of a memory mapped register */ + const char * memory_context;/* the context ID of a memory context in which a memory mapped register is located */ + const char * role; /* the role the register plays in a program execution */ }; /* Stack tracing command codes */ @@ -153,9 +174,7 @@ extern uint8_t * get_break_instruction(Context * ctx, size_t * size); */ extern int crawl_stack_frame(StackFrame * frame, StackFrame * down); -/* - * Execute stack tracing command sequence. - */ +/* Execute stack tracing command sequence */ extern uint64_t evaluate_stack_trace_commands(Context * ctx, StackFrame * frame, StackTracingCommandSequence * cmds); #endif /* ENABLE_DebugContext */ diff --git a/services/breakpoints.c b/services/breakpoints.c index 683399da..7c13a86a 100644 --- a/services/breakpoints.c +++ b/services/breakpoints.c @@ -319,7 +319,7 @@ static BreakInstruction * add_instruction(Context * ctx, ContextAddress address) static BreakInstruction * find_instruction(Context * ctx, ContextAddress address) { int hash = addr2instr_hash(ctx, address); LINK * l = addr2instr[hash].next; - assert(address != 0); + if (address == 0) return NULL; while (l != addr2instr + hash) { BreakInstruction * bi = link_adr2bi(l); if (bi->ctx->mem == ctx->mem && bi->address == address) return bi; diff --git a/services/registers.c b/services/registers.c index 06e49cc0..7003b4eb 100644 --- a/services/registers.c +++ b/services/registers.c @@ -41,6 +41,15 @@ static uint8_t * bbf = NULL; static unsigned bbf_pos = 0; static unsigned bbf_len = 0; +static void write_boolean_member(OutputStream * out, const char * name, int val) { + /* For this service FALSE is same as absence of the member */ + if (!val) return; + write_stream(out, ','); + json_write_string(out, name); + write_stream(out, ':'); + json_write_boolean(out, 1); +} + static void write_context(OutputStream * out, char * id, Context * ctx, int frame, RegisterDefinition * reg_def) { assert(!ctx->exited); @@ -61,6 +70,11 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int fram } write_stream(out, ','); + json_write_string(out, "ProcessID"); + write_stream(out, ':'); + json_write_string(out, ctx->mem->id); + + write_stream(out, ','); json_write_string(out, "Name"); write_stream(out, ':'); json_write_string(out, reg_def->name); @@ -70,23 +84,6 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int fram write_stream(out, ':'); json_write_long(out, reg_def->size); - write_stream(out, ','); - json_write_string(out, "Readable"); - write_stream(out, ':'); - json_write_boolean(out, 1); - - write_stream(out, ','); - json_write_string(out, "Writeable"); - write_stream(out, ':'); - json_write_boolean(out, 1); - - if (reg_def == get_PC_definition(ctx)) { - write_stream(out, ','); - json_write_string(out, "Role"); - write_stream(out, ':'); - json_write_string(out, "PC"); - } - if (reg_def->dwarf_id >= 0) { write_stream(out, ','); json_write_string(out, "DwarfID"); @@ -101,22 +98,93 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int fram json_write_long(out, reg_def->eh_frame_id); } - if (reg_def->traceable) { + write_boolean_member(out, "Traceable", reg_def->traceable); + write_boolean_member(out, "BigEndian", reg_def->big_endian); + write_boolean_member(out, "Float", reg_def->fp_value); + write_boolean_member(out, "Readable", !reg_def->no_read); + write_boolean_member(out, "Writeable", !reg_def->no_write); + write_boolean_member(out, "ReadOnce", reg_def->read_once); + write_boolean_member(out, "WriteOnce", reg_def->write_once); + write_boolean_member(out, "Volatile", reg_def->volatile_value); + write_boolean_member(out, "SideEffects", reg_def->side_effects); + write_boolean_member(out, "LeftToRight", reg_def->left_to_right); + + if (reg_def->first_bit > 0) { write_stream(out, ','); - json_write_string(out, "Traceable"); + json_write_string(out, "FirstBit"); write_stream(out, ':'); - json_write_boolean(out, reg_def->traceable); + json_write_long(out, reg_def->first_bit); } - write_stream(out, ','); - json_write_string(out, "ProcessID"); - write_stream(out, ':'); - json_write_string(out, ctx->mem->id); + if (reg_def->bits != NULL) { + int i = 0; + write_stream(out, ','); + json_write_string(out, "Bits"); + write_stream(out, ':'); + write_stream(out, '['); + while (reg_def->bits[i] >= 0) { + if (i > 0) write_stream(out, ','); + json_write_long(out, reg_def->bits[i++]); + } + write_stream(out, ']'); + } - write_stream(out, ','); - json_write_string(out, "BigEndian"); - write_stream(out, ':'); - json_write_boolean(out, reg_def->big_endian); + if (reg_def->values != NULL) { + int i = 0; + write_stream(out, ','); + json_write_string(out, "Values"); + write_stream(out, ':'); + write_stream(out, '['); + while (reg_def->values[i] != NULL) { + NamedRegisterValue * v = reg_def->values[i++]; + if (i > 0) write_stream(out, ','); + write_stream(out, '('); + json_write_string(out, "Value"); + write_stream(out, ':'); + json_write_binary(out, v->value, reg_def->size); + if (v->name != NULL) { + write_stream(out, ','); + json_write_string(out, "Name"); + write_stream(out, ':'); + json_write_string(out, v->name); + } + if (v->description != NULL) { + write_stream(out, ','); + json_write_string(out, "Description"); + write_stream(out, ':'); + json_write_string(out, v->description); + } + write_stream(out, '}'); + } + write_stream(out, ']'); + } + + if (reg_def->memory_address > 0) { + write_stream(out, ','); + json_write_string(out, "MemoryAddress"); + write_stream(out, ':'); + json_write_uint64(out, reg_def->memory_address); + } + + if (reg_def->memory_context != NULL) { + write_stream(out, ','); + json_write_string(out, "MemoryContext"); + write_stream(out, ':'); + json_write_string(out, reg_def->memory_context); + } + + if (reg_def->role != NULL) { + write_stream(out, ','); + json_write_string(out, "Role"); + write_stream(out, ':'); + json_write_string(out, reg_def->role); + } + else if (reg_def == get_PC_definition(ctx)) { + write_stream(out, ','); + json_write_string(out, "Role"); + write_stream(out, ':'); + json_write_string(out, "PC"); + } write_stream(out, '}'); write_stream(out, 0); diff --git a/services/runctrl.c b/services/runctrl.c index ec6d1d5b..78866df5 100644 --- a/services/runctrl.c +++ b/services/runctrl.c @@ -227,14 +227,22 @@ static void write_context_state(OutputStream * out, Context * ctx) { /* Object: Additional context state info */ write_stream(out, '{'); if (ctx->signal) { + const char * name = signal_name(ctx->signal); + const char * desc = signal_description(ctx->signal); json_write_string(out, "Signal"); write_stream(out, ':'); json_write_long(out, ctx->signal); - if (signal_name(ctx->signal)) { + if (name != NULL) { write_stream(out, ','); json_write_string(out, "SignalName"); write_stream(out, ':'); - json_write_string(out, signal_name(ctx->signal)); + json_write_string(out, name); + } + if (desc != NULL) { + write_stream(out, ','); + json_write_string(out, "SignalDescription"); + write_stream(out, ':'); + json_write_string(out, desc); } fst = 0; } @@ -741,7 +749,9 @@ static void send_event_context_exception(Context * ctx) { } else { char buf[128]; - snprintf(buf, sizeof(buf), "Signal %d %s", ctx->signal, signal_name(ctx->signal)); + const char * desc = signal_description(ctx->signal); + if (desc == NULL) desc = signal_name(ctx->signal); + snprintf(buf, sizeof(buf), desc == NULL ? "Signal %d" : "Signal %d: %s", ctx->signal, desc); json_write_string(out, buf); } write_stream(out, 0); diff --git a/system/Darwin/context-darwin.c b/system/Darwin/context-darwin.c index 2ad089c6..7113e656 100644 --- a/system/Darwin/context-darwin.c +++ b/system/Darwin/context-darwin.c @@ -74,14 +74,7 @@ const char * context_suspend_reason(Context * ctx) { if (EXT(ctx)->end_of_step) return "Step"; if (EXT(ctx)->syscall_enter) return "System Call"; if (EXT(ctx)->syscall_exit) return "System Return"; - if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) { - return "Suspended"; - } - if (signal_name(ctx->signal)) { - snprintf(reason, sizeof(reason), "Signal %d %s", ctx->signal, signal_name(ctx->signal)); - return reason; - } - + if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return "Suspended"; snprintf(reason, sizeof(reason), "Signal %d", ctx->signal); return reason; } diff --git a/system/FreeBSD/context-freebsd.c b/system/FreeBSD/context-freebsd.c index f619d4ee..86773588 100644 --- a/system/FreeBSD/context-freebsd.c +++ b/system/FreeBSD/context-freebsd.c @@ -90,14 +90,7 @@ const char * context_suspend_reason(Context * ctx) { snprintf(reason, sizeof(reason), "Event: %s", event_name(EXT(ctx)->ptrace_event)); return reason; } - if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) { - return "Suspended"; - } - if (signal_name(ctx->signal)) { - snprintf(reason, sizeof(reason), "Signal %d %s", ctx->signal, signal_name(ctx->signal)); - return reason; - } - + if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return "Suspended"; snprintf(reason, sizeof(reason), "Signal %d", ctx->signal); return reason; } diff --git a/system/GNU/Linux/context-linux.c b/system/GNU/Linux/context-linux.c index d63c5e8c..fd734997 100644 --- a/system/GNU/Linux/context-linux.c +++ b/system/GNU/Linux/context-linux.c @@ -131,14 +131,7 @@ const char * context_suspend_reason(Context * ctx) { } if (EXT(ctx)->syscall_enter) return "System Call"; if (EXT(ctx)->syscall_exit) return "System Return"; - if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) { - return "Suspended"; - } - if (signal_name(ctx->signal)) { - snprintf(reason, sizeof(reason), "Signal %d %s", ctx->signal, signal_name(ctx->signal)); - return reason; - } - + if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return "Suspended"; snprintf(reason, sizeof(reason), "Signal %d", ctx->signal); return reason; } diff --git a/system/Windows/context-win32.c b/system/Windows/context-win32.c index 0a5ff718..5fb4b3d0 100644 --- a/system/Windows/context-win32.c +++ b/system/Windows/context-win32.c @@ -104,17 +104,17 @@ static OSVERSIONINFOEX os_version; const char * context_suspend_reason(Context * ctx) { ContextExtensionWin32 * ext = EXT(ctx); DWORD exception_code = ext->suspend_reason.ExceptionRecord.ExceptionCode; - const char * desc = NULL; static char buf[64]; if (exception_code == 0) return "Suspended"; if (exception_code == EXCEPTION_SINGLE_STEP) return "Step"; if (exception_code == EXCEPTION_BREAKPOINT) return "Eventpoint"; - - desc = signal_description(get_signal_from_code(exception_code)); - if (desc != NULL) return desc; - - snprintf(buf, sizeof(buf), "Exception %#lx", exception_code); + if (ext->suspend_reason.dwFirstChance) { + snprintf(buf, sizeof(buf), "Exception %#lx", exception_code); + } + else { + snprintf(buf, sizeof(buf), "Unhandled exception %#lx", exception_code); + } return buf; } |