mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
Fix incorrect handling of STT_COMMON symbols in shared libraries.
The gABI allows STT_COMMON symbols to appear in executables and shared objects, so that the dynamic loader can resolve commons across modules. When reading a shared object, however, an STT_COMMON symbol should be treated as a regular definition at link time. In a relocatable object, the gABI requires that any STT_COMMON symbols must also be defined in the special SHN_COMMON section (which we extend to include target-specific small and large common sections). Thus, there is no need for gold to treat STT_COMMON symbols as common unless the st_shndx field is also set to a common section. gold/ PR gold/18288 * resolve.cc (symbol_to_bits): Remove type parameter; adjust all callers. Don't use STT_COMMON to check for common symbols. (Symbol_table::resolve): Warn if relocatable object has STT_COMMON symbol that's not in a common section. * symtab.h (Symbol::is_common): Don't use STT_COMMON to check for common symbols.
This commit is contained in:
parent
66f38e2951
commit
b8cf50755b
@ -1,3 +1,13 @@
|
||||
2015-06-07 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/18288
|
||||
* resolve.cc (symbol_to_bits): Remove type parameter; adjust all
|
||||
callers. Don't use STT_COMMON to check for common symbols.
|
||||
(Symbol_table::resolve): Warn if relocatable object has STT_COMMON
|
||||
symbol that's not in a common section.
|
||||
* symtab.h (Symbol::is_common): Don't use STT_COMMON to check for
|
||||
common symbols.
|
||||
|
||||
2015-06-04 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/18200
|
||||
|
@ -173,7 +173,7 @@ static const unsigned int common_flag = 2 << def_undef_or_common_shift;
|
||||
|
||||
static unsigned int
|
||||
symbol_to_bits(elfcpp::STB binding, bool is_dynamic,
|
||||
unsigned int shndx, bool is_ordinary, elfcpp::STT type)
|
||||
unsigned int shndx, bool is_ordinary)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
@ -218,9 +218,7 @@ symbol_to_bits(elfcpp::STB binding, bool is_dynamic,
|
||||
break;
|
||||
|
||||
default:
|
||||
if (type == elfcpp::STT_COMMON)
|
||||
bits |= common_flag;
|
||||
else if (!is_ordinary && Symbol::is_common_shndx(shndx))
|
||||
if (!is_ordinary && Symbol::is_common_shndx(shndx))
|
||||
bits |= common_flag;
|
||||
else
|
||||
bits |= def_flag;
|
||||
@ -272,6 +270,15 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
||||
|
||||
if (!object->is_dynamic())
|
||||
{
|
||||
if (sym.get_st_type() == elfcpp::STT_COMMON
|
||||
&& (is_ordinary || !Symbol::is_common_shndx(st_shndx)))
|
||||
{
|
||||
gold_warning(_("STT_COMMON symbol '%s' in %s "
|
||||
"is not in a common section"),
|
||||
to->demangled_name().c_str(),
|
||||
to->object()->name().c_str());
|
||||
return;
|
||||
}
|
||||
// Record that we've seen this symbol in a regular object.
|
||||
to->set_in_reg();
|
||||
}
|
||||
@ -314,7 +321,8 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
||||
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)
|
||||
if (to->is_common()
|
||||
&& !is_ordinary && Symbol::is_common_shndx(st_shndx))
|
||||
{
|
||||
adjust_common = true;
|
||||
tosize = to->symsize();
|
||||
@ -370,8 +378,7 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
||||
: sym.get_st_type());
|
||||
unsigned int frombits = symbol_to_bits(sym.get_st_bind(),
|
||||
object->is_dynamic(),
|
||||
st_shndx, is_ordinary,
|
||||
fromtype);
|
||||
st_shndx, is_ordinary);
|
||||
|
||||
bool adjust_common_sizes;
|
||||
bool adjust_dyndef;
|
||||
@ -454,11 +461,9 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
|
||||
unsigned int tobits;
|
||||
if (to->source() == Symbol::IS_UNDEFINED)
|
||||
tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_UNDEF, true,
|
||||
to->type());
|
||||
tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_UNDEF, true);
|
||||
else if (to->source() != Symbol::FROM_OBJECT)
|
||||
tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_ABS, false,
|
||||
to->type());
|
||||
tobits = symbol_to_bits(to->binding(), false, elfcpp::SHN_ABS, false);
|
||||
else
|
||||
{
|
||||
bool is_ordinary;
|
||||
@ -466,8 +471,7 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
tobits = symbol_to_bits(to->binding(),
|
||||
to->object()->is_dynamic(),
|
||||
shndx,
|
||||
is_ordinary,
|
||||
to->type());
|
||||
is_ordinary);
|
||||
}
|
||||
|
||||
if ((to->type() == elfcpp::STT_TLS) ^ (fromtype == elfcpp::STT_TLS)
|
||||
|
@ -557,8 +557,6 @@ class Symbol
|
||||
{
|
||||
if (this->source_ != FROM_OBJECT)
|
||||
return false;
|
||||
if (this->type_ == elfcpp::STT_COMMON)
|
||||
return true;
|
||||
bool is_ordinary;
|
||||
unsigned int shndx = this->shndx(&is_ordinary);
|
||||
return !is_ordinary && Symbol::is_common_shndx(shndx);
|
||||
|
Loading…
Reference in New Issue
Block a user