summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog8
-rw-r--r--gold/resolve.cc23
-rw-r--r--gold/symtab.cc12
3 files changed, 35 insertions, 8 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 87ac625373..4b39c3fe0f 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,11 @@
+2014-09-25 Cary Coutant <ccoutant@google.com>
+
+ PR gold/17432
+ * resolve.cc (Symbol_table::resolve): Override common placeholder
+ symbols, but adjust sizes.
+ * symtab.cc (Symbol_table::add_from_object): Don't add placeholder
+ symbols to common lists.
+
2014-09-24 Alan Modra <amodra@gmail.com>
* po/POTFILES.in: Regenerate.
diff --git a/gold/resolve.cc b/gold/resolve.cc
index abb5d90d77..52dae8b999 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -309,11 +309,26 @@ Symbol_table::resolve(Sized_symbol<size>* to,
{
Pluginobj* obj = to->object()->pluginobj();
if (obj != NULL
- && parameters->options().plugins()->in_replacement_phase()
- && !to->is_common())
+ && parameters->options().plugins()->in_replacement_phase())
{
- this->override(to, sym, st_shndx, is_ordinary, object, version);
- return;
+ bool adjust_common = false;
+ typename Sized_symbol<size>::Size_type tosize = 0;
+ typename Sized_symbol<size>::Value_type tovalue = 0;
+ if (to->is_common() && !is_ordinary && st_shndx == elfcpp::SHN_COMMON)
+ {
+ adjust_common = true;
+ typename Sized_symbol<size>::Size_type tosize = to->symsize();
+ typename Sized_symbol<size>::Value_type tovalue = to->value();
+ }
+ this->override(to, sym, st_shndx, is_ordinary, object, version);
+ if (adjust_common)
+ {
+ if (tosize > to->symsize())
+ to->set_symsize(tosize);
+ if (tovalue > to->value())
+ to->set_value(tovalue);
+ }
+ return;
}
}
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 210ab25927..70fb3f04f9 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -980,7 +980,8 @@ Symbol_table::add_from_object(Object* object,
gold_assert(ret != NULL);
was_undefined = ret->is_undefined();
- was_common = ret->is_common();
+ // Commons from plugins are just placeholders.
+ was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
this->resolve(ret, sym, st_shndx, is_ordinary, orig_st_shndx, object,
version);
@@ -1003,7 +1004,8 @@ Symbol_table::add_from_object(Object* object,
ret = this->get_sized_symbol<size>(insdefault.first->second);
was_undefined = ret->is_undefined();
- was_common = ret->is_common();
+ // Commons from plugins are just placeholders.
+ was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
this->resolve(ret, sym, st_shndx, is_ordinary, orig_st_shndx, object,
version);
@@ -1066,8 +1068,10 @@ Symbol_table::add_from_object(Object* object,
}
// Keep track of common symbols, to speed up common symbol
- // allocation.
- if (!was_common && ret->is_common())
+ // allocation. Don't record commons from plugin objects;
+ // we need to wait until we see the real symbol in the
+ // replacement file.
+ if (!was_common && ret->is_common() && ret->object()->pluginobj() == NULL)
{
if (ret->type() == elfcpp::STT_TLS)
this->tls_commons_.push_back(ret);