diff options
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r-- | dwflpp.cxx | 107 |
1 files changed, 74 insertions, 33 deletions
@@ -124,7 +124,7 @@ dwflpp::get_module_dwarf(bool required, bool report) if (required) throw semantic_error (msg); - else + else if (! sess.suppress_warnings) cerr << "WARNING: " << msg << "\n"; } } @@ -808,19 +808,43 @@ dwflpp::iterate_over_srcfile_lines (char const * srcfile, } else if (line_type == WILDCARD) function_line (&lineno); + else if (line_type == RANGE) { /* correct lineno */ + int start_lineno; + + function_line (&start_lineno); + lineno = lineno < start_lineno ? start_lineno : lineno; + if (lineno > lines[1]) { /* invalid line range */ + stringstream advice; + advice << "Invalid line range (" << lines[0] << "-" << lines[1] << ")"; + if (start_lineno > lines[1]) + advice << ", the end line number " << lines[1] << " < " << start_lineno; + throw semantic_error (advice.str()); + } + } + for (int l = lineno; ; l = l + 1) { set<int> lines_probed; pair<set<int>::iterator,bool> line_probed; - dwarf_assert ("dwarf_getsrc_file", - dwarf_getsrc_file (module_dwarf, - srcfile, l, 0, - &srcsp, &nsrcs)); + int ret = 0; + + ret = dwarf_getsrc_file (module_dwarf, srcfile, l, 0, + &srcsp, &nsrcs); + if (line_type != WILDCARD && line_type != RANGE) + dwarf_assert ("dwarf_getsrc_file", ret); + if (line_type == WILDCARD || line_type == RANGE) { Dwarf_Addr line_addr; + + if (ret != 0) /* tolerate invalid line number */ + break; + dwarf_lineno (srcsp [0], &lineno); + /* Maybe lineno will exceed the input end */ + if (line_type == RANGE && lineno > lines[1]) + break; line_probed = lines_probed.insert(lineno); if (lineno != l || line_probed.second == false || nsrcs > 1) continue; @@ -1596,9 +1620,8 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) bool -dwflpp::find_struct_member(const string& member, +dwflpp::find_struct_member(const target_symbol::component& c, Dwarf_Die *parentdie, - const target_symbol *e, Dwarf_Die *memberdie, vector<Dwarf_Attribute>& locs) { @@ -1616,7 +1639,7 @@ dwflpp::find_struct_member(const string& member, throw semantic_error (string (dwarf_tag(&die) == DW_TAG_union_type ? "union" : "struct") + string (dwarf_diename_integrate (&die) ?: "<anonymous>") + string (dwarf_errmsg (-1)), - e->tok); + c.tok); } do @@ -1634,10 +1657,10 @@ dwflpp::find_struct_member(const string& member, !dwarf_formref_die (&attr, &subdie)) continue; - if (find_struct_member(member, &subdie, e, memberdie, locs)) + if (find_struct_member(c, &subdie, memberdie, locs)) goto success; } - else if (name == member) + else if (name == c.member) { *memberdie = die; goto success; @@ -1656,9 +1679,9 @@ success: /* Union members don't usually have a location, * but just use the containing union's location. */ else if (dwarf_tag(parentdie) != DW_TAG_union_type) - throw semantic_error ("no location for field '" + member + throw semantic_error ("no location for field '" + c.member + "': " + string(dwarf_errmsg (-1)), - e->tok); + c.tok); return true; } @@ -1685,6 +1708,8 @@ dwflpp::translate_components(struct obstack *pool, while (i < e->components.size()) { + const target_symbol::component& c = e->components[i]; + /* XXX: This would be desirable, but we don't get the target_symbol token, and printing that gives us the file:line number too early anyway. */ #if 0 @@ -1706,39 +1731,53 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_pointer_type: c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); - if (e->components[i].first != target_symbol::comp_literal_array_index) + if (c.type != target_symbol::comp_literal_array_index && + c.type != target_symbol::comp_expression_array_index) break; /* else fall through as an array access */ case DW_TAG_array_type: - if (e->components[i].first == target_symbol::comp_literal_array_index) + if (c.type == target_symbol::comp_literal_array_index) { c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, - NULL, lex_cast<Dwarf_Word>(e->components[i].second)); + NULL, c.num_index); + ++i; + } + else if (c.type == target_symbol::comp_expression_array_index) + { + string index = "THIS->index" + lex_cast<string>(i); + c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, + index.c_str(), 0); ++i; } else - throw semantic_error("bad field '" - + e->components[i].second - + "' for array type", - e->tok); + throw semantic_error ("invalid access '" + + lex_cast<string>(c) + + "' for array type", + c.tok); break; case DW_TAG_structure_type: case DW_TAG_union_type: + if (c.type != target_symbol::comp_struct_member) + throw semantic_error ("invalid access '" + + lex_cast<string>(c) + + "' for struct/union type", + c.tok); + if (dwarf_hasattr(die, DW_AT_declaration)) { Dwarf_Die *tmpdie = dwflpp::declaration_resolve(dwarf_diename(die)); if (tmpdie == NULL) throw semantic_error ("unresolved struct " + string (dwarf_diename_integrate (die) ?: "<anonymous>"), - e->tok); + c.tok); *die_mem = *tmpdie; } { vector<Dwarf_Attribute> locs; - if (!find_struct_member(e->components[i].second, die, e, die, locs)) + if (!find_struct_member(c, die, die, locs)) { string alternatives; stringstream members; @@ -1746,10 +1785,10 @@ dwflpp::translate_components(struct obstack *pool, if (members.str().size() != 0) alternatives = " (alternatives:" + members.str(); throw semantic_error("unable to find member '" + - e->components[i].second + "' for struct " + c.member + "' for struct " + string(dwarf_diename_integrate(die) ?: "<unknown>") + alternatives, - e->tok); + c.tok); } for (unsigned j = 0; j < locs.size(); ++j) @@ -1760,39 +1799,41 @@ dwflpp::translate_components(struct obstack *pool, break; case DW_TAG_enumeration_type: - throw semantic_error ("field '" - + e->components[i].second + throw semantic_error ("invalid access '" + + lex_cast<string>(c) + "' vs. enum type " + string(dwarf_diename_integrate (die) ?: "<anonymous type>"), - e->tok); + c.tok); break; case DW_TAG_base_type: - throw semantic_error ("field '" - + e->components[i].second + throw semantic_error ("invalid access '" + + lex_cast<string>(c) + "' vs. base type " + string(dwarf_diename_integrate (die) ?: "<anonymous type>"), - e->tok); + c.tok); break; case -1: throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)), - e->tok); + c.tok); break; default: throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>") + ": unexpected type tag " + lex_cast<string>(dwarf_tag (die)), - e->tok); + c.tok); break; } /* Now iterate on the type in DIE's attribute. */ if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL) - throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)), e->tok); + throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)), + c.tok); } /* For an array index, we need to dereference the final DIE */ - if (e->components.back().first == target_symbol::comp_literal_array_index) + if (e->components.back().type == target_symbol::comp_literal_array_index || + e->components.back().type == target_symbol::comp_expression_array_index) die = dwarf_formref_die (attr_mem, die_mem); return die; |