summaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2015-04-09 11:52:21 -0700
committerCary Coutant <ccoutant@google.com>2015-04-09 11:53:01 -0700
commit437ddf0c4cb63fdb68c4bd1cc155144db344d0c5 (patch)
tree125d12fcbbc64bc9b76e629407a64c687ac12000 /gold
parentcd6faa73f8e3b888ee8b73a733382a5587aca202 (diff)
downloadbinutils-gdb-437ddf0c4cb63fdb68c4bd1cc155144db344d0c5.tar.gz
Improve ODR checking in gold.
gold/ * debug.h (DEBUG_LOCATION): New. (DEBUG_ALL): Include DEBUG_LOCATION. (debug_string_to_enum): Add DEBUG_LOCATION. * 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. * testsuite/debug_msg.sh: Allow range of line numbers for canonical results on optimized code.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog14
-rw-r--r--gold/debug.h5
-rw-r--r--gold/dwarf_reader.cc32
-rw-r--r--gold/symtab.cc11
-rwxr-xr-xgold/testsuite/debug_msg.sh12
5 files changed, 57 insertions, 17 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index fa82e421e0c..9943cf50a1e 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,17 @@
+2015-04-09 Cary Coutant <ccoutant@google.com>
+
+ * debug.h (DEBUG_LOCATION): New.
+ (DEBUG_ALL): Include DEBUG_LOCATION.
+ (debug_string_to_enum): Add DEBUG_LOCATION.
+ * 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.
+ * testsuite/debug_msg.sh: Allow range of line numbers for
+ canonical results on optimized code.
+
2015-04-07 HC Yen <hc.yen@mediatek.com>
Add AArch32 support for gold linker.
diff --git a/gold/debug.h b/gold/debug.h
index bca55f3798d..3fecbd8bf05 100644
--- a/gold/debug.h
+++ b/gold/debug.h
@@ -38,9 +38,11 @@ const int DEBUG_SCRIPT = 0x2;
const int DEBUG_FILES = 0x4;
const int DEBUG_RELAXATION = 0x8;
const int DEBUG_INCREMENTAL = 0x10;
+const int DEBUG_LOCATION = 0x20;
const int DEBUG_ALL = (DEBUG_TASK | DEBUG_SCRIPT | DEBUG_FILES
- | DEBUG_RELAXATION | DEBUG_INCREMENTAL);
+ | DEBUG_RELAXATION | DEBUG_INCREMENTAL
+ | DEBUG_LOCATION);
// Convert a debug string to the appropriate enum.
inline int
@@ -54,6 +56,7 @@ debug_string_to_enum(const char* arg)
{ "files", DEBUG_FILES },
{ "relaxation", DEBUG_RELAXATION },
{ "incremental", DEBUG_INCREMENTAL },
+ { "location", DEBUG_LOCATION },
{ "all", DEBUG_ALL }
};
diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc
index e7c95ce6497..59b85b8bb41 100644
--- a/gold/dwarf_reader.cc
+++ b/gold/dwarf_reader.cc
@@ -2205,13 +2205,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;
}
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 045327ac310..88e932268ed 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -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
diff --git a/gold/testsuite/debug_msg.sh b/gold/testsuite/debug_msg.sh
index 785e5c5f3e7..54c72f14280 100755
--- a/gold/testsuite/debug_msg.sh
+++ b/gold/testsuite/debug_msg.sh
@@ -74,7 +74,7 @@ fi
# Check we detected the ODR (One Definition Rule) violation.
check debug_msg.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
check debug_msg.err "odr_violation1.cc:6"
-check debug_msg.err "odr_violation2.cc:12"
+check debug_msg.err "odr_violation2.cc:1[25]"
# Check we don't have ODR false positives:
check_missing debug_msg.err "OdrDerived::~OdrDerived()"
@@ -88,7 +88,7 @@ check_missing debug_msg.err "odr_violation1.cc:16"
check_missing debug_msg.err "odr_violation2.cc:23"
check debug_msg.err ": symbol 'SometimesInlineFunction(int)' defined in multiple places (possible ODR violation):"
check debug_msg.err "debug_msg.cc:68"
-check debug_msg.err "odr_violation2.cc:27"
+check debug_msg.err "odr_violation2.cc:2[78]"
# Check for the same error messages when using --compressed-debug-sections.
if test -r debug_msg_cdebug.err
@@ -106,7 +106,7 @@ then
fi
check debug_msg_cdebug.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
check debug_msg_cdebug.err "odr_violation1.cc:6"
- check debug_msg_cdebug.err "odr_violation2.cc:12"
+ check debug_msg_cdebug.err "odr_violation2.cc:1[25]"
check_missing debug_msg_cdebug.err "OdrDerived::~OdrDerived()"
check_missing debug_msg_cdebug.err "__adjust_heap"
check_missing debug_msg_cdebug.err ": symbol 'OverriddenCFunction' defined in multiple places (possible ODR violation):"
@@ -114,7 +114,7 @@ then
check_missing debug_msg_cdebug.err "odr_violation2.cc:23"
check debug_msg_cdebug.err ": symbol 'SometimesInlineFunction(int)' defined in multiple places (possible ODR violation):"
check debug_msg_cdebug.err "debug_msg.cc:68"
- check debug_msg_cdebug.err "odr_violation2.cc:27"
+ check debug_msg_cdebug.err "odr_violation2.cc:2[78]"
fi
# When linking together .so's, we don't catch the line numbers, but we
@@ -124,7 +124,7 @@ check debug_msg_so.err "debug_msg.so: error: undefined reference to 'undef_fn2()
check debug_msg_so.err "debug_msg.so: error: undefined reference to 'undef_int'"
check debug_msg_so.err ": symbol 'Ordering::operator()(int, int)' defined in multiple places (possible ODR violation):"
check debug_msg_so.err "odr_violation1.cc:6"
-check debug_msg_so.err "odr_violation2.cc:12"
+check debug_msg_so.err "odr_violation2.cc:1[25]"
check_missing debug_msg_so.err "OdrDerived::~OdrDerived()"
check_missing debug_msg_so.err "__adjust_heap"
check_missing debug_msg_so.err ": symbol 'OverriddenCFunction' defined in multiple places (possible ODR violation):"
@@ -132,7 +132,7 @@ check_missing debug_msg_so.err "odr_violation1.cc:16"
check_missing debug_msg_so.err "odr_violation2.cc:23"
check debug_msg_so.err ": symbol 'SometimesInlineFunction(int)' defined in multiple places (possible ODR violation):"
check debug_msg_so.err "debug_msg.cc:68"
-check debug_msg_so.err "odr_violation2.cc:27"
+check debug_msg_so.err "odr_violation2.cc:2[78]"
# These messages shouldn't need any debug info to detect:
check debug_msg_ndebug.err "debug_msg_ndebug.so: error: undefined reference to 'undef_fn1()'"