diff options
author | eutarass | 2009-09-21 21:29:56 +0000 |
---|---|---|
committer | eutarass | 2009-09-21 21:29:56 +0000 |
commit | 5cc9ef8eaed360cdf39bfacdbb15b83ddf306505 (patch) | |
tree | 44ff0ce0503dc78beee0cae4891cf75e44c074a7 | |
parent | 7a0aa29bb6633508dc5a3f895094c85a28125139 (diff) | |
download | org.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.launch | 26 | ||||
-rw-r--r-- | expressions.c | 133 | ||||
-rw-r--r-- | symbols.h | 7 | ||||
-rw-r--r-- | symbols_elf.c | 288 | ||||
-rw-r--r-- | symbols_win32.c | 376 |
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; @@ -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 { |