X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fdwarf_reader.cc;h=ac9fbad5482f997117a9f2b465e2b3502dacd884;hb=f6044a4be7f6f04e96f145ba045608e75e1e852b;hp=e7c95ce64975be9dfdf3bc0dfd8a3e5153d97a22;hpb=b90efa5b79ac1524ec260f8eb89d1be37e0219a7;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index e7c95ce649..ac9fbad548 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -1,6 +1,6 @@ // dwarf_reader.cc -- parse dwarf2/3 debug information -// Copyright (C) 2007-2015 Free Software Foundation, Inc. +// Copyright (C) 2007-2020 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -737,7 +737,6 @@ Dwarf_die::read_attributes() break; } case elfcpp::DW_FORM_addr: - case elfcpp::DW_FORM_ref_addr: { off_t sec_off; if (this->dwinfo_->address_size() == 4) @@ -751,6 +750,20 @@ Dwarf_die::read_attributes() ref_form = true; break; } + case elfcpp::DW_FORM_ref_addr: + { + off_t sec_off; + if (this->dwinfo_->ref_addr_size() == 4) + sec_off = this->dwinfo_->read_from_pointer<32>(&pattr); + else + sec_off = this->dwinfo_->read_from_pointer<64>(&pattr); + unsigned int shndx = + this->dwinfo_->lookup_reloc(attr_off, &sec_off); + attr_value.aux.shndx = shndx; + attr_value.val.refval = sec_off; + ref_form = true; + break; + } case elfcpp::DW_FORM_block1: attr_value.aux.blocklen = *pattr++; attr_value.val.blockval = pattr; @@ -947,9 +960,11 @@ Dwarf_die::skip_attributes() pattr += this->dwinfo_->offset_size(); break; case elfcpp::DW_FORM_addr: - case elfcpp::DW_FORM_ref_addr: pattr += this->dwinfo_->address_size(); break; + case elfcpp::DW_FORM_ref_addr: + pattr += this->dwinfo_->ref_addr_size(); + break; case elfcpp::DW_FORM_block1: pattr += 1 + *pattr; break; @@ -1652,6 +1667,17 @@ Sized_dwarf_line_info::read_header_prolog( header_.min_insn_length = *lineptr; lineptr += 1; + if (header_.version < 4) + header_.max_ops_per_insn = 1; + else + { + // DWARF 4 added the maximum_operations_per_instruction field. + header_.max_ops_per_insn = *lineptr; + lineptr += 1; + // TODO: Add support for values other than 1. + gold_assert(header_.max_ops_per_insn == 1); + } + header_.default_is_stmt = *lineptr; lineptr += 1; @@ -2205,13 +2231,33 @@ Sized_dwarf_line_info::do_addr2line( return ""; std::string result = this->format_file_lineno(*it); + gold_debug(DEBUG_LOCATION, "do_addr2line: canonical result: %s", + result.c_str()); if (other_lines != NULL) - for (++it; it != offsets->end() && it->offset == offset; ++it) - { - if (it->line_num == -1) - continue; // The end of a previous function. - other_lines->push_back(this->format_file_lineno(*it)); - } + { + unsigned int last_file_num = it->file_num; + int last_line_num = it->line_num; + // Return up to 4 more locations from the beginning of the function + // for fuzzy matching. + for (++it; it != offsets->end(); ++it) + { + if (it->offset == offset && it->line_num == -1) + continue; // The end of a previous function. + if (it->line_num == -1) + break; // The end of the current function. + if (it->file_num != last_file_num || it->line_num != last_line_num) + { + other_lines->push_back(this->format_file_lineno(*it)); + gold_debug(DEBUG_LOCATION, "do_addr2line: other: %s", + other_lines->back().c_str()); + last_file_num = it->file_num; + last_line_num = it->line_num; + } + if (it->offset > offset && other_lines->size() >= 4) + break; + } + } + return result; }