This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[gold patch] When comparing two symbols, handle the forwarding case
- From: "Sterling Augustine via binutils" <binutils at sourceware dot org>
- To: Binutils <binutils at sourceware dot org>
- Date: Wed, 10 Jan 2018 14:50:37 -0800
- Subject: [gold patch] When comparing two symbols, handle the forwarding case
- Authentication-results: sourceware.org; auth=none
- Reply-to: Sterling Augustine <saugustine at google dot com>
The function Cref_inputs::Cref_table_compare::operator() claims that
two different symbols can't have the same name and version.
But this can actually happen in obscure cases dealing with forwarding
symbols. See the complicated comment in
Symbol_table::define_default_version for those circumstances.
I'm having trouble writing a small test case to demonstrate the
failure, but I believe it's straightforward fix.
The enclosed patch adds logic to handle such a case.
2018-1-10 Sterling Augustine <saugustine@google.com>
* cref.cc (Cref_inputs::Cref_table_compare::operator): Add conditionals and
calls to is_forwarder
diff --git a/gold/cref.cc b/gold/cref.cc
index 84a9e46c84..0777453501 100644
--- a/gold/cref.cc
+++ b/gold/cref.cc
@@ -236,9 +236,13 @@ Cref_inputs::Cref_table_compare::operator()(const
Symbol* s1,
}
// We should never have two different symbols with the same name and
- // version.
+ // version, where one doesn't forward to the other.
if (s1 == s2)
return false;
+ if (s1->is_forwarder() && !s2->is_forwarder())
+ return true;
+ if (!s1->is_forwarder() && s2->is_forwarder())
+ return false;
gold_unreachable();
}
diff --git a/gold/cref.cc b/gold/cref.cc
index 84a9e46c84..0777453501 100644
--- a/gold/cref.cc
+++ b/gold/cref.cc
@@ -236,9 +236,13 @@ Cref_inputs::Cref_table_compare::operator()(const Symbol* s1,
}
// We should never have two different symbols with the same name and
- // version.
+ // version, where one doesn't forward to the other.
if (s1 == s2)
return false;
+ if (s1->is_forwarder() && !s2->is_forwarder())
+ return true;
+ if (!s1->is_forwarder() && s2->is_forwarder())
+ return false;
gold_unreachable();
}