diff options
author | eutarass | 2011-08-31 15:14:19 +0000 |
---|---|---|
committer | eutarass | 2011-08-31 15:14:19 +0000 |
commit | 627f0a63c8eed59d5f259b48c7747d98fd6daed2 (patch) | |
tree | 2eed10f55460ec4cb88fc03e0b51334c6d693bd9 | |
parent | 9d5f29e38f2968fc9b2d30cebdc1ed25f67fa16f (diff) | |
download | org.eclipse.tcf.agent-627f0a63c8eed59d5f259b48c7747d98fd6daed2.tar.gz org.eclipse.tcf.agent-627f0a63c8eed59d5f259b48c7747d98fd6daed2.tar.xz org.eclipse.tcf.agent-627f0a63c8eed59d5f259b48c7747d98fd6daed2.zip |
TCF Agent: fixed handling of DWARF info of dynamic types (e.g. arrays with variable size).
-rw-r--r-- | services/dwarfcache.c | 1 | ||||
-rw-r--r-- | services/dwarfexpr.c | 51 | ||||
-rw-r--r-- | services/symbols_elf.c | 202 | ||||
-rw-r--r-- | services/vm.c | 11 |
4 files changed, 168 insertions, 97 deletions
diff --git a/services/dwarfcache.c b/services/dwarfcache.c index a6f02d8a..06b1cfdc 100644 --- a/services/dwarfcache.c +++ b/services/dwarfcache.c @@ -952,7 +952,6 @@ void read_and_evaluate_dwarf_object_property(Context * Ctx, int Frame, U8_T Base } } - static void free_unit_cache(CompUnit * Unit) { Unit->mFilesCnt = 0; Unit->mFilesMax = 0; diff --git a/services/dwarfexpr.c b/services/dwarfexpr.c index 0cfe2f89..6def5985 100644 --- a/services/dwarfexpr.c +++ b/services/dwarfexpr.c @@ -34,7 +34,8 @@ #include <services/vm.h> static VMState sState; -static U8_T sStartPos = 0; +static ELF_Section * sSection = NULL; +static U8_T sSectionOffs = 0; static PropertyValue * sValue = NULL; static StackFrame * get_stack_frame(PropertyValue * sValue) { @@ -79,22 +80,24 @@ static U8_T get_fbreg(void) { memset(&FP, 0, sizeof(FP)); { - PropertyValue * SValue = sValue; - U8_T SStartPos = sStartPos; - VMState SState = sState; + PropertyValue * OrgValue = sValue; + ELF_Section * OrgSection = sSection; + U8_T OrgSectionOffs = sSectionOffs; + VMState OrgState = sState; read_and_evaluate_dwarf_object_property(sState.ctx, sState.stack_frame, 0, Parent, AT_frame_base, &FP); - assert(sState.ctx == SState.ctx); - assert(sState.addr_size == SState.addr_size); - assert(sState.big_endian == SState.big_endian); - - sState.code = SState.code; - sState.code_pos = SState.code_pos; - sState.code_len = SState.code_len; - sState.object_address = SState.object_address; - sStartPos = SStartPos; - sValue = SValue; + assert(sState.ctx == OrgState.ctx); + assert(sState.addr_size == OrgState.addr_size); + assert(sState.big_endian == OrgState.big_endian); + + sState.code = OrgState.code; + sState.code_pos = OrgState.code_pos; + sState.code_len = OrgState.code_len; + sState.object_address = OrgState.object_address; + sSectionOffs = OrgSectionOffs; + sSection = OrgSection; + sValue = OrgValue; } if (FP.mRegister != NULL) { @@ -103,12 +106,12 @@ static U8_T get_fbreg(void) { else { addr = get_numeric_property_value(&FP); } - dio_EnterSection(&Unit->mDesc, Unit->mDesc.mSection, sStartPos + sState.code_pos); + dio_EnterSection(&Unit->mDesc, sSection, sSectionOffs + sState.code_pos); return addr + dio_ReadS8LEB128(); } static void client_op(uint8_t op) { - dio_SetPos(sStartPos + sState.code_pos); + dio_SetPos(sSectionOffs + sState.code_pos); switch (op) { case OP_addr: sState.stk[sState.stk_pos++] = read_address(); @@ -121,7 +124,7 @@ static void client_op(uint8_t op) { trace(LOG_ALWAYS, "Unsupported DWARF expression op 0x%02x", op); str_exception(ERR_UNSUPPORTED, "Unsupported DWARF expression op"); } - sState.code_pos = (size_t)(dio_GetPos() - sStartPos); + sState.code_pos = (size_t)(dio_GetPos() - sSectionOffs); } static void evaluate_expression(ELF_Section * Section, U1_T * Buf, size_t Size) { @@ -131,8 +134,9 @@ static void evaluate_expression(ELF_Section * Section, U1_T * Buf, size_t Size) sState.code = Buf; sState.code_len = Size; sState.code_pos = 0; - sStartPos = Buf - (U1_T *)Section->data; - dio_EnterSection(&Unit->mDesc, Section, sStartPos); + sSection = Section; + sSectionOffs = Buf - (U1_T *)Section->data; + dio_EnterSection(&Unit->mDesc, sSection, sSectionOffs); if (evaluate_vm_expression(&sState) < 0) error = errno; dio_ExitSection(); if (error) exception(error); @@ -192,6 +196,7 @@ static void evaluate_location(void) { } void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * v) { + unsigned stk_pos = 0; CompUnit * Unit = v->mObject->mCompUnit; sValue = v; @@ -204,6 +209,7 @@ void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * v) { sState.client_op = client_op;; if (sValue->mAttr != AT_frame_base) sState.stk_pos = 0; + stk_pos = sState.stk_pos; if (sValue->mAttr == AT_data_member_location) { if (sState.stk_pos >= sState.stk_max) { @@ -222,9 +228,6 @@ void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * v) { else { evaluate_expression(Unit->mDesc.mSection, sValue->mAddr, sValue->mSize); } - if (sValue->mAttr != AT_frame_base && sState.stk_pos != (sValue->mRegister == NULL ? 1u : 0u)) { - str_exception(ERR_INV_DWARF, "invalid DWARF expression stack"); - } if (sValue->mRegister == NULL) { assert(sState.stk_pos > 0); @@ -233,7 +236,9 @@ void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * v) { } sValue->mAddr = NULL; - if (sValue->mAttr != AT_frame_base) sState.stk_pos = 0; + if (sState.stk_pos != stk_pos) { + str_exception(ERR_INV_DWARF, "Invalid DWARF expression stack"); + } } #endif /* ENABLE_ELF && ENABLE_DebugContext */ diff --git a/services/symbols_elf.c b/services/symbols_elf.c index b9e1c6b1..9fccf9ce 100644 --- a/services/symbols_elf.c +++ b/services/symbols_elf.c @@ -50,13 +50,17 @@ struct Symbol { ObjectInfo * obj; ObjectInfo * var; /* 'this' object if the symbol represents implicit 'this' reference */ ELF_Section * tbl; + int has_size; + int has_address; + ContextAddress size; ContextAddress address; int sym_class; Context * ctx; int frame; unsigned index; unsigned dimension; - ContextAddress size; + unsigned cardinal; + ContextAddress length; Symbol * base; }; @@ -130,11 +134,43 @@ static int syminfo2address(Context * ctx, ELF_SymbolInfo * info, ContextAddress return -1; } +static int is_frame_based_object(Symbol * sym) { + int res = 0; + ContextAddress addr = 0; + ContextAddress size = 0; + Context * org_ctx = sym_ctx; + int org_frame = sym_frame; + ContextAddress org_ip = sym_ip; + + if (sym->sym_class == SYM_CLASS_REFERENCE) { + if (get_symbol_address(sym, &addr) < 0) { + res = 1; + } + else { + sym->has_address = 1; + sym->address = addr; + } + } + + if (!res) { + if (get_symbol_size(sym, &size) < 0) { + res = 1; + } + else { + sym->has_size = 1; + sym->size = size; + } + } + + sym_ctx = org_ctx; + sym_frame = org_frame; + sym_ip = org_ip; + return res; +} + static void object2symbol(ObjectInfo * obj, Symbol ** res) { - Context * ctx = sym_ctx; Symbol * sym = alloc_symbol(); sym->obj = obj; - sym->frame = STACK_NO_FRAME; switch (obj->mTag) { case TAG_global_subroutine: case TAG_subroutine: @@ -174,21 +210,22 @@ static void object2symbol(ObjectInfo * obj, Symbol ** res) { case TAG_global_variable: case TAG_inheritance: case TAG_member: - sym->sym_class = SYM_CLASS_REFERENCE; - break; case TAG_formal_parameter: case TAG_local_variable: case TAG_variable: sym->sym_class = SYM_CLASS_REFERENCE; - sym->frame = sym_frame; break; case TAG_constant: case TAG_enumerator: sym->sym_class = SYM_CLASS_VALUE; break; } - if (sym->frame == STACK_NO_FRAME) ctx = context_get_group(ctx, CONTEXT_GROUP_PROCESS); - sym->ctx = ctx; + sym->frame = STACK_NO_FRAME; + sym->ctx = context_get_group(sym_ctx, CONTEXT_GROUP_PROCESS); + if (sym_frame != STACK_NO_FRAME && is_frame_based_object(sym)) { + sym->frame = sym_frame; + sym->ctx = sym_ctx; + } *res = sym; } @@ -311,7 +348,7 @@ static int find_in_object_tree(ObjectInfo * list, ContextAddress rt_offs, Contex if (strcmp(obj->mName, name) == 0) { object2symbol(obj, &sym_cur); } - if (sym_frame >= 0 && strcmp(obj->mName, "this") == 0 && get_num_prop(obj, AT_artificial, &v) && v != 0) { + if (sym_frame != STACK_NO_FRAME && strcmp(obj->mName, "this") == 0 && get_num_prop(obj, AT_artificial, &v) && v != 0) { ObjectInfo * type = get_original_type(obj); if ((type->mTag == TAG_pointer_type || type->mTag == TAG_mod_pointer) && type->mType != NULL) { type = get_original_type(type->mType); @@ -494,6 +531,7 @@ int find_symbol_by_name(Context * ctx, int frame, ContextAddress ip, char * name sym->ctx = context_get_group(ctx, CONTEXT_GROUP_PROCESS); sym->frame = STACK_NO_FRAME; sym->address = (ContextAddress)ptr; + sym->has_address = 1; if (SYM_IS_TEXT(type)) { sym->sym_class = SYM_CLASS_FUNCTION; @@ -594,6 +632,7 @@ int find_symbol_by_name(Context * ctx, int frame, ContextAddress ip, char * name sym->ctx = context_get_group(ctx, CONTEXT_GROUP_PROCESS); sym->frame = STACK_NO_FRAME; sym->address = (ContextAddress)address; + sym->has_address = 1; sym->sym_class = sym_class; *res = sym; } @@ -790,9 +829,15 @@ static void enumerate_local_vars(ObjectInfo * obj, int level, ContextAddress rt_ case TAG_local_variable: case TAG_variable: if (level > 0 && obj->mName != NULL) { + Context * org_ctx = sym_ctx; + int org_frame = sym_frame; + ContextAddress org_ip = sym_ip; Symbol * sym = NULL; object2symbol(obj, &sym); call_back(args, sym); + sym_ctx = org_ctx; + sym_frame = org_frame; + sym_ip = org_ip; } break; } @@ -825,7 +870,7 @@ const char * symbol2id(const Symbol * sym) { assert(sym->frame == STACK_NO_FRAME); assert(sym->sym_class == SYM_CLASS_TYPE); strcpy(base, symbol2id(sym->base)); - snprintf(id, sizeof(id), "@P%"PRIX64".%s", (uint64_t)sym->size, base); + snprintf(id, sizeof(id), "@P%"PRIX64".%s", (uint64_t)sym->length, base); } else { ELF_File * file = NULL; @@ -840,14 +885,14 @@ const char * symbol2id(const Symbol * sym) { if (sym->tbl != NULL) tbl_index = sym->tbl->index; if (frame == STACK_TOP_FRAME) frame = get_top_frame(sym->ctx); assert(sym->var == NULL || sym->var->mCompUnit->mFile == file); - snprintf(id, sizeof(id), "@S%X.%lX.%lX.%"PRIX64".%"PRIX64".%"PRIX64".%X.%d.%X.%X.%"PRIX64".%s", + snprintf(id, sizeof(id), "@S%X.%lX.%lX.%"PRIX64".%"PRIX64".%"PRIX64".%X.%d.%X.%X.%X.%s", sym->sym_class, file ? (unsigned long)file->dev : 0ul, file ? (unsigned long)file->ino : 0ul, file ? file->mtime : (int64_t)0, obj_index, var_index, tbl_index, frame, sym->index, - sym->dimension, (uint64_t)sym->size, + sym->dimension, sym->cardinal, sym->ctx->id); } return id; @@ -898,7 +943,7 @@ int id2symbol(const char * id, Symbol ** res) { *res = sym; if (id != NULL && id[0] == '@' && id[1] == 'P') { p = id + 2; - sym->size = (ContextAddress)read_hex(&p); + sym->length = (ContextAddress)read_hex(&p); if (*p == '.') p++; if (id2symbol(p, &sym->base)) return -1; sym->ctx = sym->base->ctx; @@ -928,7 +973,7 @@ int id2symbol(const char * id, Symbol ** res) { if (*p == '.') p++; sym->dimension = (unsigned)read_hex(&p); if (*p == '.') p++; - sym->size = (ContextAddress)read_hex(&p); + sym->cardinal = (unsigned)read_hex(&p); if (*p == '.') p++; sym->ctx = id2ctx(p); if (sym->ctx == NULL) { @@ -1050,39 +1095,19 @@ void ini_symbols_lib(void) { /*************** Functions for retrieving symbol properties ***************************************/ -static ELF_File * file; -static DWARFCache * cache; -static ObjectInfo * obj; -static ELF_Section * tbl; -static unsigned sym_index; -static unsigned dimension; -static ELF_SymbolInfo * sym_info; - static int unpack(const Symbol * sym) { + ELF_File * file = NULL; assert(sym->base == NULL); - assert(sym->size == 0); assert(!is_cardinal_type_pseudo_symbol(sym)); if (get_sym_context(sym->ctx, sym->frame, 0) < 0) return -1; - file = NULL; - cache = NULL; - obj = sym->obj; - tbl = sym->tbl; - sym_index = sym->index; - dimension = sym->dimension; - sym_info = NULL; - if (obj != NULL) file = obj->mCompUnit->mFile; - if (tbl != NULL) file = tbl->file; + if (sym->obj != NULL) file = sym->obj->mCompUnit->mFile; + if (sym->tbl != NULL) file = sym->tbl->file; if (file != NULL) { - cache = (DWARFCache *)file->dwarf_dt_cache; + DWARFCache * cache = (DWARFCache *)file->dwarf_dt_cache; if (cache == NULL || cache->magic != DWARF_CACHE_MAGIC) { errno = ERR_INV_CONTEXT; return -1; } - if (tbl != NULL) { - static ELF_SymbolInfo info; - unpack_elf_symbol_info(tbl, sym_index, &info); - sym_info = &info; - } } return 0; } @@ -1119,12 +1144,12 @@ static U8_T get_object_length(ObjectInfo * obj) { return 0; } -static void alloc_cardinal_type_pseudo_symbol(Context * ctx, ContextAddress size, Symbol ** type) { +static void alloc_cardinal_type_pseudo_symbol(Context * ctx, unsigned size, Symbol ** type) { *type = alloc_symbol(); (*type)->ctx = context_get_group(ctx, CONTEXT_GROUP_PROCESS); (*type)->frame = STACK_NO_FRAME; (*type)->sym_class = SYM_CLASS_TYPE; - (*type)->size = size; + (*type)->cardinal = size; } static int map_to_sym_table(ObjectInfo * obj, Symbol ** sym) { @@ -1150,6 +1175,7 @@ int get_symbol_class(const Symbol * sym, int * sym_class) { } int get_symbol_type(const Symbol * sym, Symbol ** type) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base || is_cardinal_type_pseudo_symbol(sym)) { *type = (Symbol *)sym; @@ -1180,10 +1206,11 @@ int get_symbol_type(const Symbol * sym, Symbol ** type) { int get_symbol_type_class(const Symbol * sym, int * type_class) { U8_T x; + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { if (sym->base->sym_class == SYM_CLASS_FUNCTION) *type_class = TYPE_CLASS_FUNCTION; - else if (sym->size > 0) *type_class = TYPE_CLASS_ARRAY; + else if (sym->length > 0) *type_class = TYPE_CLASS_ARRAY; else *type_class = TYPE_CLASS_POINTER; return 0; } @@ -1308,9 +1335,13 @@ int get_symbol_type_class(const Symbol * sym, int * type_class) { break; } } - if (sym_info != NULL && sym_info->type == STT_FUNC) { - *type_class = TYPE_CLASS_FUNCTION; - return 0; + if (sym->tbl != NULL) { + ELF_SymbolInfo info; + unpack_elf_symbol_info(sym->tbl, sym->index, &info); + if (info.type == STT_FUNC) { + *type_class = TYPE_CLASS_FUNCTION; + return 0; + } } *type_class = TYPE_CLASS_UNKNOWN; return 0; @@ -1343,11 +1374,12 @@ int get_symbol_name(const Symbol * sym, char ** name) { } int get_symbol_size(const Symbol * sym, ContextAddress * size) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { - if (sym->size > 0) { + if (sym->length > 0) { if (get_symbol_size(sym->base, size)) return -1; - *size *= sym->size; + *size *= sym->length; } else { Symbol * base = sym->base; @@ -1358,6 +1390,10 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { return 0; } if (is_cardinal_type_pseudo_symbol(sym)) { + *size = sym->cardinal; + return 0; + } + if (sym->has_size != 0) { *size = sym->size; return 0; } @@ -1369,7 +1405,7 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { U8_T sz = 0; if (!set_trap(&trap)) return -1; - if (dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); + if (sym->dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); if (!ok && sym->sym_class == SYM_CLASS_FUNCTION) { if (obj->u.mAddr.mHighPC > obj->u.mAddr.mLowPC) { ok = 1; @@ -1377,19 +1413,18 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { } } else if (!ok) { - Symbol * s = NULL; ObjectInfo * ref = NULL; if (sym->sym_class == SYM_CLASS_REFERENCE) { ref = obj; if (obj->mType != NULL) { obj = obj->mType; - if (dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); + if (sym->dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); } } while (!ok && obj->mType != NULL) { if (!is_modified_type(obj) && obj->mTag != TAG_enumeration_type) break; obj = obj->mType; - if (dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); + if (sym->dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); } if (!ok && obj->mTag == TAG_array_type) { unsigned i = 0; @@ -1397,7 +1432,7 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { ObjectInfo * elem_type = obj->mType; ObjectInfo * idx = obj->mChildren; while (idx != NULL) { - if (i++ >= dimension) length *= get_object_length(idx); + if (i++ >= sym->dimension) length *= get_object_length(idx); idx = idx->mSibling; } ok = get_num_prop(obj, AT_stride_size, &sz); @@ -1427,20 +1462,29 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { clear_trap(&trap); } } - if (!ok && ref && map_to_sym_table(ref, &s) && get_symbol_size(s, size) == 0) ok = 1; + if (!ok && ref != NULL) { + Symbol * elf_sym = NULL; + ContextAddress elf_sym_size = 0; + if (map_to_sym_table(ref, &elf_sym) && get_symbol_size(elf_sym, &elf_sym_size) == 0) { + sz = elf_sym_size; + ok = 1; + } + } } if (!ok) str_exception(ERR_INV_DWARF, "Object has no size attribute"); *size = (ContextAddress)sz; clear_trap(&trap); } - else if (sym_info != NULL) { - switch (sym_info->type) { + else if (sym->tbl != NULL) { + ELF_SymbolInfo info; + unpack_elf_symbol_info(sym->tbl, sym->index, &info); + switch (info.type) { case STT_OBJECT: case STT_FUNC: - *size = (ContextAddress)sym_info->size; + *size = (ContextAddress)info.size; break; default: - *size = sym_info->sym_section->file->elf64 ? 8 : 4; + *size = info.sym_section->file->elf64 ? 8 : 4; break; } } @@ -1452,6 +1496,7 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { } int get_symbol_base_type(const Symbol * sym, Symbol ** base_type) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { if (sym->base->sym_class == SYM_CLASS_FUNCTION) { @@ -1476,7 +1521,7 @@ int get_symbol_base_type(const Symbol * sym, Symbol ** base_type) { obj = get_original_type(obj); if (obj != NULL) { if (obj->mTag == TAG_array_type) { - int i = dimension; + int i = sym->dimension; ObjectInfo * idx = obj->mChildren; while (i > 0 && idx != NULL) { idx = idx->mSibling; @@ -1505,6 +1550,7 @@ int get_symbol_base_type(const Symbol * sym, Symbol ** base_type) { } int get_symbol_index_type(const Symbol * sym, Symbol ** index_type) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { if (sym->base->sym_class == SYM_CLASS_FUNCTION) { @@ -1521,7 +1567,7 @@ int get_symbol_index_type(const Symbol * sym, Symbol ** index_type) { if (unpack(sym) < 0) return -1; obj = get_original_type(obj); if (obj != NULL && obj->mTag == TAG_array_type) { - int i = dimension; + int i = sym->dimension; ObjectInfo * idx = obj->mChildren; while (i > 0 && idx != NULL) { idx = idx->mSibling; @@ -1537,13 +1583,14 @@ int get_symbol_index_type(const Symbol * sym, Symbol ** index_type) { } int get_symbol_length(const Symbol * sym, ContextAddress * length) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { if (sym->base->sym_class == SYM_CLASS_FUNCTION) { errno = ERR_INV_CONTEXT; return -1; } - *length = sym->size == 0 ? 1 : sym->size; + *length = sym->length == 0 ? 1 : sym->length; return 0; } if (is_cardinal_type_pseudo_symbol(sym)) { @@ -1553,7 +1600,7 @@ int get_symbol_length(const Symbol * sym, ContextAddress * length) { if (unpack(sym) < 0) return -1; obj = get_original_type(obj); if (obj != NULL && obj->mTag == TAG_array_type) { - int i = dimension; + int i = sym->dimension; ObjectInfo * idx = obj->mChildren; while (i > 0 && idx != NULL) { idx = idx->mSibling; @@ -1572,6 +1619,7 @@ int get_symbol_length(const Symbol * sym, ContextAddress * length) { } int get_symbol_lower_bound(const Symbol * sym, int64_t * value) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { if (sym->base->sym_class == SYM_CLASS_FUNCTION) { @@ -1588,7 +1636,7 @@ int get_symbol_lower_bound(const Symbol * sym, int64_t * value) { if (unpack(sym) < 0) return -1; obj = get_original_type(obj); if (obj != NULL && obj->mTag == TAG_array_type) { - int i = dimension; + int i = sym->dimension; ObjectInfo * idx = obj->mChildren; while (i > 0 && idx != NULL) { idx = idx->mSibling; @@ -1609,6 +1657,7 @@ int get_symbol_children(const Symbol * sym, Symbol *** children, int * count) { int n = 0; static Symbol ** buf = NULL; static int buf_len = 0; + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base) { if (sym->base->sym_class == SYM_CLASS_FUNCTION && sym->base->obj == NULL) { @@ -1680,6 +1729,7 @@ int get_symbol_children(const Symbol * sym, Symbol *** children, int * count) { } int get_symbol_offset(const Symbol * sym, ContextAddress * offset) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base || is_cardinal_type_pseudo_symbol(sym)) { errno = ERR_INV_CONTEXT; @@ -1697,6 +1747,7 @@ int get_symbol_offset(const Symbol * sym, ContextAddress * offset) { } int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big_endian) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base || is_cardinal_type_pseudo_symbol(sym) || sym->var) { errno = ERR_INV_CONTEXT; @@ -1763,22 +1814,24 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big set_errno(ERR_OTHER, "Object location or value info not available"); return -1; } - if (sym_info != NULL) { - switch (sym_info->type) { + if (sym->tbl != NULL) { + ELF_SymbolInfo info; + unpack_elf_symbol_info(sym->tbl, sym->index, &info); + switch (info.type) { case STT_OBJECT: case STT_FUNC: set_errno(ERR_OTHER, "Symbol represents an address"); return -1; } - if (sym_info->sym_section->file->elf64) { + if (info.sym_section->file->elf64) { static U8_T buf = 0; - buf = sym_info->value; + buf = info.value; *value = &buf; *size = 8; } else { static U4_T buf = 0; - buf = (U4_T)sym_info->value; + buf = (U4_T)info.value; *value = &buf; *size = 4; } @@ -1810,12 +1863,13 @@ static int calc_member_offset(ObjectInfo * type, ObjectInfo * member, ContextAdd } int get_symbol_address(const Symbol * sym, ContextAddress * address) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); if (sym->base || is_cardinal_type_pseudo_symbol(sym)) { errno = ERR_INV_CONTEXT; return -1; } - if (sym->address != 0) { + if (sym->has_address) { *address = sym->address; return 0; } @@ -1864,8 +1918,10 @@ int get_symbol_address(const Symbol * sym, ContextAddress * address) { set_errno(ERR_OTHER, "No object location info found in DWARF data"); return -1; } - if (sym_info != NULL) { - return syminfo2address(sym_ctx, sym_info, address); + if (sym->tbl != NULL) { + ELF_SymbolInfo info; + unpack_elf_symbol_info(sym->tbl, sym->index, &info); + return syminfo2address(sym_ctx, &info, address); } errno = ERR_INV_CONTEXT; @@ -1873,8 +1929,9 @@ int get_symbol_address(const Symbol * sym, ContextAddress * address) { } int get_symbol_register(const Symbol * sym, Context ** ctx, int * frame, RegisterDefinition ** reg) { + ObjectInfo * obj = sym->obj; assert(sym->magic == SYMBOL_MAGIC); - if (sym->base || is_cardinal_type_pseudo_symbol(sym) || sym->address != 0) { + if (sym->base || is_cardinal_type_pseudo_symbol(sym) || sym->has_address) { errno = ERR_INV_CONTEXT; return -1; } @@ -1899,9 +1956,10 @@ int get_symbol_register(const Symbol * sym, Context ** ctx, int * frame, Registe int get_symbol_flags(const Symbol * sym, SYM_FLAGS * flags) { U8_T v = 0; ObjectInfo * i = NULL; + ObjectInfo * obj = sym->obj; *flags = 0; assert(sym->magic == SYMBOL_MAGIC); - if (sym->base || is_cardinal_type_pseudo_symbol(sym) || sym->address) return 0; + if (sym->base || is_cardinal_type_pseudo_symbol(sym)) return 0; if (unpack(sym) < 0) return -1; i = obj; while (i != NULL) { @@ -1989,7 +2047,7 @@ int get_array_symbol(const Symbol * sym, ContextAddress length, Symbol ** ptr) { (*ptr)->frame = STACK_NO_FRAME; (*ptr)->sym_class = SYM_CLASS_TYPE; (*ptr)->base = (Symbol *)sym; - (*ptr)->size = length; + (*ptr)->length = length; return 0; } diff --git a/services/vm.c b/services/vm.c index b417033d..026f81b3 100644 --- a/services/vm.c +++ b/services/vm.c @@ -25,7 +25,7 @@ #include <services/dwarf.h> #include <services/vm.h> -#define check_e_stack(n) { if (state->stk_pos < n) inv_dwarf("invalid DWARF expression stack"); } +#define check_e_stack(n) { if (state->stk_pos < n) inv_dwarf("Invalid DWARF expression stack"); } static VMState * state = NULL; static uint8_t * code = NULL; @@ -547,10 +547,19 @@ static void evaluate_expression(void) { case OP_piece: state->piece_bits = read_u4leb128() * 8; state->piece_offs = 0; + if (code_pos < code_len && state->piece_bits == 0) { + if (state->reg) state->reg = NULL; + else state->stk_pos--; + } break; case OP_bit_piece: state->piece_bits = read_u4leb128(); state->piece_offs = read_u4leb128(); + if (code_pos < code_len && state->piece_bits == 0) { + if (state->reg) state->reg = NULL; + else state->stk_pos--; + state->piece_offs = 0; + } break; case OP_call2: case OP_call4: |