- return (this->visibility_ != elfcpp::STV_INTERNAL
- && this->visibility_ != elfcpp::STV_HIDDEN
- && this->visibility_ != elfcpp::STV_PROTECTED
- && parameters->output_is_shared()
- && !parameters->symbolic());
+ // It doesn't make sense to ask whether an undefined symbol
+ // is preemptible.
+ gold_assert(!this->is_undefined());
+
+ // If a symbol does not have default visibility, it can not be
+ // seen outside this link unit and therefore is not preemptible.
+ if (this->visibility_ != elfcpp::STV_DEFAULT)
+ return false;
+
+ // If this symbol has been forced to be a local symbol by a
+ // version script, then it is not visible outside this link unit
+ // and is not preemptible.
+ if (this->is_forced_local_)
+ return false;
+
+ // If we are not producing a shared library, then nothing is
+ // preemptible.
+ if (!parameters->options().shared())
+ return false;
+
+ // If the symbol was named in a --dynamic-list script, it is preemptible.
+ if (parameters->options().in_dynamic_list(this->name()))
+ return true;
+
+ // If the user used -Bsymbolic, then nothing (else) is preemptible.
+ if (parameters->options().Bsymbolic())
+ return false;
+
+ // If the user used -Bsymbolic-functions, then functions are not
+ // preemptible. We explicitly check for not being STT_OBJECT,
+ // rather than for being STT_FUNC, because that is what the GNU
+ // linker does.
+ if (this->type() != elfcpp::STT_OBJECT
+ && parameters->options().Bsymbolic_functions())
+ return false;
+
+ // Otherwise the symbol is preemptible.
+ return true;