diff --git a/ruamoko/include/types.h b/ruamoko/include/types.h index 530bfad1f..a1527d890 100644 --- a/ruamoko/include/types.h +++ b/ruamoko/include/types.h @@ -82,6 +82,9 @@ typedef struct qfot_type_s { }; } qfot_type_t; +// the minimum size of a type encoding +#define TYPESIZE 4 + typedef struct qfot_type_encodings_s { qfot_type_t *types; int size; diff --git a/ruamoko/qwaq/Makefile.am b/ruamoko/qwaq/Makefile.am index 99f59b474..ab3b5459b 100644 --- a/ruamoko/qwaq/Makefile.am +++ b/ruamoko/qwaq/Makefile.am @@ -29,6 +29,7 @@ qwaq_app_dat_src= \ qwaq-app.r \ debugger/debug.r \ debugger/debugger.r \ + debugger/typeencodings.r \ editor/editbuffer.r \ editor/editor.r \ ui/button.r \ diff --git a/ruamoko/qwaq/builtins/curses.c b/ruamoko/qwaq/builtins/curses.c index f4db018a0..3f757b124 100644 --- a/ruamoko/qwaq/builtins/curses.c +++ b/ruamoko/qwaq/builtins/curses.c @@ -618,7 +618,7 @@ cmd_mvwhline (qwaq_resources_t *res) static void dump_command (qwaq_resources_t *res, int len) { - if (1) { + if (0) { qwaq_commands cmd = RB_PEEK_DATA (res->command_queue, 0); Sys_Printf ("%s[%d]", qwaq_command_names[cmd], len); for (int i = 2; i < len; i++) { diff --git a/ruamoko/qwaq/builtins/debug.c b/ruamoko/qwaq/builtins/debug.c index c1835f99d..218a953cb 100644 --- a/ruamoko/qwaq/builtins/debug.c +++ b/ruamoko/qwaq/builtins/debug.c @@ -506,7 +506,8 @@ static builtin_t builtins[] = { {"qdb_continue", qdb_continue, -1}, {"qdb_get_state", qdb_get_state, -1}, {"qdb_get_data", qdb_get_data, -1}, - {"qdb_get_string", qdb_get_string, -1}, + {"qdb_get_string|{tag qdb_target_s=}i", qdb_get_string, -1}, + {"qdb_get_string|{tag qdb_target_s=}*", qdb_get_string, -1}, {"qdb_find_global", qdb_find_global, -1}, {"qdb_find_field", qdb_find_field, -1}, {"qdb_find_function", qdb_find_function, -1}, diff --git a/ruamoko/qwaq/debugger/debug.h b/ruamoko/qwaq/debugger/debug.h index 74ebf1c39..161014b84 100644 --- a/ruamoko/qwaq/debugger/debug.h +++ b/ruamoko/qwaq/debugger/debug.h @@ -63,7 +63,10 @@ int qdb_clear_watchpoint (qdb_target_t target); int qdb_continue (qdb_target_t target); qdb_state_t qdb_get_state (qdb_target_t target); int qdb_get_data (qdb_target_t target, unsigned src, unsigned len, void *dst); -string qdb_get_string (qdb_target_t target, unsigned str); +@overload string qdb_get_string (qdb_target_t target, unsigned str); +// note: str is likely not valid in the host progs, it's just a convinience to +// avoid cast shenanigans when getting type encoding strings +@overload string qdb_get_string (qdb_target_t target, string str); qdb_def_t qdb_find_global (qdb_target_t target, string name); qdb_def_t qdb_find_field (qdb_target_t target, string name); qdb_function_t *qdb_find_function (qdb_target_t target, string name); diff --git a/ruamoko/qwaq/debugger/debug.r b/ruamoko/qwaq/debugger/debug.r index b4175fbbb..7ad286cf7 100644 --- a/ruamoko/qwaq/debugger/debug.r +++ b/ruamoko/qwaq/debugger/debug.r @@ -13,6 +13,7 @@ qdb_state_t qdb_get_state (qdb_target_t target) = #0; int qdb_get_data (qdb_target_t target, unsigned src, unsigned len, void *dst) = #0; string qdb_get_string (qdb_target_t target, unsigned str) = #0; +string qdb_get_string (qdb_target_t target, string str) = #0; qdb_def_t qdb_find_global (qdb_target_t target, string name) = #0; qdb_def_t qdb_find_field (qdb_target_t target, string name) = #0; qdb_function_t *qdb_find_function (qdb_target_t target, string name) = #0; diff --git a/ruamoko/qwaq/debugger/debugger.h b/ruamoko/qwaq/debugger/debugger.h index 2fc402291..04a6a3354 100644 --- a/ruamoko/qwaq/debugger/debugger.h +++ b/ruamoko/qwaq/debugger/debugger.h @@ -1,6 +1,7 @@ #ifndef __qwaq_debugger_debugger_h #define __qwaq_debugger_debugger_h +#include #include #include "debugger/debug.h" @@ -12,7 +13,8 @@ @interface Debugger : Object { - qdb_target_t debug_target; + qdb_target_t target; + qfot_type_encodings_t target_encodings; Window *source_window; ProxyView *file_proxy; @@ -28,7 +30,7 @@ qdb_def_t *local_defs; void *local_data; } --(qdb_target_t)debug_target; +-(qdb_target_t)target; -initWithTarget:(qdb_target_t) target; -handleDebugEvent; @end diff --git a/ruamoko/qwaq/debugger/debugger.r b/ruamoko/qwaq/debugger/debugger.r index 3948c0b0e..44075babf 100644 --- a/ruamoko/qwaq/debugger/debugger.r +++ b/ruamoko/qwaq/debugger/debugger.r @@ -8,13 +8,14 @@ #include "ui/proxyview.h" #include "ui/window.h" #include "debugger/debugger.h" +#include "debugger/typeencodings.h" #include "editor/editor.h" #include "qwaq-app.h" @implementation Debugger --(qdb_target_t)debug_target +-(qdb_target_t)target { - return debug_target; + return target; } -initWithTarget:(qdb_target_t) target @@ -22,12 +23,15 @@ if (!(self = [super init])) { return nil; } - debug_target = target; + self.target = target; files = [[Array array] retain]; source_window = [[Window alloc] initWithRect: {nil, [application size]}]; [application addView:source_window]; + qdb_def_t encodings_def = qdb_find_global (target, ".type_encodings"); + qdb_get_data (target, encodings_def.offset, sizeof(target_encodings), + &target_encodings); return self; } @@ -50,7 +54,7 @@ -(void) setup { - qdb_state_t state = qdb_get_state (debug_target); + qdb_state_t state = qdb_get_state (target); current_file = [self find_file: state.file]; file_proxy = [[ProxyView alloc] initWithView: current_file]; @@ -75,7 +79,7 @@ -(void) show_line { - qdb_state_t state = qdb_get_state (debug_target); + qdb_state_t state = qdb_get_state (target); Editor *file = [self find_file: state.file]; printf ("%s:%d\n", state.file, state.line); @@ -104,10 +108,10 @@ update_current_func (Debugger *self, unsigned fnum) if (self.local_data) { obj_free (self.local_data); } - self.func = qdb_get_function (self.debug_target, fnum); - self.aux_func = qdb_get_auxfunction (self.debug_target, fnum); + self.func = qdb_get_function (self.target, fnum); + self.aux_func = qdb_get_auxfunction (self.target, fnum); if (self.aux_func) { - self.local_defs = qdb_get_local_defs (self.debug_target, fnum); + self.local_defs = qdb_get_local_defs (self.target, fnum); } if (self.func) { self.local_data = obj_malloc (self.func.local_size); @@ -116,14 +120,14 @@ update_current_func (Debugger *self, unsigned fnum) -(void)update_watchvars { - qdb_state_t state = qdb_get_state (debug_target); + qdb_state_t state = qdb_get_state (target); if (state.func != current_fnum) { update_current_func (self, state.func); } if (!local_data) { return; } - qdb_get_data (debug_target, func.local_data, func.local_size, local_data); + qdb_get_data (target, func.local_data, func.local_size, local_data); [locals_view clear]; if (!local_defs) { [locals_view mvprintf:{0,0}, "%d", func.local_size]; @@ -145,23 +149,25 @@ update_current_func (Debugger *self, unsigned fnum) break; } qdb_def_t *def = local_defs + y; + unsigned te = def.type_encoding + (int) target_encodings.types; + qfot_type_t *type; + type = [TypeEncodings getType:te fromTarget:target]; [locals_view mvprintf:{0, y}, "%s", - qdb_get_string (debug_target, def.name)]; + qdb_get_string (target, def.name)]; @param value = nil; string valstr = "--"; unsigned offset = func.local_data + def.offset; printf ("%d %d %s %d\n", def.type_size, offset, - qdb_get_string (debug_target, def.name), + qdb_get_string (target, def.name), def.type_encoding); - qdb_get_data (debug_target, offset, def.type_size >> 16, - &value); + qdb_get_data (target, offset, def.type_size >> 16, &value); switch (def.type_size & 0xffff) { case ev_void: case ev_invalid: case ev_type_count: break; case ev_string: - valstr = qdb_get_string (debug_target, value.integer_val); + valstr = qdb_get_string (target, value.integer_val); break; case ev_float: valstr = sprintf ("%.9g", value.float_val); @@ -216,8 +222,8 @@ proxy_event (Debugger *self, id proxy, qwaq_event_t *event) } else if (event.what == qe_keydown) { switch (event.key.code) { case QFK_F7: - qdb_set_trace (self.debug_target, 1); - qdb_continue (self.debug_target); + qdb_set_trace (self.target, 1); + qdb_continue (self.target); return 1; } } diff --git a/ruamoko/qwaq/debugger/typeencodings.h b/ruamoko/qwaq/debugger/typeencodings.h new file mode 100644 index 000000000..213dad8a7 --- /dev/null +++ b/ruamoko/qwaq/debugger/typeencodings.h @@ -0,0 +1,13 @@ +#ifndef __qwaq_debugger_typeencodings_h +#define __qwaq_debugger_typeencodings_h + +#include +#include + +#include "debugger/debug.h" + +@interface TypeEncodings : Object ++(qfot_type_t *)getType:(unsigned)typeAddr fromTarget:(qdb_target_t)target; +@end + +#endif//__qwaq_debugger_typeencodings_h diff --git a/ruamoko/qwaq/debugger/typeencodings.r b/ruamoko/qwaq/debugger/typeencodings.r new file mode 100644 index 000000000..30ff48181 --- /dev/null +++ b/ruamoko/qwaq/debugger/typeencodings.r @@ -0,0 +1,146 @@ +#include +#include +#include +#include // printf FIXME + +#include "debugger/typeencodings.h" + +@implementation TypeEncodings + +// these are encodings that we already have so don't need to copy them from +// the target +static hashtab_t *static_encodings; +// these are condings that had to be copied from the target +static hashtab_t *dynamic_encodings; + +static qfot_type_t * +next_type (qfot_type_t *type) +{ + int size = type.size; + + if (!size) { // null type + size = TYPESIZE; + } + return (qfot_type_t *) ((int *) type + size); +} + +static string +type_get_key (void *t, void *unusded) +{ + qfot_type_t *type = (qfot_type_t *) t; + return type.encoding; +} + +static void type_free (void *t, void *unused) +{ + qfot_type_t *type = (qfot_type_t *) t; + str_free (type.encoding); + switch (type.meta) { + case ty_basic: + case ty_array: + break; + case ty_struct: + case ty_union: + case ty_enum: + str_free (type.strct.tag); + for (int i = 0; i < type.strct.num_fields; i++) { + str_free (type.strct.fields[i].name); + } + break; + case ty_class: + str_free (type.class); + break; + case ty_alias: + str_free (type.alias.name); + break; + } + obj_free (t); +} + ++initialize +{ + qfot_type_encodings_t *encodings; + qfot_type_t *type; + + static_encodings = Hash_NewTable (1023, type_get_key, nil, nil); + dynamic_encodings = Hash_NewTable (1023, type_get_key, type_free, nil); + + encodings = PR_FindGlobal (".type_encodings"); + for (type = encodings.types; + ((int *)type - (int *) encodings.types) < encodings.size; + type = next_type (type)) { + printf ("%s\n", type.encoding); + Hash_Add (static_encodings, type); + } + return self; +} + ++(qfot_type_t *) getType:(unsigned)typeAddr fromTarget:(qdb_target_t)target +{ + qfot_type_t buffer = {}; + string encoding; + qfot_type_t *type; + + if (!qdb_get_data (target, typeAddr, TYPESIZE, &buffer)) { + return nil; + } + if (!buffer.encoding) { + return nil; + } + encoding = qdb_get_string (target, buffer.encoding); + if (!encoding) { + return nil; + } + if ((type = Hash_Find (static_encodings, encoding))) { + return type; + } + if ((type = Hash_Find (dynamic_encodings, encoding))) { + return type; + } + type = obj_calloc (1, buffer.size); + if (!qdb_get_data (target, typeAddr, TYPESIZE, &buffer)) { + goto error; + } + if (!(type.encoding = qdb_get_string (target, type.encoding))) { + goto error; + } + switch (type.meta) { + case ty_basic: + case ty_array: + goto hash_type; + case ty_struct: + case ty_union: + case ty_enum: + if (!(type.strct.tag = qdb_get_string (target, type.strct.tag))) { + goto error; + } + for (int i = 0; i < type.strct.num_fields; i++) { + qfot_var_t *var = &type.strct.fields[i]; + if (!(var.name = qdb_get_string (target, var.name))) { + goto error; + } + } + goto hash_type; + case ty_class: + if (!(type.class = qdb_get_string (target, type.class))) { + goto error; + } + goto hash_type; + case ty_alias: + if (!(type.alias.name = qdb_get_string (target, type.alias.name))) { + goto error; + } + goto hash_type; + } + goto error; +hash_type: + printf ("fetched type %s\n", type.encoding); + Hash_Add (dynamic_encodings, type); + return type; + // not a valid type +error: + type_free (type, nil); + return nil; +} + +@end diff --git a/ruamoko/qwaq/qwaq-app.r b/ruamoko/qwaq/qwaq-app.r index 19daf643a..a17312ead 100644 --- a/ruamoko/qwaq/qwaq-app.r +++ b/ruamoko/qwaq/qwaq-app.r @@ -80,7 +80,7 @@ arp_end (void) for (int i = [debuggers count]; i-- > 0; ) { debugger = [debuggers objectAtIndex: i]; - if ([debugger debug_target].handle == target.handle) { + if ([debugger target].handle == target.handle) { return debugger; } }