Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2009-09-21 21:29:56 +0000
committereutarass2009-09-21 21:29:56 +0000
commit5cc9ef8eaed360cdf39bfacdbb15b83ddf306505 (patch)
tree44ff0ce0503dc78beee0cae4891cf75e44c074a7
parent7a0aa29bb6633508dc5a3f895094c85a28125139 (diff)
downloadorg.eclipse.tcf.agent-5cc9ef8eaed360cdf39bfacdbb15b83ddf306505.tar.gz
org.eclipse.tcf.agent-5cc9ef8eaed360cdf39bfacdbb15b83ddf306505.tar.xz
org.eclipse.tcf.agent-5cc9ef8eaed360cdf39bfacdbb15b83ddf306505.zip
TCF Debugger: Added user actions in variables and expression views: Display As Array, Cast To Type, Restore Original Type.
-rw-r--r--TCF Agent - Linux i686.launch26
-rw-r--r--expressions.c133
-rw-r--r--symbols.h7
-rw-r--r--symbols_elf.c288
-rw-r--r--symbols_win32.c376
5 files changed, 590 insertions, 240 deletions
diff --git a/TCF Agent - Linux i686.launch b/TCF Agent - Linux i686.launch
index bc0ef4ac..52cdbb36 100644
--- a/TCF Agent - Linux i686.launch
+++ b/TCF Agent - Linux i686.launch
@@ -1,12 +1,14 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.tm.tcf.debug.LaunchConfigurationType">
-<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
-<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
-<stringAttribute key="org.eclipse.tm.tcf.debug.LocalProgramFile" value="Linux/i686/Debug/agent"/>
-<stringAttribute key="org.eclipse.tm.tcf.debug.PeerID" value="TCP:147.11.46.31:1534"/>
-<stringAttribute key="org.eclipse.tm.tcf.debug.ProgramArguments" value="-t"/>
-<stringAttribute key="org.eclipse.tm.tcf.debug.ProgramFile" value="/tmp/agent"/>
-<stringAttribute key="org.eclipse.tm.tcf.debug.ProjectName" value="org.eclipse.tm.tcf.agent"/>
-<booleanAttribute key="org.eclipse.tm.tcf.debug.UseTerminal" value="true"/>
-<stringAttribute key="org.eclipse.tm.tcf.debug.WorkingDirectory" value="/tmp"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.tm.tcf.debug.LaunchConfigurationType">
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_ENCODING" value="UTF-8"/>
+<stringAttribute key="org.eclipse.tm.tcf.debug.LocalProgramFile" value="Linux/i686/Debug/agent"/>
+<stringAttribute key="org.eclipse.tm.tcf.debug.PeerID" value="TCP:147.11.217.34:1534"/>
+<stringAttribute key="org.eclipse.tm.tcf.debug.ProgramArguments" value="-t"/>
+<stringAttribute key="org.eclipse.tm.tcf.debug.ProgramFile" value="/tmp/agent"/>
+<stringAttribute key="org.eclipse.tm.tcf.debug.ProjectName" value="org.eclipse.tm.tcf.agent"/>
+<booleanAttribute key="org.eclipse.tm.tcf.debug.RunLocalAgent" value="false"/>
+<booleanAttribute key="org.eclipse.tm.tcf.debug.UseLocalAgent" value="false"/>
+<booleanAttribute key="org.eclipse.tm.tcf.debug.UseTerminal" value="true"/>
+<stringAttribute key="org.eclipse.tm.tcf.debug.WorkingDirectory" value="/tmp"/>
+</launchConfiguration>
diff --git a/expressions.c b/expressions.c
index b8b66527..b882e831 100644
--- a/expressions.c
+++ b/expressions.c
@@ -542,7 +542,7 @@ static int identifier(char * name, Value * v) {
{
Symbol sym;
if (find_symbol(expression_context, expression_frame, name, &sym) < 0) {
- error(errno, "Invalid identifier");
+ if (errno != ERR_SYM_NOT_FOUND) error(errno, "Cannot read symbol data");
}
else {
if (get_symbol_type(&sym, &v->type) < 0) {
@@ -594,31 +594,88 @@ static int identifier(char * name, Value * v) {
return sym.sym_class;
}
}
-#else
- error(ERR_UNSUPPORTED, "Symbols service not available");
#endif
return SYM_CLASS_UNKNOWN;
}
+static int64_t to_int(int mode, Value * v);
+#define TYPE_EXPR_LENGTH 64
+
+static int type_expression(int mode, int * buf) {
+ int i = 0;
+ int pos = 0;
+ int expr_buf[TYPE_EXPR_LENGTH];
+ int expr_len = 0;
+ while (text_sy == '*') {
+ next_sy();
+ if (pos >= TYPE_EXPR_LENGTH) error(ERR_BUFFER_OVERFLOW, "Type expression is too long");
+ buf[pos++] = 1;
+ }
+ if (text_sy == '(') {
+ next_sy();
+ expr_len = type_expression(mode, expr_buf);
+ if (text_sy != ')') error(ERR_INV_EXPRESSION, "')' expected");
+ next_sy();
+ }
+ while (text_sy == '[') {
+ next_sy();
+ if (text_sy != SY_VAL) error(ERR_INV_EXPRESSION, "Number expected");
+ if (pos >= TYPE_EXPR_LENGTH) error(ERR_BUFFER_OVERFLOW, "Type expression is too long");
+ buf[pos] = (int)to_int(mode, &text_val);
+ if (mode == MODE_NORMAL && buf[pos] < 1) error(ERR_INV_EXPRESSION, "Positive number expected");
+ pos++;
+ next_sy();
+ if (text_sy != ']') error(ERR_INV_EXPRESSION, "']' expected");
+ next_sy();
+ }
+ for (i = 0; i < expr_len; i++) {
+ if (pos >= TYPE_EXPR_LENGTH) error(ERR_BUFFER_OVERFLOW, "Type expression is too long");
+ buf[pos++] = expr_buf[i];
+ }
+ return pos;
+}
+
static int type_name(int mode, Symbol * type) {
Value v;
- char * name = text_val.value;
+ int expr_buf[TYPE_EXPR_LENGTH];
+ int expr_len = 0;
+ char name[256];
int sym_class;
+ int name_cnt = 0;
if (text_sy != SY_ID) return 0;
- next_sy();
+ name[0] = 0;
+ do {
+ if (strlen(text_val.value) + strlen(name) >= sizeof(name) - 1) {
+ error(ERR_BUFFER_OVERFLOW, "Type name is too long");
+ }
+ if (name[0]) strcat(name, " ");
+ strcat(name, text_val.value);
+ name_cnt++;
+ next_sy();
+ }
+ while (text_sy == SY_ID);
sym_class = identifier(name, &v);
if (sym_class != SYM_CLASS_TYPE) return 0;
- while (text_sy == '*') {
- next_sy();
- if (mode == MODE_SKIP) continue;
+ expr_len = type_expression(mode, expr_buf);
+ if (mode != MODE_SKIP) {
+ int i;
+ for (i = 0; i < expr_len; i++) {
#if SERVICE_Symbols
- if (get_symbol_pointer(&v.type, &v.type)) {
- error(errno, "Cannot get pointer type");
- }
+ if (expr_buf[i] == 1) {
+ if (get_pointer_symbol(&v.type, &v.type)) {
+ error(errno, "Cannot get pointer type");
+ }
+ }
+ else {
+ if (get_array_symbol(&v.type, expr_buf[i], &v.type)) {
+ error(errno, "Cannot get array type");
+ }
+ }
#else
- memset(&v.type, 0, sizeof(v.type));
+ memset(&v.type, 0, sizeof(v.type));
#endif
+ }
}
*type = v.type;
return 1;
@@ -820,6 +877,7 @@ static void primary_expression(int mode, Value * v) {
else if (text_sy == SY_ID) {
if (mode != MODE_SKIP) {
int sym_class = identifier((char *)text_val.value, v);
+ if (sym_class == SYM_CLASS_UNKNOWN) error(ERR_INV_EXPRESSION, "Invalid identifier");
if (sym_class == SYM_CLASS_TYPE) error(ERR_INV_EXPRESSION, "Illegal usage of type name");
}
next_sy();
@@ -836,18 +894,10 @@ static void op_deref(int mode, Value * v) {
error(ERR_INV_EXPRESSION, "Array or pointer type expected");
}
if (v->type_class == TYPE_CLASS_POINTER) {
- if (mode == MODE_TYPE) {
- v->address = 0;
- }
- else {
- load_value(v);
- switch (v->size) {
- case 2: v->address = (ContextAddress)*(uint16_t *)v->value; break;
- case 4: v->address = (ContextAddress)*(uint32_t *)v->value; break;
- case 8: v->address = (ContextAddress)*(uint64_t *)v->value; break;
- default: error(ERR_INV_EXPRESSION, "Invalid value size");
- }
- }
+ v->address = (ContextAddress)to_uns(mode, v);
+ v->remote = 1;
+ v->constant = 0;
+ v->value = NULL;
}
if (get_symbol_base_type(&v->type, &v->type) < 0) {
error(errno, "Cannot retrieve symbol type");
@@ -858,9 +908,6 @@ static void op_deref(int mode, Value * v) {
if (get_symbol_size(&v->type, expression_frame, &v->size) < 0) {
error(errno, "Cannot retrieve symbol size");
}
- v->value = NULL;
- v->remote = 1;
- v->constant = 0;
#else
error(ERR_UNSUPPORTED, "Symbols service not available");
#endif
@@ -949,18 +996,10 @@ static void op_index(int mode, Value * v) {
error(ERR_INV_EXPRESSION, "Array or pointer expected");
}
if (v->type_class == TYPE_CLASS_POINTER) {
- if (mode == MODE_TYPE) {
- v->address = 0;
- }
- else {
- load_value(v);
- switch (v->size) {
- case 2: v->address = (ContextAddress)*(uint16_t *)v->value; break;
- case 4: v->address = (ContextAddress)*(uint32_t *)v->value; break;
- case 8: v->address = (ContextAddress)*(uint64_t *)v->value; break;
- default: error(ERR_INV_EXPRESSION, "Invalid value size");
- }
- }
+ v->address = (ContextAddress)to_uns(mode, v);
+ v->remote = 1;
+ v->constant = 0;
+ v->value = NULL;
}
if (get_symbol_base_type(&v->type, &type) < 0) {
error(errno, "Cannot get array element type");
@@ -996,7 +1035,7 @@ static void op_addr(int mode, Value * v) {
set_ctx_word_value(v, v->address);
v->type_class = TYPE_CLASS_POINTER;
#if SERVICE_Symbols
- if (get_symbol_pointer(&v->type, &v->type)) {
+ if (get_pointer_symbol(&v->type, &v->type)) {
error(errno, "Cannot get pointer type");
}
#else
@@ -1268,6 +1307,20 @@ static void cast_expression(int mode, Value * v) {
}
}
break;
+ case TYPE_CLASS_ARRAY:
+ if (v->type_class == TYPE_CLASS_POINTER) {
+ v->address = (ContextAddress)to_uns(mode, v);
+ v->type = type;
+ v->type_class = type_class;
+ v->size = type_size;
+ v->remote = 1;
+ v->constant = 0;
+ v->value = NULL;
+ }
+ else {
+ error(ERR_INV_EXPRESSION, "Invalid type cast: illegal source type");
+ }
+ break;
default:
error(ERR_INV_EXPRESSION, "Invalid type cast: illegal destination type");
break;
diff --git a/symbols.h b/symbols.h
index 0d17b85b..8111f10c 100644
--- a/symbols.h
+++ b/symbols.h
@@ -31,7 +31,7 @@
typedef struct Symbol {
Context * ctx;
int sym_class;
- char location[64];
+ int location[16];
} Symbol;
#define SYM_CLASS_UNKNOWN 0
@@ -123,7 +123,10 @@ extern int get_symbol_value(const Symbol * sym, void ** value, size_t * size);
extern int get_symbol_address(const Symbol * sym, int frame, ContextAddress * address);
/* Get a type that represents a pointer to given base type */
-extern int get_symbol_pointer(const Symbol * sym, Symbol * ptr);
+extern int get_pointer_symbol(const Symbol * sym, Symbol * ptr);
+
+/* Get a type that represents an array of elements of given base type */
+extern int get_array_symbol(const Symbol * sym, size_t length, Symbol * ptr);
/*************************************************************************************************/
diff --git a/symbols_elf.c b/symbols_elf.c
index c456ac38..2d705ed7 100644
--- a/symbols_elf.c
+++ b/symbols_elf.c
@@ -50,14 +50,39 @@ typedef struct SymLocation {
void * address;
unsigned index;
unsigned dimension;
- unsigned pointer;
+ size_t pointer;
+ size_t size;
} SymLocation;
+#define LOC(sym) ((SymLocation *)(sym)->location)
+
+static Symbol * sym_buf = NULL;
+static size_t sym_buf_pos = 0;
+static size_t sym_buf_len = 0;
+static int sym_buf_event_posted = 0;
+
+static void sym_buf_event(void * arg) {
+ sym_buf_pos = 0;
+ sym_buf_event_posted = 0;
+}
+
+static size_t add_to_sym_buf(Symbol * sym) {
+ if (sym_buf_pos >= sym_buf_len) {
+ sym_buf_len = sym_buf_len == 0 ? 16 : sym_buf_len * 2;
+ sym_buf = loc_realloc(sym_buf, sym_buf_len * sizeof(Symbol));
+ }
+ sym_buf[sym_buf_pos++] = *sym;
+ if (!sym_buf_event_posted) {
+ post_event(sym_buf_event, NULL);
+ sym_buf_event_posted = 1;
+ }
+ return sym_buf_pos;
+}
+
static void object2symbol(Context * ctx, ObjectInfo * obj, Symbol * sym) {
- SymLocation * loc = (SymLocation *)sym->location;
memset(sym, 0, sizeof(Symbol));
sym->ctx = ctx;
- loc->obj = obj;
+ LOC(sym)->obj = obj;
switch (obj->mTag) {
case TAG_global_subroutine:
case TAG_subroutine:
@@ -155,7 +180,6 @@ static int find_in_dwarf(DWARFCache * cache, Context * ctx, char * name, Context
static int find_in_sym_table(DWARFCache * cache, Context * ctx, char * name, Symbol * sym) {
unsigned m = 0;
unsigned h = calc_symbol_name_hash(name);
- SymLocation * loc = (SymLocation *)sym->location;
while (m < cache->mSymSectionsCnt) {
SymbolSection * tbl = cache->mSymSections[m];
unsigned n = tbl->mSymbolHash[h];
@@ -177,8 +201,8 @@ static int find_in_sym_table(DWARFCache * cache, Context * ctx, char * name, Sym
sym->sym_class = SYM_CLASS_REFERENCE;
break;
}
- loc->tbl = tbl;
- loc->index = n;
+ LOC(sym)->tbl = tbl;
+ LOC(sym)->index = n;
return 1;
}
n = tbl->mHashNext[n];
@@ -205,7 +229,7 @@ int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
else {
memset(sym, 0, sizeof(Symbol));
sym->ctx = ctx;
- ((SymLocation *)sym->location)->addr = ptr;
+ LOC(sym)->addr = ptr;
if (SYM_IS_TEXT(type)) {
sym->sym_class = SYM_CLASS_FUNCTION;
@@ -251,8 +275,7 @@ int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
}
if (!found) {
- SymLocation * loc = (SymLocation *)sym->location;
- found = find_test_symbol(ctx, name, sym, &loc->address) >= 0;
+ found = find_test_symbol(ctx, name, sym, &LOC(sym)->address) >= 0;
}
if (error == 0 && !found) error = ERR_SYM_NOT_FOUND;
@@ -342,25 +365,34 @@ int enumerate_symbols(Context * ctx, int frame, EnumerateSymbolsCallBack * call_
char * symbol2id(const Symbol * sym) {
static char id[256];
- const SymLocation * loc = (SymLocation *)sym->location;
- ELF_File * file = NULL;
- unsigned long long obj_index = 0;
- unsigned tbl_index = 0;
- if (loc->obj != NULL) file = loc->obj->mCompUnit->mFile;
- if (loc->tbl != NULL) file = loc->tbl->mFile;
- if (file == NULL) return "SYM";
- if (loc->obj != NULL) obj_index = loc->obj->mID;
- if (loc->tbl != NULL) tbl_index = loc->tbl->mIndex + 1;
- snprintf(id, sizeof(id), "SYM%X.%lX.%lX.%X.%llX.%X.%X.%X.%X.%s",
- sym->sym_class, (unsigned long)file->dev, (unsigned long)file->ino,
- (unsigned)file->mtime & 0xffff, obj_index, tbl_index,
- loc->index, loc->dimension, loc->pointer, container_id(sym->ctx));
+ if (LOC(sym)->pointer) {
+ char base[256];
+ assert(LOC(sym)->pointer <= sym_buf_pos);
+ assert(sym->ctx == sym_buf[LOC(sym)->pointer - 1].ctx);
+ assert(sym->sym_class == SYM_CLASS_TYPE);
+ strcpy(base, symbol2id(sym_buf + (LOC(sym)->pointer - 1)));
+ snprintf(id, sizeof(id), "PTR%zX.%s", LOC(sym)->size, base);
+ }
+ else {
+ ELF_File * file = NULL;
+ unsigned long long obj_index = 0;
+ unsigned tbl_index = 0;
+ if (LOC(sym)->obj != NULL) file = LOC(sym)->obj->mCompUnit->mFile;
+ if (LOC(sym)->tbl != NULL) file = LOC(sym)->tbl->mFile;
+ if (file == NULL) return "SYM";
+ if (LOC(sym)->obj != NULL) obj_index = LOC(sym)->obj->mID;
+ if (LOC(sym)->tbl != NULL) tbl_index = LOC(sym)->tbl->mIndex + 1;
+ snprintf(id, sizeof(id), "SYM%X.%lX.%lX.%X.%llX.%X.%X.%X.%zX.%s",
+ sym->sym_class, (unsigned long)file->dev, (unsigned long)file->ino,
+ (unsigned)file->mtime & 0xffff, obj_index, tbl_index,
+ LOC(sym)->index, LOC(sym)->dimension, LOC(sym)->size, container_id(sym->ctx));
+ }
return id;
}
-static unsigned read_hex(char ** s) {
- unsigned res = 0;
+static unsigned long read_hex(char ** s) {
+ unsigned long res = 0;
char * p = *s;
for (;;) {
if (*p >= '0' && *p <= '9') res = (res << 4) | (*p - '0');
@@ -391,64 +423,75 @@ int id2symbol(char * id, Symbol * sym) {
unsigned mtime = 0;
unsigned long long obj_index = 0;
unsigned tbl_index = 0;
- SymLocation * loc = (SymLocation *)sym->location;
ELF_File * file = NULL;
char * p;
Trap trap;
memset(sym, 0, sizeof(Symbol));
- if (id == NULL || id[0] != 'S' || id[1] != 'Y' || id[2] != 'M') {
- errno = ERR_INV_CONTEXT;
- return -1;
- }
- p = id + 3;
- if (*p == 0) return 0;
- sym->sym_class = read_hex(&p);
- if (*p == '.') p++;
- dev = read_hex(&p);
- if (*p == '.') p++;
- ino = read_hex(&p);
- if (*p == '.') p++;
- mtime = read_hex(&p);
- if (*p == '.') p++;
- obj_index = read_hex_ll(&p);
- if (*p == '.') p++;
- tbl_index = read_hex(&p);
- if (*p == '.') p++;
- loc->index = read_hex(&p);
- if (*p == '.') p++;
- loc->dimension = read_hex(&p);
- if (*p == '.') p++;
- loc->pointer = read_hex(&p);
- if (*p == '.') p++;
- sym->ctx = id2ctx(p);
- if (sym->ctx == NULL) {
- errno = ERR_INV_CONTEXT;
- return -1;
- }
- file = elf_list_first(sym->ctx, 0, ~(ContextAddress)0);
- if (file == NULL) return -1;
- while (file->dev != dev || file->ino != ino || ((unsigned)file->mtime & 0xffff) != mtime) {
- file = elf_list_next(sym->ctx);
- if (file == NULL) break;
- }
- elf_list_done(sym->ctx);
- if (file == NULL) {
- errno = ERR_INV_CONTEXT;
- return -1;
+ if (id != NULL && id[0] == 'P' && id[1] == 'T' && id[2] == 'R') {
+ Symbol base;
+ p = id + 3;
+ LOC(sym)->size = read_hex(&p);
+ if (*p == '.') p++;
+ if (id2symbol(p, &base)) return -1;
+ LOC(sym)->pointer = add_to_sym_buf(&base);
+ sym->ctx = base.ctx;
+ sym->sym_class = SYM_CLASS_TYPE;
+ return 0;
}
- if (set_trap(&trap)) {
- DWARFCache * cache = get_dwarf_cache(file);
- if (obj_index) {
- loc->obj = find_object(cache, obj_index);
- if (loc->obj == NULL) exception(ERR_INV_CONTEXT);
+ else if (id != NULL && id[0] == 'S' && id[1] == 'Y' && id[2] == 'M') {
+ p = id + 3;
+ if (*p == 0) return 0;
+ sym->sym_class = read_hex(&p);
+ if (*p == '.') p++;
+ dev = read_hex(&p);
+ if (*p == '.') p++;
+ ino = read_hex(&p);
+ if (*p == '.') p++;
+ mtime = read_hex(&p);
+ if (*p == '.') p++;
+ obj_index = read_hex_ll(&p);
+ if (*p == '.') p++;
+ tbl_index = read_hex(&p);
+ if (*p == '.') p++;
+ LOC(sym)->index = read_hex(&p);
+ if (*p == '.') p++;
+ LOC(sym)->dimension = read_hex(&p);
+ if (*p == '.') p++;
+ LOC(sym)->size = read_hex(&p);
+ if (*p == '.') p++;
+ sym->ctx = id2ctx(p);
+ if (sym->ctx == NULL) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
}
- if (tbl_index) {
- if (tbl_index > cache->mSymSectionsCnt) exception(ERR_INV_CONTEXT);
- loc->tbl = cache->mSymSections[tbl_index - 1];
+ file = elf_list_first(sym->ctx, 0, ~(ContextAddress)0);
+ if (file == NULL) return -1;
+ while (file->dev != dev || file->ino != ino || ((unsigned)file->mtime & 0xffff) != mtime) {
+ file = elf_list_next(sym->ctx);
+ if (file == NULL) break;
}
- clear_trap(&trap);
- return 0;
+ elf_list_done(sym->ctx);
+ if (file == NULL) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ if (set_trap(&trap)) {
+ DWARFCache * cache = get_dwarf_cache(file);
+ if (obj_index) {
+ LOC(sym)->obj = find_object(cache, obj_index);
+ if (LOC(sym)->obj == NULL) exception(ERR_INV_CONTEXT);
+ }
+ if (tbl_index) {
+ if (tbl_index > cache->mSymSectionsCnt) exception(ERR_INV_CONTEXT);
+ LOC(sym)->tbl = cache->mSymSections[tbl_index - 1];
+ }
+ clear_trap(&trap);
+ return 0;
+ }
+ }
+ else {
+ errno = ERR_INV_CONTEXT;
}
return -1;
}
@@ -492,13 +535,14 @@ static Elf32_Sym * sym32;
static Elf64_Sym * sym64;
static int unpack(const Symbol * sym) {
- const SymLocation * loc = (const SymLocation *)sym->location;
+ assert(LOC(sym)->pointer == 0);
+ assert(LOC(sym)->size == 0);
file = NULL;
cache = NULL;
- obj = loc->obj;
- tbl = loc->tbl;
- sym_index = loc->index;
- dimension = loc->dimension;
+ obj = LOC(sym)->obj;
+ tbl = LOC(sym)->tbl;
+ sym_index = LOC(sym)->index;
+ dimension = LOC(sym)->dimension;
sym32 = NULL;
sym64 = NULL;
if (obj != NULL) file = obj->mCompUnit->mFile;
@@ -577,7 +621,7 @@ static U8_T get_object_length(Context * ctx, int frame, ObjectInfo * obj) {
}
int get_symbol_type(const Symbol * sym, Symbol * type) {
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
*type = *sym;
return 0;
}
@@ -589,8 +633,12 @@ int get_symbol_type(const Symbol * sym, Symbol * type) {
}
int get_symbol_type_class(const Symbol * sym, int * type_class) {
- if (((SymLocation *)sym->location)->pointer) {
- *type_class = TYPE_CLASS_POINTER;
+ if (LOC(sym)->pointer) {
+ *type_class = LOC(sym)->size == 0 ? TYPE_CLASS_POINTER : TYPE_CLASS_ARRAY;
+ return 0;
+ }
+ if (LOC(sym)->size) {
+ *type_class = TYPE_CLASS_CARDINAL;
return 0;
}
if (unpack(sym) < 0) return -1;
@@ -665,7 +713,7 @@ int get_symbol_type_class(const Symbol * sym, int * type_class) {
}
int get_symbol_name(const Symbol * sym, char ** name) {
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
*name = NULL;
return 0;
}
@@ -686,8 +734,18 @@ int get_symbol_name(const Symbol * sym, char ** name) {
}
int get_symbol_size(const Symbol * sym, int frame, size_t * size) {
- if (((SymLocation *)sym->location)->pointer) {
- *size = sizeof(void *);
+ if (LOC(sym)->pointer) {
+ if (LOC(sym)->size > 0) {
+ if (get_symbol_size(sym_buf + (LOC(sym)->pointer - 1), frame, size)) return -1;
+ *size *= LOC(sym)->size;
+ }
+ else {
+ *size = sizeof(void *);
+ }
+ return 0;
+ }
+ if (LOC(sym)->size) {
+ *size = LOC(sym)->size;
return 0;
}
if (unpack(sym) < 0) return -1;
@@ -744,11 +802,14 @@ int get_symbol_size(const Symbol * sym, int frame, size_t * size) {
}
int get_symbol_base_type(const Symbol * sym, Symbol * base_type) {
- if (((SymLocation *)sym->location)->pointer) {
- *base_type = *sym;
- ((SymLocation *)base_type->location)->pointer--;
+ if (LOC(sym)->pointer) {
+ *base_type = sym_buf[LOC(sym)->pointer - 1];
return 0;
}
+ if (LOC(sym)->size) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
if (unpack(sym) < 0) return -1;
if (obj != NULL) {
obj = get_object_type(obj);
@@ -761,7 +822,7 @@ int get_symbol_base_type(const Symbol * sym, Symbol * base_type) {
}
if (idx != NULL && idx->mSibling != NULL) {
*base_type = *sym;
- ((SymLocation *)base_type->location)->dimension++;
+ LOC(base_type)->dimension++;
return 0;
}
}
@@ -777,7 +838,14 @@ int get_symbol_base_type(const Symbol * sym, Symbol * base_type) {
}
int get_symbol_index_type(const Symbol * sym, Symbol * index_type) {
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer) {
+ memset(index_type, 0, sizeof(Symbol));
+ index_type->ctx = sym->ctx;
+ index_type->sym_class = SYM_CLASS_TYPE;
+ LOC(index_type)->size = sizeof(size_t);
+ return 0;
+ }
+ if (LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
@@ -802,10 +870,14 @@ int get_symbol_index_type(const Symbol * sym, Symbol * index_type) {
}
int get_symbol_length(const Symbol * sym, int frame, unsigned long * length) {
- if (((SymLocation *)sym->location)->pointer) {
- *length = 1;
+ if (LOC(sym)->pointer) {
+ *length = LOC(sym)->size == 0 ? 1 : LOC(sym)->size;
return 0;
}
+ if (LOC(sym)->size) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
if (unpack(sym) < 0) return -1;
if (obj != NULL) {
obj = get_object_type(obj);
@@ -831,7 +903,7 @@ int get_symbol_length(const Symbol * sym, int frame, unsigned long * length) {
int get_symbol_children(const Symbol * sym, Symbol ** children, int * count) {
int n = 0;
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
*children = NULL;
*count = 0;
return 0;
@@ -858,7 +930,7 @@ int get_symbol_children(const Symbol * sym, Symbol ** children, int * count) {
}
int get_symbol_offset(const Symbol * sym, unsigned long * offset) {
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
@@ -874,7 +946,7 @@ int get_symbol_offset(const Symbol * sym, unsigned long * offset) {
}
int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
@@ -906,12 +978,12 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
}
int get_symbol_address(const Symbol * sym, int frame, ContextAddress * address) {
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
- if (((SymLocation *)sym->location)->address != NULL) {
- *address = (ContextAddress)((SymLocation *)sym->location)->address;
+ if (LOC(sym)->address != NULL) {
+ *address = (ContextAddress)LOC(sym)->address;
return 0;
}
if (unpack(sym) < 0) return -1;
@@ -938,15 +1010,19 @@ int get_symbol_address(const Symbol * sym, int frame, ContextAddress * address)
}
}
#if defined(_WRS_KERNEL)
- if ((*address = (ContextAddress)((SymLocation *)sym->location)->addr) != 0) return 0;
+ if ((*address = (ContextAddress)LOC(sym)->addr) != 0) return 0;
#endif
errno = ERR_INV_CONTEXT;
return -1;
}
-int get_symbol_pointer(const Symbol * sym, Symbol * ptr) {
- *ptr = *sym;
- if (!((SymLocation *)ptr->location)->pointer) {
+int get_pointer_symbol(const Symbol * sym, Symbol * ptr) {
+ return get_array_symbol(sym, 0, ptr);
+}
+
+int get_array_symbol(const Symbol * sym, size_t length, Symbol * ptr) {
+ Symbol type = *sym;
+ if (!LOC(&type)->pointer && !LOC(sym)->size) {
if (unpack(ptr) < 0) return -1;
obj = get_object_type(obj);
if (obj != NULL) {
@@ -957,8 +1033,12 @@ int get_symbol_pointer(const Symbol * sym, Symbol * ptr) {
ptr->sym_class = SYM_CLASS_TYPE;
}
}
- assert(ptr->sym_class == SYM_CLASS_TYPE);
- ((SymLocation *)ptr->location)->pointer++;
+ assert(type.sym_class == SYM_CLASS_TYPE);
+ memset(ptr, 0, sizeof(Symbol));
+ ptr->ctx = type.ctx;
+ ptr->sym_class = SYM_CLASS_TYPE;
+ LOC(ptr)->pointer = add_to_sym_buf(&type);
+ LOC(ptr)->size = length;
return 0;
}
diff --git a/symbols_win32.c b/symbols_win32.c
index 6453de52..c59bdcf0 100644
--- a/symbols_win32.c
+++ b/symbols_win32.c
@@ -24,7 +24,9 @@
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
+#include <wchar.h>
#include "errors.h"
+#include "events.h"
#include "tcf_elf.h"
#include "myalloc.h"
#include "symbols.h"
@@ -46,13 +48,74 @@
typedef struct SymLocation {
ULONG64 module;
ULONG index;
- unsigned pointer;
+ size_t size;
+ size_t pointer;
+ unsigned char sign;
+ unsigned char real;
void * address;
} SymLocation;
+#define LOC(sym) ((SymLocation *)(sym)->location)
+
+struct TypeInfo {
+ char * name;
+ unsigned char size;
+ unsigned char sign;
+ unsigned char real;
+};
+
+static const struct TypeInfo basic_type_info[] = {
+ { "char", sizeof(char), 1, 0 },
+ { "unsigned char", sizeof(char), 0, 0 },
+ { "signed char", sizeof(char), 1, 0 },
+ { "short", sizeof(short), 1, 0 },
+ { "unsigned short", sizeof(short), 0, 0 },
+ { "signed short", sizeof(short), 1, 0 },
+ { "int", sizeof(int), 1, 0 },
+ { "unsigned", sizeof(int), 0, 0 },
+ { "unsigned int", sizeof(int), 0, 0 },
+ { "signed int", sizeof(int), 1, 0 },
+ { "long", sizeof(long), 1, 0 },
+ { "unsigned long", sizeof(long), 0, 0 },
+ { "signed long", sizeof(long), 1, 0 },
+ { "long int", sizeof(long), 1, 0 },
+ { "unsigned long int", sizeof(long), 0, 0 },
+ { "signed long int", sizeof(long), 1, 0 },
+ { "long long", sizeof(int64_t), 1, 0 },
+ { "unsigned long long", sizeof(int64_t), 0, 0 },
+ { "signed long long", sizeof(int64_t), 1, 0 },
+ { "float", sizeof(float), 1, 1 },
+ { "double", sizeof(double), 1, 1 },
+ { "long double", sizeof(long double), 1, 1 },
+ { NULL }
+};
+
static char * tmp_buf = NULL;
static int tmp_buf_size = 0;
+static Symbol * sym_buf = NULL;
+static size_t sym_buf_pos = 0;
+static size_t sym_buf_len = 0;
+static int sym_buf_event_posted = 0;
+
+static void sym_buf_event(void * arg) {
+ sym_buf_pos = 0;
+ sym_buf_event_posted = 0;
+}
+
+static size_t add_to_sym_buf(Symbol * sym) {
+ if (sym_buf_pos >= sym_buf_len) {
+ sym_buf_len = sym_buf_len == 0 ? 16 : sym_buf_len * 2;
+ sym_buf = loc_realloc(sym_buf, sym_buf_len * sizeof(Symbol));
+ }
+ sym_buf[sym_buf_pos++] = *sym;
+ if (!sym_buf_event_posted) {
+ post_event(sym_buf_event, NULL);
+ sym_buf_event_posted = 1;
+ }
+ return sym_buf_pos;
+}
+
static int get_stack_frame(Context * ctx, int frame, IMAGEHLP_STACK_FRAME * stack_frame) {
memset(stack_frame, 0, sizeof(IMAGEHLP_STACK_FRAME));
if (frame != STACK_NO_FRAME && ctx->parent != NULL) {
@@ -70,7 +133,7 @@ static int get_sym_info(const Symbol * sym, DWORD index, SYMBOL_INFO ** res) {
info->SizeOfStruct = sizeof(SYMBOL_INFO);
info->MaxNameLen = MAX_SYM_NAME;
- if (!SymFromIndex(process, ((SymLocation *)sym->location)->module, index, info)) {
+ if (!SymFromIndex(process, LOC(sym)->module, index, info)) {
set_win32_errno(GetLastError());
return -1;
}
@@ -124,11 +187,10 @@ static void tag2symclass(Symbol * sym, int tag) {
}
static void syminfo2symbol(Context * ctx, SYMBOL_INFO * info, Symbol * sym) {
- SymLocation * loc = (SymLocation *)sym->location;
memset(sym, 0, sizeof(Symbol));
sym->ctx = ctx;
- loc->module = info->ModBase;
- loc->index = info->Index;
+ LOC(sym)->module = info->ModBase;
+ LOC(sym)->index = info->Index;
tag2symclass(sym, info->Tag);
}
@@ -138,7 +200,7 @@ static int get_type_tag(Symbol * type, DWORD * tag) {
if (get_type_info(type, TI_GET_SYMTAG, &dword) < 0) return -1;
if (dword != SymTagTypedef && dword != SymTagFunction && dword != SymTagData) break;
if (get_type_info(type, TI_GET_TYPE, &dword) < 0) return -1;
- ((SymLocation *)type->location)->index = dword;
+ LOC(type)->index = dword;
}
type->sym_class = SYM_CLASS_TYPE;
*tag = dword;
@@ -148,63 +210,118 @@ static int get_type_tag(Symbol * type, DWORD * tag) {
char * symbol2id(const Symbol * sym) {
static char buf[256];
const SymLocation * loc = (const SymLocation *)sym->location;
- snprintf(buf, sizeof(buf), "SYM%llX.%lX.%X.%s",
- loc->module, loc->index, loc->pointer, container_id(sym->ctx));
+ if (loc->pointer) {
+ char base[256];
+ assert(loc->pointer <= sym_buf_pos);
+ assert(sym->ctx == sym_buf[loc->pointer - 1].ctx);
+ assert(sym->sym_class == SYM_CLASS_TYPE);
+ strcpy(base, symbol2id(sym_buf + (loc->pointer - 1)));
+ snprintf(buf, sizeof(buf), "PTR%X.%s", loc->size, base);
+ }
+ else {
+ snprintf(buf, sizeof(buf), "SYM%llX.%lX.%X.%d.%d.%s",
+ loc->module, loc->index, loc->size,
+ loc->sign, loc->real, container_id(sym->ctx));
+ }
return buf;
}
int id2symbol(char * id, Symbol * sym) {
ULONG64 module = 0;
ULONG index = 0;
- unsigned pointer = 0;
- SymLocation * loc = (SymLocation *)sym->location;
+ size_t pointer = 0;
+ size_t size = 0;
+ unsigned char sign = 0;
+ unsigned char real = 0;
char * p;
- if (id == NULL || id[0] != 'S' || id[1] != 'Y' || id[2] != 'M') {
- errno = ERR_INV_CONTEXT;
- return -1;
- }
- p = id + 3;
- for (;;) {
- if (*p >= '0' && *p <= '9') module = (module << 4) | (*p - '0');
- else if (*p >= 'A' && *p <= 'F') module = (module << 4) | (*p - 'A' + 10);
- else break;
- p++;
- }
- if (*p++ != '.') {
- errno = ERR_INV_CONTEXT;
- return -1;
+ memset(sym, 0, sizeof(Symbol));
+ if (id != NULL && id[0] == 'P' && id[1] == 'T' && id[2] == 'R') {
+ p = id + 3;
+ for (;;) {
+ if (*p >= '0' && *p <= '9') size = (size << 4) | (*p - '0');
+ else if (*p >= 'A' && *p <= 'F') size = (size << 4) | (*p - 'A' + 10);
+ else break;
+ p++;
+ }
+ if (*p++ != '.') {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ if (id2symbol(p, sym)) return -1;
+ pointer = add_to_sym_buf(sym);
}
- for (;;) {
- if (*p >= '0' && *p <= '9') index = (index << 4) | (*p - '0');
- else if (*p >= 'A' && *p <= 'F') index = (index << 4) | (*p - 'A' + 10);
- else break;
+ else if (id != NULL && id[0] == 'S' && id[1] == 'Y' && id[2] == 'M') {
+ p = id + 3;
+ for (;;) {
+ if (*p >= '0' && *p <= '9') module = (module << 4) | (*p - '0');
+ else if (*p >= 'A' && *p <= 'F') module = (module << 4) | (*p - 'A' + 10);
+ else break;
+ p++;
+ }
+ if (*p++ != '.') {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ for (;;) {
+ if (*p >= '0' && *p <= '9') index = (index << 4) | (*p - '0');
+ else if (*p >= 'A' && *p <= 'F') index = (index << 4) | (*p - 'A' + 10);
+ else break;
+ p++;
+ }
+ if (*p++ != '.') {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ for (;;) {
+ if (*p >= '0' && *p <= '9') size = (size << 4) | (*p - '0');
+ else if (*p >= 'A' && *p <= 'F') size = (size << 4) | (*p - 'A' + 10);
+ else break;
+ p++;
+ }
+ if (*p++ != '.') {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ if (*p == '1') {
+ sign = 1;
+ }
+ else if (*p != '0') {
+ errno = ERR_INV_CONTEXT; return -1;
+ }
p++;
- }
- if (*p++ != '.') {
- errno = ERR_INV_CONTEXT;
- return -1;
- }
- for (;;) {
- if (*p >= '0' && *p <= '9') pointer = (pointer << 4) | (*p - '0');
- else if (*p >= 'A' && *p <= 'F') pointer = (pointer << 4) | (*p - 'A' + 10);
- else break;
+ if (*p++ != '.') {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ if (*p == '1') {
+ real = 1;
+ }
+ else if (*p != '0') {
+ errno = ERR_INV_CONTEXT; return -1;
+ }
p++;
+ if (*p++ != '.') {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ sym->ctx = id2ctx(p);
}
- if (*p++ != '.') {
+ else {
errno = ERR_INV_CONTEXT;
return -1;
}
- memset(sym, 0, sizeof(Symbol));
- sym->ctx = id2ctx(p);
- loc->module = module;
- loc->index = index;
- loc->pointer = pointer;
+ LOC(sym)->module = module;
+ LOC(sym)->index = index;
+ LOC(sym)->pointer = pointer;
+ LOC(sym)->size = size;
+ LOC(sym)->sign = sign;
+ LOC(sym)->real = real;
if (sym->ctx == NULL) {
errno = ERR_INV_CONTEXT;
return -1;
}
- if (loc->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
sym->sym_class = SYM_CLASS_TYPE;
}
else {
@@ -221,8 +338,20 @@ int get_symbol_type_class(const Symbol * sym, int * type_class) {
DWORD tag = 0;
DWORD base = 0;
- if (((SymLocation *)sym->location)->pointer) {
- *type_class = TYPE_CLASS_POINTER;
+ if (LOC(sym)->pointer) {
+ *type_class = LOC(sym)->size == 0 ? TYPE_CLASS_POINTER : TYPE_CLASS_ARRAY;
+ return 0;
+ }
+ if (LOC(sym)->size) {
+ if (LOC(sym)->real) {
+ *type_class = TYPE_CLASS_REAL;
+ }
+ else if (LOC(sym)->sign) {
+ *type_class = TYPE_CLASS_INTEGER;
+ }
+ else {
+ *type_class = TYPE_CLASS_CARDINAL;
+ }
return 0;
}
if (get_type_tag(&type, &tag)) return -1;
@@ -287,11 +416,23 @@ int get_symbol_name(const Symbol * sym, char ** name) {
WCHAR * ptr = NULL;
char * res = NULL;
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer) {
*name = NULL;
return 0;
}
- if (get_type_info(sym, TI_GET_SYMNAME, &ptr) < 0) return -1;
+ if (LOC(sym)->size) {
+ const struct TypeInfo * p = basic_type_info;
+ while (p->name != NULL) {
+ if (p->size == LOC(sym)->size && p->sign == LOC(sym)->sign && p->real == LOC(sym)->real) {
+ res = loc_strdup(p->name);
+ break;
+ }
+ p++;
+ }
+ *name = res;
+ return 0;
+ }
+ if (get_type_info(sym, TI_GET_SYMNAME, &ptr) < 0) ptr = NULL;
if (ptr != NULL && wcscmp(ptr, L"<unnamed-tag>") == 0) ptr = NULL;
if (ptr != NULL) {
int len = 0;
@@ -316,6 +457,29 @@ int get_symbol_name(const Symbol * sym, char ** name) {
memcpy(res, tmp_buf, len);
res[len] = 0;
}
+ else {
+ DWORD tag = 0;
+ Symbol type = *sym;
+ if (get_type_tag(&type, &tag)) return -1;
+ if (tag == SymTagBaseType) {
+ size_t size = 0;
+ int type_class = 0;
+ unsigned char sign = 0;
+ unsigned char real = 0;
+ const struct TypeInfo * p = basic_type_info;
+ if (get_symbol_size(&type, STACK_NO_FRAME, &size)) return -1;
+ if (get_symbol_type_class(&type, &type_class)) return -1;
+ if (type_class == TYPE_CLASS_INTEGER) sign = 1;
+ else if (type_class == TYPE_CLASS_INTEGER) real = sign = 1;
+ while (p->name != NULL) {
+ if (p->size == size && p->sign == sign && p->real == real) {
+ res = loc_strdup(p->name);
+ break;
+ }
+ p++;
+ }
+ }
+ }
*name = res;
return 0;
}
@@ -325,8 +489,18 @@ int get_symbol_size(const Symbol * sym, int frame, size_t * size) {
Symbol type = *sym;
DWORD tag = 0;
- if (((SymLocation *)sym->location)->pointer) {
- *size = sizeof(void *);
+ if (LOC(sym)->pointer) {
+ if (LOC(sym)->size > 0) {
+ if (get_symbol_size(sym_buf + (LOC(sym)->pointer - 1), frame, size)) return -1;
+ *size *= LOC(sym)->size;
+ }
+ else {
+ *size = sizeof(void *);
+ }
+ return 0;
+ }
+ if (LOC(sym)->size) {
+ *size = LOC(sym)->size;
return 0;
}
if (get_type_tag(&type, &tag)) return -1;
@@ -340,7 +514,7 @@ int get_symbol_type(const Symbol * sym, Symbol * type) {
DWORD tag = 0;
*type = *sym;
- if (!((SymLocation *)type->location)->pointer) {
+ if (!LOC(type)->pointer && !LOC(type)->size) {
if (get_type_tag(type, &tag)) return -1;
}
assert(type->sym_class == SYM_CLASS_TYPE);
@@ -352,13 +526,17 @@ int get_symbol_base_type(const Symbol * sym, Symbol * type) {
DWORD index = 0;
*type = *sym;
- if (((SymLocation *)type->location)->pointer) {
- ((SymLocation *)type->location)->pointer--;
+ if (LOC(type)->pointer) {
+ *type = sym_buf[LOC(type)->pointer - 1];
return 0;
}
+ if (LOC(type)->size) {
+ errno = ERR_INV_CONTEXT;
+ return 1;
+ }
if (get_type_tag(type, &tag)) return -1;
if (get_type_info(type, TI_GET_TYPE, &index) < 0) return -1;
- ((SymLocation *)type->location)->index = index;
+ LOC(type)->index = index;
return 0;
}
@@ -367,14 +545,21 @@ int get_symbol_index_type(const Symbol * sym, Symbol * type) {
DWORD tag = 0;
DWORD index = 0;
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer) {
+ memset(type, 0, sizeof(Symbol));
+ type->ctx = sym->ctx;
+ type->sym_class = SYM_CLASS_TYPE;
+ LOC(type)->size = sizeof(size_t);
+ return 0;
+ }
+ if (LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
*type = *sym;
if (get_type_tag(type, &tag)) return -1;
if (get_type_info(type, TI_GET_ARRAYINDEXTYPEID, &index) < 0) return -1;
- ((SymLocation *)type->location)->index = index;
+ LOC(type)->index = index;
return 0;
}
@@ -384,10 +569,14 @@ int get_symbol_length(const Symbol * sym, int frame, unsigned long * length) {
Symbol type = *sym;
DWORD tag = 0;
- if (((SymLocation *)sym->location)->pointer) {
- *length = 1;
+ if (LOC(sym)->pointer) {
+ *length = LOC(sym)->size == 0 ? 1 : LOC(sym)->size;
return 0;
}
+ if (LOC(sym)->size) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
if (get_type_tag(&type, &tag)) return -1;
if (get_type_info(&type, TI_GET_COUNT, &res) < 0) return -1;
@@ -405,7 +594,7 @@ int get_symbol_children(const Symbol * sym, Symbol ** children, int * count) {
Symbol type = *sym;
DWORD tag = 0;
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
*children = NULL;
*count = 0;
return 0;
@@ -424,7 +613,7 @@ int get_symbol_children(const Symbol * sym, Symbol ** children, int * count) {
DWORD dword = 0;
Symbol * x = res + params->Start++;
*x = *sym;
- ((SymLocation *)x->location)->index = params->ChildId[i];
+ LOC(x)->index = params->ChildId[i];
if (get_type_info(x, TI_GET_SYMTAG, &dword) < 0) return -1;
tag2symclass(x, dword);
}
@@ -438,7 +627,7 @@ int get_symbol_children(const Symbol * sym, Symbol ** children, int * count) {
int get_symbol_offset(const Symbol * sym, unsigned long * offset) {
DWORD dword = 0;
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
@@ -453,7 +642,7 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
void * data_addr = &data.bVal;
size_t data_size = 0;
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
@@ -502,15 +691,15 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
int get_symbol_address(const Symbol * sym, int frame, ContextAddress * addr) {
SYMBOL_INFO * info = NULL;
- if (((SymLocation *)sym->location)->address != NULL) {
- *addr = (ContextAddress)((SymLocation *)sym->location)->address;
+ if (LOC(sym)->address != NULL) {
+ *addr = (ContextAddress)LOC(sym)->address;
return 0;
}
- if (((SymLocation *)sym->location)->pointer) {
+ if (LOC(sym)->pointer || LOC(sym)->size) {
errno = ERR_INV_CONTEXT;
return -1;
}
- if (get_sym_info(sym, ((SymLocation *)sym->location)->index, &info) < 0) return -1;
+ if (get_sym_info(sym, LOC(sym)->index, &info) < 0) return -1;
*addr = (ContextAddress)info->Address;
if ((info->Flags & SYMFLAG_FRAMEREL) || (info->Flags & SYMFLAG_REGREL)) {
@@ -522,15 +711,22 @@ int get_symbol_address(const Symbol * sym, int frame, ContextAddress * addr) {
return 0;
}
-int get_symbol_pointer(const Symbol * sym, Symbol * ptr) {
- DWORD tag = 0;
+int get_pointer_symbol(const Symbol * sym, Symbol * ptr) {
+ return get_array_symbol(sym, 0, ptr);
+}
- *ptr = *sym;
- if (!((SymLocation *)ptr->location)->pointer) {
- if (get_type_tag(ptr, &tag)) return -1;
- }
- assert(ptr->sym_class == SYM_CLASS_TYPE);
- ((SymLocation *)ptr->location)->pointer++;
+int get_array_symbol(const Symbol * sym, size_t length, Symbol * ptr) {
+ Symbol type = *sym;
+ if (!LOC(&type)->pointer && !LOC(&type)->size) {
+ DWORD tag = 0;
+ if (get_type_tag(&type, &tag)) return -1;
+ }
+ assert(type.sym_class == SYM_CLASS_TYPE);
+ memset(ptr, 0, sizeof(Symbol));
+ ptr->ctx = type.ctx;
+ ptr->sym_class = SYM_CLASS_TYPE;
+ LOC(ptr)->pointer = add_to_sym_buf(&type);
+ LOC(ptr)->size = length;
return 0;
}
@@ -588,15 +784,31 @@ static int find_pe_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
return -1;
}
-int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
- if (find_pe_symbol(ctx, frame, name, sym) < 0) {
- int err = errno;
- SymLocation * loc = (SymLocation *)sym->location;
- if (find_test_symbol(ctx, name, sym, &loc->address) >= 0) return 0;
- errno = err;
- return -1;
+static int find_basic_type_symbol(Context * ctx, char * name, Symbol * sym) {
+ const struct TypeInfo * p = basic_type_info;
+ while (p->name != NULL) {
+ if (strcmp(p->name, name) == 0) break;
+ p++;
}
- return 0;
+ if (p->name != NULL) {
+ memset(sym, 0, sizeof(*sym));
+ sym->ctx = ctx;
+ sym->sym_class = SYM_CLASS_TYPE;
+ LOC(sym)->size = p->size;
+ LOC(sym)->sign = p->sign;
+ LOC(sym)->real = p->real;
+ return 0;
+ }
+ errno = ERR_SYM_NOT_FOUND;
+ return -1;
+}
+
+int find_symbol(Context * ctx, int frame, char * name, Symbol * sym) {
+ if (find_pe_symbol(ctx, frame, name, sym) >= 0) return 0;
+ if (errno != ERR_SYM_NOT_FOUND) return -1;
+ if (find_test_symbol(ctx, name, sym, &LOC(sym)->address) >= 0) return 0;
+ if (find_basic_type_symbol(ctx, name, sym) >= 0) return 0;
+ return -1;
}
typedef struct EnumerateSymbolsContext {

Back to the top