Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/tcf/services/symbols_elf.c48
-rw-r--r--tests/test-dwarf/tcf/backend/backend.c28
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) {

Back to the top