delete_map(global_alias_cache);
delete_map(cu_die_parent_cache);
+ cu_lines_cache_t::iterator i;
+ for (i = cu_lines_cache.begin(); i != cu_lines_cache.end(); ++i)
+ delete_map(*i->second);
+ delete_map(cu_lines_cache);
+
if (dwfl)
dwfl_end(dwfl);
// NB: don't "delete mod_info;", as that may be shared
}
+// Comparator function for sorting
+static bool
+compare_lines(Dwarf_Line* a, Dwarf_Line* b)
+{
+ if (a == b)
+ return false;
+
+ int lineno_a = safe_dwarf_lineno(a);
+ int lineno_b = safe_dwarf_lineno(b);
+ if (lineno_a == lineno_b)
+ return safe_dwarf_lineaddr(a) < safe_dwarf_lineaddr(b);
+ return lineno_a < lineno_b;
+}
+
+// Interface to CU lines cache sorted by lineno
+lines_t*
+dwflpp::get_cu_lines_sorted_by_lineno(const char *srcfile)
+{
+ assert(cu);
+
+ srcfile_lines_cache_t *srcfile_lines = cu_lines_cache[cu];
+ if (!srcfile_lines)
+ {
+ srcfile_lines = new srcfile_lines_cache_t();
+ cu_lines_cache[cu] = srcfile_lines;
+ }
+
+ lines_t *lines = (*srcfile_lines)[srcfile];
+ if (!lines)
+ {
+ size_t nlines_cu = 0;
+ Dwarf_Lines *lines_cu = NULL;
+ dwarf_assert("dwarf_getsrclines",
+ dwarf_getsrclines(cu, &lines_cu, &nlines_cu));
+
+ lines = new lines_t();
+ (*srcfile_lines)[srcfile] = lines;
+
+ for (size_t i = 0; i < nlines_cu; i++)
+ {
+ Dwarf_Line *line = dwarf_onesrcline(lines_cu, i);
+ const char *linesrc = safe_dwarf_linesrc(line);
+ if (strcmp(srcfile, linesrc))
+ continue;
+ lines->push_back(line);
+ }
+
+ if (lines->size() > 1)
+ sort(lines->begin(), lines->end(), compare_lines);
+
+ if (sess.verbose > 3)
+ {
+ clog << "found the following lines for %s:" << endl;
+ lines_t::iterator i;
+ for (i = lines->begin(); i != lines->end(); ++i)
+ cout << safe_dwarf_lineno(*i) << " = " << hex
+ << safe_dwarf_lineaddr(*i) << dec << endl;
+ }
+ }
+ return lines;
+}
+
template<> void
dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
int linenos[2],
// cu die -> (die -> parent die)
typedef unordered_map<void*, cu_die_parent_cache_t*> mod_cu_die_parent_cache_t;
+// Dwarf_Line[] (sorted by lineno)
+typedef std::vector<Dwarf_Line*> lines_t;
+typedef std::pair<lines_t::iterator,
+ lines_t::iterator>
+ lines_range_t;
+
+// srcfile -> Dwarf_Line[]
+typedef unordered_map<std::string, lines_t*> srcfile_lines_cache_t;
+
+// cu die -> (srcfile -> Dwarf_Line[])
+typedef unordered_map<void*, srcfile_lines_cache_t*> cu_lines_cache_t;
+
typedef std::vector<func_info> func_info_map_t;
typedef std::vector<inline_instance_info> inline_instance_map_t;
void cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die);
cu_die_parent_cache_t *get_die_parents();
+ // Cache for cu lines sorted by lineno
+ cu_lines_cache_t cu_lines_cache;
+
Dwarf_Die* get_parent_scope(Dwarf_Die* die);
/* The global alias cache is used to resolve any DIE found in a
static int mod_function_caching_callback (Dwarf_Die* func, cu_function_cache_t *v);
static int cu_function_caching_callback (Dwarf_Die* func, cu_function_cache_t *v);
+
+ lines_t* get_cu_lines_sorted_by_lineno(const char *srcfile);
+
static int external_function_cu_callback (Dwarf_Die* cu, external_function_query *efq);
static int external_function_func_callback (Dwarf_Die* func, external_function_query *efq);