diff options
Diffstat (limited to 'gold/resolve.cc')
-rw-r--r-- | gold/resolve.cc | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/gold/resolve.cc b/gold/resolve.cc index 8b1c321..af3d489 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -335,18 +335,33 @@ Symbol_table::resolve(Sized_symbol<size>* to, sym.get_st_type()); bool adjust_common_sizes; + bool adjust_dyndef; typename Sized_symbol<size>::Size_type tosize = to->symsize(); if (Symbol_table::should_override(to, frombits, OBJECT, object, - &adjust_common_sizes)) + &adjust_common_sizes, + &adjust_dyndef)) { + elfcpp::STB tobinding = to->binding(); this->override(to, sym, st_shndx, is_ordinary, object, version); if (adjust_common_sizes && tosize > to->symsize()) to->set_symsize(tosize); + if (adjust_dyndef) + { + // We are overriding an UNDEF or WEAK UNDEF with a DYN DEF. + // Remember which kind of UNDEF it was for future reference. + to->set_undef_binding(tobinding); + } } else { if (adjust_common_sizes && sym.get_st_size() > tosize) to->set_symsize(sym.get_st_size()); + if (adjust_dyndef) + { + // We are keeping a DYN DEF after seeing an UNDEF or WEAK UNDEF. + // Remember which kind of UNDEF it was. + to->set_undef_binding(sym.get_st_bind()); + } // The ELF ABI says that even for a reference to a symbol we // merge the visibility. to->override_visibility(sym.get_st_visibility()); @@ -381,9 +396,11 @@ Symbol_table::resolve(Sized_symbol<size>* to, bool Symbol_table::should_override(const Symbol* to, unsigned int frombits, Defined defined, Object* object, - bool* adjust_common_sizes) + bool* adjust_common_sizes, + bool* adjust_dyndef) { *adjust_common_sizes = false; + *adjust_dyndef = false; unsigned int tobits; if (to->source() == Symbol::IS_UNDEFINED) @@ -531,12 +548,17 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, return false; case UNDEF * 16 + DYN_DEF: - case WEAK_UNDEF * 16 + DYN_DEF: case DYN_UNDEF * 16 + DYN_DEF: case DYN_WEAK_UNDEF * 16 + DYN_DEF: // Use a dynamic definition if we have a reference. return true; + case WEAK_UNDEF * 16 + DYN_DEF: + // When overriding a weak undef by a dynamic definition, + // we need to remember that the original undef was weak. + *adjust_dyndef = true; + return true; + case COMMON * 16 + DYN_DEF: case WEAK_COMMON * 16 + DYN_DEF: case DYN_COMMON * 16 + DYN_DEF: @@ -554,12 +576,17 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, return false; case UNDEF * 16 + DYN_WEAK_DEF: - case WEAK_UNDEF * 16 + DYN_WEAK_DEF: case DYN_UNDEF * 16 + DYN_WEAK_DEF: case DYN_WEAK_UNDEF * 16 + DYN_WEAK_DEF: // Use a weak dynamic definition if we have a reference. return true; + case WEAK_UNDEF * 16 + DYN_WEAK_DEF: + // When overriding a weak undef by a dynamic definition, + // we need to remember that the original undef was weak. + *adjust_dyndef = true; + return true; + case COMMON * 16 + DYN_WEAK_DEF: case WEAK_COMMON * 16 + DYN_WEAK_DEF: case DYN_COMMON * 16 + DYN_WEAK_DEF: @@ -570,12 +597,16 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, case DEF * 16 + UNDEF: case WEAK_DEF * 16 + UNDEF: - case DYN_DEF * 16 + UNDEF: - case DYN_WEAK_DEF * 16 + UNDEF: case UNDEF * 16 + UNDEF: // A new undefined reference tells us nothing. return false; + case DYN_DEF * 16 + UNDEF: + case DYN_WEAK_DEF * 16 + UNDEF: + // For a dynamic def, we need to remember which kind of undef we see. + *adjust_dyndef = true; + return false; + case WEAK_UNDEF * 16 + UNDEF: case DYN_UNDEF * 16 + UNDEF: case DYN_WEAK_UNDEF * 16 + UNDEF: @@ -591,8 +622,6 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, case DEF * 16 + WEAK_UNDEF: case WEAK_DEF * 16 + WEAK_UNDEF: - case DYN_DEF * 16 + WEAK_UNDEF: - case DYN_WEAK_DEF * 16 + WEAK_UNDEF: case UNDEF * 16 + WEAK_UNDEF: case WEAK_UNDEF * 16 + WEAK_UNDEF: case DYN_UNDEF * 16 + WEAK_UNDEF: @@ -604,6 +633,12 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, // A new weak undefined reference tells us nothing. return false; + case DYN_DEF * 16 + WEAK_UNDEF: + case DYN_WEAK_DEF * 16 + WEAK_UNDEF: + // For a dynamic def, we need to remember which kind of undef we see. + *adjust_dyndef = true; + return false; + case DEF * 16 + DYN_UNDEF: case WEAK_DEF * 16 + DYN_UNDEF: case DYN_DEF * 16 + DYN_UNDEF: @@ -811,10 +846,12 @@ bool Symbol_table::should_override_with_special(const Symbol* to, Defined defined) { bool adjust_common_sizes; + bool adjust_dyn_def; unsigned int frombits = global_flag | regular_flag | def_flag; bool ret = Symbol_table::should_override(to, frombits, defined, NULL, - &adjust_common_sizes); - gold_assert(!adjust_common_sizes); + &adjust_common_sizes, + &adjust_dyn_def); + gold_assert(!adjust_common_sizes && !adjust_dyn_def); return ret; } |