diff options
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 12 | ||||
-rw-r--r-- | gold/i386.cc | 54 | ||||
-rw-r--r-- | gold/resolve.cc | 24 | ||||
-rw-r--r-- | gold/symtab.cc | 6 | ||||
-rw-r--r-- | gold/symtab.h | 5 | ||||
-rw-r--r-- | gold/x86_64.cc | 53 |
6 files changed, 124 insertions, 30 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 0289198..81e9e43 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,17 @@ 2011-07-08 Ian Lance Taylor <iant@google.com> + PR gold/12279 + * resolve.cc (Symbol_table::should_override): Add fromtype + parameter. Change all callers. Give error when linking together + TLS and non-TLS symbol. + (Symbol_table::should_override_with_special): Add fromtype + parameter. Change all callers. + * i386.cc (Target_i386::Relocate::relocate_tls): Don't crash if + there is no TLS segment if we have reported some errors. + * x86_64.cc (Target_x86_64::relocate_tls): Likewise. + +2011-07-08 Ian Lance Taylor <iant@google.com> + PR gold/12372 * target.h (Target::plt_address_for_global): New function. (Target::plt_address_for_local): New function. diff --git a/gold/i386.cc b/gold/i386.cc index 6c6c4b4..21d008c 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -2638,7 +2638,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_GD: // Global-dynamic if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_gd_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, view_size); @@ -2664,7 +2668,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_IE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type, got_offset, view, view_size); break; @@ -2687,7 +2695,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU; if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_desc_gd_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, view_size); @@ -2722,7 +2734,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_IE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type, got_offset, view, view_size); break; @@ -2754,7 +2770,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU; if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, view_size); break; @@ -2785,7 +2805,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, elfcpp::Shdr<32, false> shdr(relinfo->data_shdr); if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value -= tls_segment->memsz(); } } @@ -2797,7 +2821,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_TLS_IE_32: if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment, rel, r_type, value, view, view_size); @@ -2841,7 +2869,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, // have been created for this location, so do not apply it now. if (!parameters->options().shared()) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value -= tls_segment->memsz(); Relocate_functions<32, false>::rel32(view, value); } @@ -2852,7 +2884,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, // have been created for this location, so do not apply it now. if (!parameters->options().shared()) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value = tls_segment->memsz() - value; Relocate_functions<32, false>::rel32(view, value); } diff --git a/gold/resolve.cc b/gold/resolve.cc index 720b350..03288ec 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -351,8 +351,8 @@ Symbol_table::resolve(Sized_symbol<size>* to, 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, + if (Symbol_table::should_override(to, frombits, sym.get_st_type(), OBJECT, + object, &adjust_common_sizes, &adjust_dyndef)) { elfcpp::STB tobinding = to->binding(); @@ -409,8 +409,8 @@ 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, + elfcpp::STT fromtype, Defined defined, + Object* object, bool* adjust_common_sizes, bool* adjust_dyndef) { *adjust_common_sizes = false; @@ -434,7 +434,13 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, to->type()); } - // FIXME: Warn if either but not both of TO and SYM are STT_TLS. + if (to->type() == elfcpp::STT_TLS + ? fromtype != elfcpp::STT_TLS + : fromtype == elfcpp::STT_TLS) + Symbol_table::report_resolve_problem(true, + _("symbol '%s' used as both __thread " + "and non-__thread"), + to, defined, object); // We use a giant switch table for symbol resolution. This code is // unwieldy, but: 1) it is efficient; 2) we definitely handle all @@ -870,13 +876,15 @@ Symbol_table::report_resolve_problem(bool is_error, const char* msg, // defining special symbols. bool -Symbol_table::should_override_with_special(const Symbol* to, Defined defined) +Symbol_table::should_override_with_special(const Symbol* to, + elfcpp::STT fromtype, + 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, + bool ret = Symbol_table::should_override(to, frombits, fromtype, defined, + NULL, &adjust_common_sizes, &adjust_dyn_def); gold_assert(!adjust_common_sizes && !adjust_dyn_def); return ret; diff --git a/gold/symtab.cc b/gold/symtab.cc index 7e5b66c..26d8032 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1883,7 +1883,7 @@ Symbol_table::do_define_in_output_data( return sym; } - if (Symbol_table::should_override_with_special(oldsym, defined)) + if (Symbol_table::should_override_with_special(oldsym, type, defined)) this->override_with_special(oldsym, sym); if (resolve_oldsym) @@ -1997,7 +1997,7 @@ Symbol_table::do_define_in_output_segment( return sym; } - if (Symbol_table::should_override_with_special(oldsym, defined)) + if (Symbol_table::should_override_with_special(oldsym, type, defined)) this->override_with_special(oldsym, sym); if (resolve_oldsym) @@ -2116,7 +2116,7 @@ Symbol_table::do_define_as_constant( } if (force_override - || Symbol_table::should_override_with_special(oldsym, defined)) + || Symbol_table::should_override_with_special(oldsym, type, defined)) this->override_with_special(oldsym, sym); if (resolve_oldsym) diff --git a/gold/symtab.h b/gold/symtab.h index 9ba9c08..e2aa6a7 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -1661,7 +1661,8 @@ class Symbol_table // Whether we should override a symbol, based on flags in // resolve.cc. static bool - should_override(const Symbol*, unsigned int, Defined, Object*, bool*, bool*); + should_override(const Symbol*, unsigned int, elfcpp::STT, Defined, + Object*, bool*, bool*); // Report a problem in symbol resolution. static void @@ -1679,7 +1680,7 @@ class Symbol_table // Whether we should override a symbol with a special symbol which // is automatically defined by the linker. static bool - should_override_with_special(const Symbol*, Defined); + should_override_with_special(const Symbol*, elfcpp::STT, Defined); // Override a symbol with a special symbol. template<int size> diff --git a/gold/x86_64.cc b/gold/x86_64.cc index da4efed..182429e 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -3110,7 +3110,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_gd_to_le(relinfo, relnum, tls_segment, rela, r_type, value, view, view_size); @@ -3136,7 +3140,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_IE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value = target->got_plt_section()->address() + got_offset; this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type, value, view, address, view_size); @@ -3165,7 +3173,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_desc_gd_to_le(relinfo, relnum, tls_segment, rela, r_type, value, view, view_size); @@ -3200,7 +3212,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_IE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value = target->got_plt_section()->address() + got_offset; this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type, value, view, address, @@ -3232,7 +3248,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } this->tls_ld_to_le(relinfo, relnum, tls_segment, rela, r_type, value, view, view_size); break; @@ -3262,7 +3282,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, // R_X86_64_TLSLD. if (optimized_type == tls::TLSOPT_TO_LE && is_executable) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value -= tls_segment->memsz(); } Relocate_functions<64, false>::rela32(view, value, addend); @@ -3272,7 +3296,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, // See R_X86_64_DTPOFF32, just above, for why we check for is_executable. if (optimized_type == tls::TLSOPT_TO_LE && is_executable) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value -= tls_segment->memsz(); } Relocate_functions<64, false>::rela64(view, value, addend); @@ -3281,7 +3309,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec if (optimized_type == tls::TLSOPT_TO_LE) { - gold_assert(tls_segment != NULL); + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } Target_x86_64::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment, rela, r_type, value, view, view_size); @@ -3316,6 +3348,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, break; case elfcpp::R_X86_64_TPOFF32: // Local-exec + if (tls_segment == NULL) + { + gold_assert(parameters->errors()->error_count() > 0); + return; + } value -= tls_segment->memsz(); Relocate_functions<64, false>::rela32(view, value, addend); break; |