diff options
-rw-r--r-- | agent/tcf/services/symbols_elf.c | 48 | ||||
-rw-r--r-- | tests/test-dwarf/tcf/backend/backend.c | 28 |
2 files changed, 49 insertions, 27 deletions
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c index 0d6872d3..880a979e 100644 --- a/agent/tcf/services/symbols_elf.c +++ b/agent/tcf/services/symbols_elf.c @@ -1197,6 +1197,29 @@ static void find_by_name_in_pub_names(DWARFCache * cache, const char * name) { } } +static int get_object_scope(ObjectInfo * obj, ObjectInfo ** container) { + ObjectInfo * parent = get_dwarf_parent(obj); + if (parent != NULL && parent->mTag == TAG_compile_unit) { + if (obj->mFlags & DOIF_abstract_origin) { + ObjectInfo * org = get_object_ref_prop(obj, AT_abstract_origin); + if (org == NULL) return -1; + obj = org; + } + if (obj->mFlags & DOIF_specification) { + ObjectInfo * spc = get_object_ref_prop(obj, AT_specification_v2); + if (spc == NULL) return -1; + obj = spc; + } + parent = get_dwarf_parent(obj); + } + if (parent == NULL && obj->mTag >= TAG_fund_type && obj->mTag < TAG_fund_type + 0x100) { + /* Virtual DWARF object that is created by the DWARF reader. */ + parent = obj->mCompUnit->mObject; + } + *container = parent; + return 0; +} + static int find_in_object_tree(ObjectInfo * parent, unsigned level, UnitAddress * ip, const char * name) { ObjectInfo * children = get_dwarf_children(parent); @@ -1236,7 +1259,10 @@ static int find_in_object_tree(ObjectInfo * parent, unsigned level, while (obj != NULL) { if (obj->mTag != TAG_GNU_call_site) { if (obj->mName != NULL && equ_symbol_names(obj->mName, name)) { - add_obj_to_find_symbol_buf(find_definition(obj), level); + /* Skip out-of-body definitions */ + ObjectInfo * container = NULL; + if (get_object_scope(obj, &container) < 0) exception(errno); + if (container == parent) add_obj_to_find_symbol_buf(find_definition(obj), level); } if (parent->mTag == TAG_subprogram && ip != 0) { if (!obj_ptr_chk) { @@ -3327,29 +3353,11 @@ int get_symbol_container(const Symbol * sym, Symbol ** container) { return -1; } } - parent = get_dwarf_parent(obj); - if (parent != NULL && parent->mTag == TAG_compile_unit) { - if (obj->mFlags & DOIF_abstract_origin) { - ObjectInfo * org = get_object_ref_prop(obj, AT_abstract_origin); - if (org == NULL) return -1; - obj = org; - } - if (obj->mFlags & DOIF_specification) { - ObjectInfo * spc = get_object_ref_prop(obj, AT_specification_v2); - if (spc == NULL) return -1; - obj = spc; - } - parent = get_dwarf_parent(obj); - } + if (get_object_scope(obj, &parent) < 0) return -1; if (parent != NULL) { object2symbol(NULL, parent, container); return 0; } - if (obj->mTag >= TAG_fund_type && obj->mTag < TAG_fund_type + 0x100) { - /* Virtual DWARF object that is created by the DWARF reader. */ - object2symbol(NULL, obj->mCompUnit->mObject, container); - return 0; - } if (obj->mTag == TAG_compile_unit) { *container = NULL; return 0; diff --git a/tests/test-dwarf/tcf/backend/backend.c b/tests/test-dwarf/tcf/backend/backend.c index 52bbbda2..9e8568da 100644 --- a/tests/test-dwarf/tcf/backend/backend.c +++ b/tests/test-dwarf/tcf/backend/backend.c @@ -827,6 +827,7 @@ static void loc_var_func(void * args, Symbol * sym) { LocationExpressionState * loc_state = NULL; UnitAddressRange * unit_range = (UnitAddressRange *)args; Symbol * sym_container = NULL; + int out_of_body = 0; if (get_symbol_class(sym, &symbol_class) < 0) { error_sym("get_symbol_class", sym); @@ -840,7 +841,9 @@ static void loc_var_func(void * args, Symbol * sym) { if (get_symbol_name(sym, &name) < 0) { error_sym("get_symbol_name", sym); } - if (name != NULL) { + /* Check for out-of-body definition */ + out_of_body = sym_container != NULL && get_symbol_object(sym)->mParent != get_symbol_object(sym_container); + if (!out_of_body && name != NULL) { int found_next = 0; int search_in_scope = 0; Symbol * find_sym = NULL; @@ -875,6 +878,7 @@ static void loc_var_func(void * args, Symbol * sym) { if (search_in_scope) { /* 'sym' is eclipsed in the current scope by a nested declaration */ Symbol * find_container = NULL; + int find_container_class = 0; if (!found_next) { find_symbol_by_name(elf_ctx, STACK_TOP_FRAME, 0, name, &find_sym); errno = ERR_OTHER; @@ -887,9 +891,14 @@ static void loc_var_func(void * args, Symbol * sym) { if (get_symbol_container(find_sym, &find_container) < 0) { error_sym("get_symbol_container", find_sym); } - if (get_symbol_object(sym_container) != get_symbol_object(find_container)) { - errno = ERR_OTHER; - error("Invalid result of find_symbol_in_scope()"); + if (get_symbol_class(find_container, &find_container_class) < 0) { + error_sym("get_symbol_class", find_container); + } + if (find_container_class != SYM_CLASS_NAMESPACE) { + if (get_symbol_object(sym_container) != get_symbol_object(find_container)) { + errno = ERR_OTHER; + error("Invalid result of find_symbol_in_scope()"); + } } for (;;) { Symbol * find_next = NULL; @@ -909,9 +918,14 @@ static void loc_var_func(void * args, Symbol * sym) { if (get_symbol_container(find_next, &find_container) < 0) { error("get_symbol_container"); } - if (get_symbol_object(sym_container) != get_symbol_object(find_container)) { - errno = ERR_OTHER; - error("Invalid result of find_next_symbol()"); + if (get_symbol_class(find_container, &find_container_class) < 0) { + error_sym("get_symbol_class", find_container); + } + if (find_container_class != SYM_CLASS_NAMESPACE) { + if (get_symbol_object(sym_container) != get_symbol_object(find_container)) { + errno = ERR_OTHER; + error("Invalid result of find_next_symbol()"); + } } } if (symcmp(sym, find_sym) != 0) { |