diff options
-rw-r--r-- | services/symbols_elf.c | 63 | ||||
-rw-r--r-- | services/symbols_win32.c | 17 |
2 files changed, 47 insertions, 33 deletions
diff --git a/services/symbols_elf.c b/services/symbols_elf.c index 4d091639..98f1c5dc 100644 --- a/services/symbols_elf.c +++ b/services/symbols_elf.c @@ -1143,41 +1143,48 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { if (!set_trap(&trap)) return -1; if (dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); - if (!ok && sym->sym_class == SYM_CLASS_REFERENCE && obj->mType != NULL) { - obj = obj->mType; - if (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 (!ok && sym->sym_class == SYM_CLASS_FUNCTION) { + U8_T l, h; + ok = get_num_prop(obj, AT_low_pc, &l) && get_num_prop(obj, AT_high_pc, &h); + if (ok) sz = h - l; } - if (!ok && obj->mTag == TAG_array_type) { - U8_T length = 1; - int i = dimension; - ObjectInfo * idx = obj->mChildren; - while (i > 0 && idx != NULL) { - idx = idx->mSibling; - i--; - } - if (idx == NULL) exception(ERR_INV_CONTEXT); - while (idx != NULL) { - length *= get_object_length(idx); - idx = idx->mSibling; + else { + if (!ok && sym->sym_class == SYM_CLASS_REFERENCE && obj->mType != NULL) { + obj = obj->mType; + if (dimension == 0) ok = get_num_prop(obj, AT_byte_size, &sz); } - if (obj->mType == NULL) exception(ERR_INV_CONTEXT); - obj = obj->mType; - 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 (!ok && obj->mTag == TAG_array_type) { + U8_T length = 1; + int i = dimension; + ObjectInfo * idx = obj->mChildren; + while (i > 0 && idx != NULL) { + idx = idx->mSibling; + i--; + } + if (idx == NULL) exception(ERR_INV_CONTEXT); + while (idx != NULL) { + length *= get_object_length(idx); + idx = idx->mSibling; + } + if (obj->mType == NULL) exception(ERR_INV_CONTEXT); + obj = obj->mType; 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; + ok = get_num_prop(obj, AT_byte_size, &sz); + } + if (ok) sz *= length; + } + if (!ok && obj->mTag == TAG_pointer_type) { + sz = obj->mCompUnit->mDesc.mAddressSize; + ok = sz > 0; } - if (ok) sz *= length; - } - if (!ok && obj->mTag == TAG_pointer_type) { - sz = obj->mCompUnit->mDesc.mAddressSize; - ok = sz > 0; } if (!ok) str_exception(ERR_INV_DWARF, "Object has no size attribute"); *size = (ContextAddress)sz; diff --git a/services/symbols_win32.c b/services/symbols_win32.c index ea67c8f8..195ce145 100644 --- a/services/symbols_win32.c +++ b/services/symbols_win32.c @@ -90,9 +90,9 @@ struct Symbol { unsigned frame; int sym_class; ULONG64 module; - ULONG index; - const TypeInfo * info; - const Symbol * base; + ULONG index; /* The symbol index in debug info section */ + const TypeInfo * info; /* If not NULL, the symbol is basic type */ + const Symbol * base; /* If not NULL, the symbol is array or pointer with this base type */ size_t length; ContextAddress address; }; @@ -489,8 +489,15 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) { *size = sym->info->size; return 0; } - if (get_type_tag(&type, &tag)) return -1; - if (get_type_info(&type, TI_GET_LENGTH, &res) < 0) return -1; + if (sym->sym_class == SYM_CLASS_REFERENCE || sym->sym_class == SYM_CLASS_FUNCTION) { + SYMBOL_INFO * info = NULL; + if (get_sym_info(sym, sym->index, &info) < 0) return -1; + res = info->Size; + } + else { + if (get_type_tag(&type, &tag)) return -1; + if (get_type_info(&type, TI_GET_LENGTH, &res) < 0) return -1; + } *size = (ContextAddress)res; return 0; |