summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r--dwflpp.cxx64
1 files changed, 58 insertions, 6 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index ee13d0b2..f3015fcc 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -267,9 +267,29 @@ dwflpp::function_name_matches(const string& pattern)
bool
-dwflpp::function_name_final_match(const string& pattern)
+dwflpp::function_scope_matches(const vector<string> scopes)
{
- return module_name_final_match (pattern);
+ // walk up the containing scopes
+ Dwarf_Die* die = function;
+ for (int i = scopes.size() - 1; i >= 0; --i)
+ {
+ die = get_parent_scope(die);
+
+ // check if this scope matches, and prepend it if so
+ // NB: a NULL die is the global scope, compared as ""
+ string name = dwarf_diename(die) ?: "";
+ if (name_has_wildcard(scopes[i]) ?
+ function_name_matches_pattern(name, scopes[i]) :
+ name == scopes[i])
+ function_name = name + "::" + function_name;
+ else
+ return false;
+
+ // make sure there's no more if we're at the global scope
+ if (!die && i > 0)
+ return false;
+ }
+ return true;
}
@@ -598,6 +618,9 @@ dwflpp::cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die)
case DW_TAG_entry_point:
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
+ case DW_TAG_namespace:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
parents->insert(make_pair(child.addr, *die));
cache_die_parents(parents, &child);
break;
@@ -750,6 +773,34 @@ dwflpp::getscopes(Dwarf_Addr pc)
}
+Dwarf_Die*
+dwflpp::get_parent_scope(Dwarf_Die* die)
+{
+ Dwarf_Die specification;
+ if (dwarf_attr_die(die, DW_AT_specification, &specification))
+ die = &specification;
+
+ cu_die_parent_cache_t *parents = get_die_parents();
+ cu_die_parent_cache_t::iterator it = parents->find(die->addr);
+ while (it != parents->end())
+ {
+ Dwarf_Die* scope = &it->second;
+ switch (dwarf_tag (scope))
+ {
+ case DW_TAG_namespace:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ return scope;
+
+ default:
+ break;
+ }
+ it = parents->find(scope->addr);
+ }
+ return NULL;
+}
+
+
int
dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg)
{
@@ -1681,11 +1732,12 @@ dwflpp::translate_location(struct obstack *pool,
#if !_ELFUTILS_PREREQ (0,142)
if (dwarf_whatattr (attr) == DW_AT_data_member_location)
{
- Dwarf_Op offset_loc = { .atom = DW_OP_plus_uconst };
+ Dwarf_Op offset_loc;
+ offset_loc.atom = DW_OP_plus_uconst;
if (dwarf_formudata (attr, &offset_loc.number) == 0)
return c_translate_location (pool, &loc2c_error, this,
&loc2c_emit_address, 1, 0, pc,
- &offset_loc, 1, NULL, NULL);
+ &offset_loc, 1, NULL, NULL, NULL);
}
#endif
@@ -1722,7 +1774,7 @@ dwflpp::translate_location(struct obstack *pool,
return c_translate_location (pool, &loc2c_error, this,
&loc2c_emit_address,
1, 0 /* PR9768 */,
- pc, expr, len, tail, fb_attr, cfa_ops);
+ pc, attr, expr, len, tail, fb_attr, cfa_ops);
}
@@ -2345,7 +2397,7 @@ dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die,
struct location *head = c_translate_location (&pool, &loc2c_error, this,
&loc2c_emit_address,
1, 0 /* PR9768 */,
- pc, locops, nlocops,
+ pc, NULL, locops, nlocops,
&tail, NULL, NULL);
/* Translate the ->bar->baz[NN] parts. */