Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2012-09-27 05:55:04 +0000
committerEugene Tarassov2012-09-27 05:55:04 +0000
commit38fa28ad6eef80effde72fcac433a546ab80097d (patch)
treebc4e606fbc397b1b8d27ddff81cdae36f143487d
parenta45c62f3ae93762008d6e17d2985935643876b9e (diff)
downloadorg.eclipse.tcf.agent-38fa28ad6eef80effde72fcac433a546ab80097d.tar.gz
org.eclipse.tcf.agent-38fa28ad6eef80effde72fcac433a546ab80097d.tar.xz
org.eclipse.tcf.agent-38fa28ad6eef80effde72fcac433a546ab80097d.zip
Bug 390309 - Unable to set function breakpoint on a fully qualified C++ name
-rw-r--r--agent/tcf/services/dwarfcache.c8
-rw-r--r--agent/tcf/services/dwarfcache.h1
-rw-r--r--agent/tcf/services/expressions.c14
-rw-r--r--agent/tcf/services/symbols_elf.c207
4 files changed, 161 insertions, 69 deletions
diff --git a/agent/tcf/services/dwarfcache.c b/agent/tcf/services/dwarfcache.c
index 8cfd6aba..7a2d29f0 100644
--- a/agent/tcf/services/dwarfcache.c
+++ b/agent/tcf/services/dwarfcache.c
@@ -614,6 +614,7 @@ static void read_object_info(U2_T Tag, U2_T Attr, U2_T Form) {
case AT_low_pc:
dio_ChkAddr(Form);
Info->u.mCode.mLowPC = (ContextAddress)dio_gFormData;
+ Info->mFlags |= DOIF_low_pc;
break;
case AT_high_pc:
dio_ChkAddr(Form);
@@ -745,10 +746,15 @@ static void read_object_refs(void) {
assert(ref.org->mTag != 0);
if (ref.org->mFlags & DOIF_load_mark) str_fmt_exception(ERR_INV_DWARF,
"Invalid forward reference at %x", (unsigned)ref.obj->mID);
- if (ref.obj->mFlags & DOIF_specification) ref.org->mDefinition = ref.obj;
if (ref.obj->mName == NULL) ref.obj->mName = ref.org->mName;
if (ref.obj->mType == NULL) ref.obj->mType = ref.org->mType;
ref.obj->mFlags |= ref.org->mFlags & ~(DOIF_children_loaded | DOIF_declaration | DOIF_specification);
+ if (ref.obj->mFlags & DOIF_specification) {
+ ref.org->mDefinition = ref.obj;
+ if ((ref.obj->mFlags & (DOIF_low_pc | DOIF_ranges)) == 0) {
+ ref.obj->mFlags |= ref.org->mFlags & DOIF_declaration;
+ }
+ }
if (ref.obj->mFlags & DOIF_external) {
ObjectInfo * cls = ref.org;
while (cls->mParent != NULL &&
diff --git a/agent/tcf/services/dwarfcache.h b/agent/tcf/services/dwarfcache.h
index 33739015..1f913b60 100644
--- a/agent/tcf/services/dwarfcache.h
+++ b/agent/tcf/services/dwarfcache.h
@@ -80,6 +80,7 @@ struct FileInfo {
#define DOIF_find_mark 0x1000
#define DOIF_load_mark 0x2000
#define DOIF_pub_mark 0x4000
+#define DOIF_low_pc 0x8000
struct ObjectInfo {
diff --git a/agent/tcf/services/expressions.c b/agent/tcf/services/expressions.c
index 1ff0b921..dbfa3d6b 100644
--- a/agent/tcf/services/expressions.c
+++ b/agent/tcf/services/expressions.c
@@ -874,7 +874,9 @@ static int identifier(int mode, Value * scope, char * name, SYM_FLAGS flags, Val
Symbol * nxt = NULL;
while (find_next_symbol(&nxt) == 0) {
SYM_FLAGS nxt_flags = (get_all_symbol_flags(nxt) ^ flags) & flag_mask;
- if (flag_count(nxt_flags) < flag_count(sym_flags)) sym = nxt;
+ if (flag_count(nxt_flags) >= flag_count(sym_flags)) continue;
+ sym_flags = nxt_flags;
+ sym = nxt;
}
}
return sym2value(mode, sym, v);
@@ -901,10 +903,16 @@ static int qualified_name(int mode, Value * scope, SYM_FLAGS flags, Value * v) {
memset(v, 0, sizeof(Value));
if (text_sy == SY_NAME) {
if (mode != MODE_SKIP) {
- sym_class = identifier(mode, scope, (char *)text_val.value, flags, v);
+ char * name = tmp_strdup((char *)text_val.value);
+ SYM_FLAGS f = flags;
+ next_sy();
+ if (text_sy == SY_SCOPE) f |= SYM_FLAG_TYPE;
+ sym_class = identifier(mode, scope, name, f, v);
if (sym_class < 0) error(ERR_INV_EXPRESSION, "Undefined identifier '%s'", text_val.value);
}
- next_sy();
+ else {
+ next_sy();
+ }
}
else if (text_sy == SY_ID) {
if (mode != MODE_SKIP) {
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index 323a0515..cd25a97d 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -493,6 +493,68 @@ static int check_in_range(ObjectInfo * obj, ContextAddress rt_offs, ContextAddre
return 0;
}
+static int cmp_object_profiles(ObjectInfo * x, ObjectInfo * y) {
+ if (x == y) return 1;
+ while (x != NULL) {
+ switch (x->mTag) {
+ case TAG_typedef:
+ case TAG_const_type:
+ case TAG_volatile_type:
+ x = x->mType;
+ continue;
+ }
+ break;
+ }
+ while (y != NULL) {
+ switch (y->mTag) {
+ case TAG_typedef:
+ case TAG_const_type:
+ case TAG_volatile_type:
+ y = y->mType;
+ continue;
+ }
+ break;
+ }
+ if (x == NULL || y == NULL) return 0;
+ if (x->mTag != y->mTag) return 0;
+ switch (x->mTag) {
+ case TAG_subprogram:
+ {
+ ObjectInfo * px = get_dwarf_children(x);
+ ObjectInfo * py = get_dwarf_children(y);
+ while (px != NULL && py != NULL) {
+ if (px->mTag != TAG_formal_parameter) {
+ px = px->mSibling;
+ continue;
+ }
+ if (py->mTag != TAG_formal_parameter) {
+ py = py->mSibling;
+ continue;
+ }
+ if (!cmp_object_profiles(px->mType, py->mType)) return 0;
+ px = px->mSibling;
+ py = py->mSibling;
+ }
+ if (px != NULL || py != NULL) return 0;
+ }
+ break;
+ case TAG_packed_type:
+ case TAG_const_type:
+ case TAG_volatile_type:
+ case TAG_restrict_type:
+ case TAG_shared_type:
+ case TAG_pointer_type:
+ case TAG_mod_pointer:
+ case TAG_string_type:
+ case TAG_array_type:
+ if (!cmp_object_profiles(x->mType, y->mType)) return 0;
+ break;
+ }
+ if (x->mName == y->mName) return 1;
+ if (x->mName == NULL || y->mName == NULL) return 0;
+ return strcmp(x->mName, y->mName) == 0;
+}
+
static void add_to_find_symbol_buf(ObjectInfo * obj, Symbol * sym) {
Symbol * p = NULL;
Symbol * s = find_symbol_list;
@@ -516,89 +578,104 @@ static void add_to_find_symbol_buf(ObjectInfo * obj, Symbol * sym) {
else find_symbol_list = sym;
}
+static int pub_name_priority(ObjectInfo * obj) {
+ int p = 0;
+ if (obj->mFlags & DOIF_external) p += 2;
+ if (obj->mFlags & DOIF_declaration) p -= 4;
+ switch (obj->mTag) {
+ case TAG_class_type:
+ case TAG_structure_type:
+ case TAG_union_type:
+ case TAG_enumeration_type:
+ p -= 1;
+ break;
+ }
+ return p;
+}
+
+static int pub_name_comparator(const void * x, const void * y) {
+ int px = pub_name_priority(*(ObjectInfo **)x);
+ int py = pub_name_priority(*(ObjectInfo **)y);
+ if (px > py) return -1;
+ if (px < py) return +1;
+ return 0;
+}
+
static void find_by_name_in_pub_names(DWARFCache * cache, const char * name) {
PubNamesTable * tbl = &cache->mPubNames;
if (tbl->mHash != NULL) {
- ObjectInfo * decl = NULL;
- ObjectInfo * type = NULL;
- ObjectInfo * other = NULL;
+ static ObjectInfo ** buf = NULL;
+ static unsigned buf_pos = 0;
+ static unsigned buf_max = 0;
unsigned n = tbl->mHash[calc_symbol_name_hash(name) % tbl->mHashSize];
+ buf_pos = 0;
while (n != 0) {
ObjectInfo * obj = tbl->mNext[n].mObject;
- if (obj->mFlags & DOIF_external) {
- if (cmp_symbol_names(obj->mName, name) == 0) {
- add_to_find_symbol_buf(obj, NULL);
- }
- }
- else if (obj->mFlags & DOIF_declaration) {
- if (decl == NULL && cmp_symbol_names(obj->mName, name) == 0) decl = obj;
- }
- else {
- switch (obj->mTag) {
- case TAG_class_type:
- case TAG_structure_type:
- case TAG_union_type:
- case TAG_enumeration_type:
- if (type == NULL && cmp_symbol_names(obj->mName, name) == 0) type = obj;
- break;
- default:
- if (other == NULL && cmp_symbol_names(obj->mName, name) == 0) other = obj;
- break;
+ if (cmp_symbol_names(obj->mName, name) == 0) {
+ if (buf_pos >= buf_max) {
+ buf_max += 0x100;
+ buf = (ObjectInfo **)loc_realloc(buf, sizeof(ObjectInfo *) * buf_max);
}
+ buf[buf_pos++] = obj;
}
n = tbl->mNext[n].mNext;
}
- if (other != NULL) {
- add_to_find_symbol_buf(other, NULL);
- }
- if (type != NULL) {
- add_to_find_symbol_buf(type, NULL);
- }
- if (decl != NULL) {
- add_to_find_symbol_buf(decl, NULL);
+ if (buf_pos > 0) {
+ unsigned i;
+ qsort(buf, buf_pos, sizeof(ObjectInfo *), pub_name_comparator);
+ for (i = 0; i < buf_pos; i++) add_to_find_symbol_buf(buf[i], NULL);
}
}
}
/* If 'decl' represents a declaration, replace it with definition - if possible */
static ObjectInfo * find_definition(ObjectInfo * decl) {
- int search_pub_names = 1;
- if (decl == NULL) return NULL;
- if ((decl->mFlags & DOIF_declaration) == 0) return decl;
- if (decl->mDefinition != NULL) return decl->mDefinition;
- if (decl->mName == NULL) return decl;
- switch (decl->mTag) {
- case TAG_structure_type:
- case TAG_interface_type:
- case TAG_union_type:
- case TAG_class_type:
- search_pub_names = 1;
- break;
- default:
- search_pub_names = (decl->mFlags & DOIF_external) != 0;
- break;
- }
- if (search_pub_names) {
- Trap trap;
- Symbol * def = NULL;
- Symbol * list = find_symbol_list;
- if (set_trap(&trap)) {
- DWARFCache * cache = get_dwarf_cache(get_dwarf_file(decl->mCompUnit->mFile));
- find_symbol_list = NULL;
- find_by_name_in_pub_names(cache, decl->mName);
- while (find_symbol_list != NULL) {
- Symbol * sym = find_symbol_list;
- find_symbol_list = find_symbol_list->next;
- if (sym->obj == NULL) continue;
- if (sym->obj->mTag != decl->mTag) continue;
- if (sym->obj->mFlags & DOIF_declaration) continue;
- def = sym;
- break;
+ while (decl != NULL) {
+ int search_pub_names = 0;
+ if (decl->mDefinition != NULL) {
+ decl = decl->mDefinition;
+ continue;
+ }
+ if (decl->mName == NULL) return decl;
+ if ((decl->mFlags & DOIF_declaration) == 0) return decl;
+ switch (decl->mTag) {
+ case TAG_structure_type:
+ case TAG_interface_type:
+ case TAG_union_type:
+ case TAG_class_type:
+ search_pub_names = 1;
+ break;
+ default:
+ search_pub_names = (decl->mFlags & DOIF_external) != 0;
+ break;
+ }
+ if (search_pub_names) {
+ Trap trap;
+ Symbol * def = NULL;
+ Symbol * list = find_symbol_list;
+ if (set_trap(&trap)) {
+ DWARFCache * cache = get_dwarf_cache(get_dwarf_file(decl->mCompUnit->mFile));
+ find_symbol_list = NULL;
+ find_by_name_in_pub_names(cache, decl->mName);
+ while (find_symbol_list != NULL) {
+ Symbol * sym = find_symbol_list;
+ find_symbol_list = find_symbol_list->next;
+ if (sym->obj == NULL) continue;
+ if (sym->obj->mTag != decl->mTag) continue;
+ if (sym->obj->mFlags & DOIF_declaration) continue;
+ if (!cmp_object_profiles(decl, sym->obj)) continue;
+ def = sym;
+ break;
+ }
+ clear_trap(&trap);
+ }
+ find_symbol_list = list;
+ if (def != NULL) {
+ decl = def->obj;
+ continue;
}
- clear_trap(&trap);
}
- find_symbol_list = list;
- if (def != NULL) return def->obj;
+ break;
}
return decl;
}

Back to the top