]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Improve ODR checking.
authorCary Coutant <ccoutant@google.com>
Mon, 9 Feb 2015 23:58:57 +0000 (15:58 -0800)
committerCary Coutant <ccoutant@google.com>
Mon, 23 Feb 2015 07:44:29 +0000 (23:44 -0800)
2015-02-09  Cary Coutant  <ccoutant@google.com>

gold/
* dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Fix debug
output to print correct context.
(Sized_dwarf_line_info::do_addr2line): Add debug output. Return
up to 4 more locations at the beginning of the function.
* symtab.cc (Symbol_table::detect_odr_violations): Get canonical
result before sorting list of line numbers.

gold/dwarf_reader.cc
gold/symtab.cc

index 6049704aacf00b5c437e81dc3f7a18281943213a..4c66a9a8b9ae820370bbb6eab342cd04d36f7513 100644 (file)
@@ -2276,7 +2276,7 @@ Sized_dwarf_line_info<size, big_endian>::read_lines(
                                 "logical %u file %d line %d context %u",
                                 lsm.shndx, static_cast<int>(lsm.address),
                                 lsm.line_num, logical.file_num,
-                                logical.line_num, lsm.context);
+                                logical.line_num, logical.context);
                      entry.offset = static_cast<off_t>(lsm.address);
                      entry.header_num = this->current_header_index_;
                      entry.file_num =
@@ -2570,13 +2570,33 @@ Sized_dwarf_line_info<size, big_endian>::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;
 }
 
index 045327ac310c378d192e4a1cbd665aaeb0caade7..6ac79292de96f86cf8708dbe89a87a50669c3ddb 100644 (file)
@@ -3336,8 +3336,11 @@ Symbol_table::detect_odr_violations(const Task* task,
           first_object_name = locs->object->name();
           first_object_linenos = this->linenos_from_loc(task, *locs);
         }
+      if (first_object_linenos.empty())
+       continue;
 
       // Sort by Odr_violation_compare to make std::set_intersection work.
+      std::string first_object_canonical_result = first_object_linenos.back();
       std::sort(first_object_linenos.begin(), first_object_linenos.end(),
                 Odr_violation_compare());
 
@@ -3349,6 +3352,8 @@ Symbol_table::detect_odr_violations(const Task* task,
           if (linenos.empty())
             continue;
           // Sort by Odr_violation_compare to make std::set_intersection work.
+         gold_assert(!linenos.empty());
+          std::string second_object_canonical_result = linenos.back();
           std::sort(linenos.begin(), linenos.end(), Odr_violation_compare());
 
           Check_intersection intersection_result =
@@ -3367,13 +3372,11 @@ Symbol_table::detect_odr_violations(const Task* task,
               // which may not be the location we expect to intersect
               // with another definition.  We could print the whole
               // set of locations, but that seems too verbose.
-              gold_assert(!first_object_linenos.empty());
-              gold_assert(!linenos.empty());
               fprintf(stderr, _("  %s from %s\n"),
-                      first_object_linenos[0].c_str(),
+                      first_object_canonical_result.c_str(),
                       first_object_name.c_str());
               fprintf(stderr, _("  %s from %s\n"),
-                      linenos[0].c_str(),
+                      second_object_canonical_result.c_str(),
                       locs->object->name().c_str());
               // Only print one broken pair, to avoid needing to
               // compare against a list of the disjoint definition