diff options
author | Cary Coutant <ccoutant@gmail.com> | 2015-06-07 14:03:09 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2015-06-07 14:03:52 -0700 |
commit | b8cf50755b573140aae71f7247b604373fcdfbeb (patch) | |
tree | 9703225459949bc9fde830bbf7bba2cca5dcd38d /gold/resolve.cc | |
parent | 66f38e2951a1f7110ca3f1adf362322ec4208428 (diff) | |
download | binutils-b8cf50755b573140aae71f7247b604373fcdfbeb.zip binutils-b8cf50755b573140aae71f7247b604373fcdfbeb.tar.gz binutils-b8cf50755b573140aae71f7247b604373fcdfbeb.tar.bz2 |
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.
Diffstat (limited to 'gold/resolve.cc')
-rw-r--r-- | gold/resolve.cc | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/gold/resolve.cc b/gold/resolve.cc index 1c0344c..fdae0ba 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -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) |