2021-06-01 14:52:04 +00:00
|
|
|
#include <stdlib.h>
|
2020-03-31 11:48:38 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <types.h>
|
2020-06-21 14:15:17 +00:00
|
|
|
#include "ruamoko/qwaq/debugger/views/defview.h"
|
|
|
|
#include "ruamoko/qwaq/debugger/views/nameview.h"
|
|
|
|
#include "ruamoko/qwaq/debugger/localsdata.h"
|
2021-09-24 17:14:26 +00:00
|
|
|
#include "ruamoko/qwaq/ui/listener.h"
|
2020-03-31 11:48:38 +00:00
|
|
|
|
|
|
|
@implementation LocalsData
|
|
|
|
|
|
|
|
-initWithTarget:(qdb_target_t) target
|
|
|
|
{
|
|
|
|
if (!(self = [super init])) {
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
self.target = target;
|
|
|
|
|
|
|
|
qdb_def_t encodings_def = qdb_find_global (target, ".type_encodings");
|
|
|
|
qdb_get_data (target, encodings_def.offset, sizeof(target_encodings),
|
|
|
|
&target_encodings);
|
|
|
|
|
2022-02-12 01:19:45 +00:00
|
|
|
self.has_stack = qdb_has_data_stack (target);
|
|
|
|
|
2021-09-24 17:14:26 +00:00
|
|
|
self.onRowCountChanged = [[ListenerGroup listener] retain];
|
2020-03-31 11:48:38 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
+(LocalsData *)withTarget:(qdb_target_t)target
|
|
|
|
{
|
|
|
|
return [[[self alloc] initWithTarget:target] autorelease];
|
|
|
|
}
|
|
|
|
|
2021-06-01 14:52:04 +00:00
|
|
|
static void
|
|
|
|
free_defs (LocalsData *self)
|
|
|
|
{
|
|
|
|
obj_free (self.defs);
|
|
|
|
self.defs = nil;
|
2022-02-12 00:28:22 +00:00
|
|
|
for (int i = 0; i < self.num_user_defs; i++) {
|
2021-06-01 14:52:04 +00:00
|
|
|
[self.def_views[i] release];
|
|
|
|
}
|
|
|
|
obj_free (self.def_views);
|
|
|
|
self.def_views = nil;
|
|
|
|
obj_free (self.def_rows);
|
|
|
|
self.def_rows = nil;
|
|
|
|
}
|
|
|
|
|
2020-03-31 11:48:38 +00:00
|
|
|
-(void)dealloc
|
|
|
|
{
|
2021-09-24 17:14:26 +00:00
|
|
|
[onRowCountChanged release];
|
2020-03-31 11:48:38 +00:00
|
|
|
if (defs) {
|
2021-06-01 14:52:04 +00:00
|
|
|
free_defs (self);
|
2020-03-31 11:48:38 +00:00
|
|
|
}
|
|
|
|
if (data) {
|
|
|
|
obj_free (data);
|
|
|
|
data = nil;
|
|
|
|
}
|
2021-09-26 01:07:34 +00:00
|
|
|
[super dealloc];
|
2020-03-31 11:48:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
-setFunction:(unsigned) fnum
|
|
|
|
{
|
|
|
|
if (current_fnum == fnum) {
|
|
|
|
return self;
|
|
|
|
}
|
2021-09-24 17:14:26 +00:00
|
|
|
current_fnum = fnum;
|
2020-03-31 11:48:38 +00:00
|
|
|
|
|
|
|
if (defs) {
|
2021-06-01 14:52:04 +00:00
|
|
|
free_defs (self);
|
2020-03-31 11:48:38 +00:00
|
|
|
}
|
|
|
|
if (data) {
|
|
|
|
obj_free (data);
|
|
|
|
data = nil;
|
|
|
|
}
|
|
|
|
func = qdb_get_function (target, fnum);
|
2021-06-01 14:52:04 +00:00
|
|
|
if (func && func.local_size) {
|
|
|
|
data = obj_malloc (func.local_size);
|
|
|
|
}
|
2020-03-31 11:48:38 +00:00
|
|
|
aux_func = qdb_get_auxfunction (target, fnum);
|
2022-02-12 00:28:22 +00:00
|
|
|
num_user_defs = 0;
|
2020-03-31 11:48:38 +00:00
|
|
|
if (aux_func) {
|
|
|
|
defs = qdb_get_local_defs (target, fnum);
|
2021-06-01 14:52:04 +00:00
|
|
|
for (int i = 0; i < aux_func.num_locals; i++) {
|
2022-02-12 00:28:22 +00:00
|
|
|
string def_name = qdb_get_string (target, defs[i].name);
|
|
|
|
if (str_mid (def_name, 0, 1) != ".") {
|
|
|
|
num_user_defs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
def_views = obj_malloc (num_user_defs);
|
|
|
|
def_rows = obj_malloc (num_user_defs + 1);
|
|
|
|
def_rows[0] = 0;
|
|
|
|
for (int i = 0, j = 0; i < aux_func.num_locals; i++) {
|
|
|
|
string def_name = qdb_get_string (target, defs[i].name);
|
|
|
|
if (str_mid (def_name, 0, 1) == ".") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
def_views[j] = [[DefView withDef:defs[i] in:data target:target]
|
2021-06-01 14:52:04 +00:00
|
|
|
retain];
|
2022-02-12 00:28:22 +00:00
|
|
|
def_rows[j + 1] = [def_views[j] rows];
|
|
|
|
j++;
|
2021-06-01 14:52:04 +00:00
|
|
|
}
|
2022-02-12 00:28:22 +00:00
|
|
|
prefixsum (def_rows, num_user_defs + 1);
|
2020-03-31 11:48:38 +00:00
|
|
|
}
|
2021-09-24 17:14:26 +00:00
|
|
|
[onRowCountChanged respond:self];
|
2020-03-31 11:48:38 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-31 14:23:18 +00:00
|
|
|
-fetchData
|
|
|
|
{
|
2022-02-12 01:19:45 +00:00
|
|
|
if (data && func.local_size) {
|
|
|
|
unsigned local_data = func.local_data;
|
|
|
|
if (has_stack) {
|
|
|
|
unsigned stack_ptr = qdb_get_frame_addr (target);
|
|
|
|
local_data = 0;
|
|
|
|
if (stack_ptr) {
|
|
|
|
local_data = stack_ptr - func.local_data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (local_data) {
|
|
|
|
qdb_get_data (target, local_data, func.local_size, data);
|
|
|
|
}
|
2020-04-02 10:31:11 +00:00
|
|
|
}
|
2022-02-12 00:28:22 +00:00
|
|
|
int rowCount = def_rows[num_user_defs];
|
2021-06-04 04:35:53 +00:00
|
|
|
if (aux_func) {
|
|
|
|
def_rows[0] = 0;
|
2022-02-12 00:28:22 +00:00
|
|
|
for (int i = 0; i < num_user_defs; i++) {
|
2021-06-04 04:35:53 +00:00
|
|
|
[def_views[i] fetchData];
|
|
|
|
def_rows[i + 1] = [def_views[i] rows];
|
|
|
|
}
|
2022-02-12 00:28:22 +00:00
|
|
|
prefixsum (def_rows, num_user_defs + 1);
|
2021-06-04 04:35:53 +00:00
|
|
|
}
|
2022-02-12 00:28:22 +00:00
|
|
|
if (rowCount != def_rows[num_user_defs]) {
|
2021-09-24 17:14:26 +00:00
|
|
|
[onRowCountChanged respond:self];
|
|
|
|
}
|
2020-03-31 14:23:18 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2021-09-24 17:14:26 +00:00
|
|
|
-(ListenerGroup *)onRowCountChanged
|
|
|
|
{
|
|
|
|
return onRowCountChanged;
|
|
|
|
}
|
|
|
|
|
2020-03-31 11:48:38 +00:00
|
|
|
-(int)numberOfRows:(TableView *)tableview
|
|
|
|
{
|
|
|
|
if (aux_func) {
|
2022-02-12 00:28:22 +00:00
|
|
|
if (!num_user_defs) {
|
2021-06-01 14:52:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2022-02-12 00:28:22 +00:00
|
|
|
return def_rows[num_user_defs];
|
2020-03-31 11:48:38 +00:00
|
|
|
} else if (func) {
|
|
|
|
return (func.local_size + 3) / 4;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
-(View *)tableView:(TableView *)tableview
|
|
|
|
forColumn:(TableViewColumn *)column
|
|
|
|
row:(int)row
|
|
|
|
{
|
2021-06-01 14:52:04 +00:00
|
|
|
View *view = nil;
|
2022-02-12 00:28:22 +00:00
|
|
|
int *index = fbsearch (&row, def_rows, num_user_defs, 1, nil);
|
2020-03-31 11:48:38 +00:00
|
|
|
|
2021-06-01 14:52:04 +00:00
|
|
|
if (index) {
|
2021-06-04 04:35:53 +00:00
|
|
|
DefView *dv = def_views[index - def_rows];
|
|
|
|
int r = row - *index;
|
|
|
|
view = [dv viewAtRow: r forColumn:column];
|
2020-03-31 11:48:38 +00:00
|
|
|
}
|
|
|
|
return view;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|