From 99fff23b2e6c675a1f35bf3ba853f70e2b7b4ce8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 29 Dec 2009 00:31:48 +0000 Subject: * symtab.h (class Symbol_table): Add enum Defined. * resolve.cc (Symbol_table::should_override): Add defined parameter. Change all callers. Test whether object is NULL before calling a method on it. (Symbol_table::report_resolve_problem): Add defined parameter. Change all callers. (Symbol_table::should_override_with_special): Likewise. * symtab.cc (Symbol_table::define_in_output_data): Add defined parameter. Change all callers. (Symbol_table::do_define_in_output_data): Likewise. (Symbol_table::define_in_output_segment): Likewise. (Symbol_table::do_define_in_output_segment): Likewise. (Symbol_table::define_as_constant): Likewise. (Symbol_table::do_define_as_constant): Likewise. * script.h (class Symbol_assignment): Add is_defsym parameter to constructor; change all callers. * script.cc (Script_options::add_symbol_assignment): Add is_defsym parameter. Change all callers. Add is_defsym_ field. (class Parser_closure): Add parsing_defsym parameter to constructor; change all callers. Add parsing_defsym accessor function. Add parsing_defsym_ field. --- gold/ChangeLog | 24 +++++++++++++++++++++ gold/arm.cc | 11 ++++++---- gold/dynobj.cc | 4 +++- gold/i386.cc | 2 ++ gold/layout.cc | 5 ++++- gold/powerpc.cc | 3 +++ gold/resolve.cc | 56 +++++++++++++++++++++++++++++++++---------------- gold/script-sections.cc | 4 ++-- gold/script.cc | 41 +++++++++++++++++++++++++----------- gold/script.h | 15 +++++++------ gold/sparc.cc | 2 ++ gold/symtab.cc | 42 ++++++++++++++++++++++--------------- gold/symtab.h | 36 +++++++++++++++++++++++-------- gold/x86_64.cc | 2 ++ 14 files changed, 177 insertions(+), 70 deletions(-) (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index 3292a51b47..ed7f31d768 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,27 @@ +2009-12-28 Ian Lance Taylor + + * symtab.h (class Symbol_table): Add enum Defined. + * resolve.cc (Symbol_table::should_override): Add defined + parameter. Change all callers. Test whether object is NULL + before calling a method on it. + (Symbol_table::report_resolve_problem): Add defined parameter. + Change all callers. + (Symbol_table::should_override_with_special): Likewise. + * symtab.cc (Symbol_table::define_in_output_data): Add defined + parameter. Change all callers. + (Symbol_table::do_define_in_output_data): Likewise. + (Symbol_table::define_in_output_segment): Likewise. + (Symbol_table::do_define_in_output_segment): Likewise. + (Symbol_table::define_as_constant): Likewise. + (Symbol_table::do_define_as_constant): Likewise. + * script.h (class Symbol_assignment): Add is_defsym parameter to + constructor; change all callers. + * script.cc (Script_options::add_symbol_assignment): Add is_defsym + parameter. Change all callers. Add is_defsym_ field. + (class Parser_closure): Add parsing_defsym parameter to + constructor; change all callers. Add parsing_defsym accessor + function. Add parsing_defsym_ field. + 2009-12-28 Ian Lance Taylor * gold.cc (queue_middle_tasks): Fix formatting. diff --git a/gold/arm.cc b/gold/arm.cc index b02afbe23e..afe1bc0a22 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -2611,6 +2611,7 @@ Target_arm::got_section(Symbol_table* symtab, Layout* layout) // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, + Symbol_table::PREDEFINED, this->got_plt_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, @@ -4763,12 +4764,14 @@ Target_arm::do_finalize_sections( && !parameters->options().relocatable()) { // Create __exidx_start and __exdix_end symbols. - symtab->define_in_output_data("__exidx_start", NULL, exidx_section, - 0, 0, elfcpp::STT_OBJECT, + symtab->define_in_output_data("__exidx_start", NULL, + Symbol_table::PREDEFINED, + exidx_section, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0, false, false); - symtab->define_in_output_data("__exidx_end", NULL, exidx_section, - 0, 0, elfcpp::STT_OBJECT, + symtab->define_in_output_data("__exidx_end", NULL, + Symbol_table::PREDEFINED, + exidx_section, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0, true, false); diff --git a/gold/dynobj.cc b/gold/dynobj.cc index 1b0dad93d7..ebb5f33ad9 100644 --- a/gold/dynobj.cc +++ b/gold/dynobj.cc @@ -1526,7 +1526,9 @@ Versions::finalize(Symbol_table* symtab, unsigned int dynsym_index, if (!(*p)->is_symbol_created()) { Symbol* vsym = symtab->define_as_constant((*p)->name(), - (*p)->name(), 0, 0, + (*p)->name(), + Symbol_table::PREDEFINED, + 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_GLOBAL, elfcpp::STV_DEFAULT, 0, diff --git a/gold/i386.cc b/gold/i386.cc index bf7c695ed4..43edd65db7 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -480,6 +480,7 @@ Target_i386::got_section(Symbol_table* symtab, Layout* layout) // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, + Symbol_table::PREDEFINED, this->got_plt_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, @@ -779,6 +780,7 @@ Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout) { bool is_exec = parameters->options().output_is_executable(); symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL, + Symbol_table::PREDEFINED, tls_segment, 0, 0, elfcpp::STT_TLS, elfcpp::STB_LOCAL, diff --git a/gold/layout.cc b/gold/layout.cc index 914de92cfc..17477bba03 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -1161,7 +1161,8 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab) false, false, true); this->dynamic_section_->set_is_relro(); - symtab->define_in_output_data("_DYNAMIC", NULL, this->dynamic_section_, 0, 0, + symtab->define_in_output_data("_DYNAMIC", NULL, Symbol_table::PREDEFINED, + this->dynamic_section_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, elfcpp::STV_HIDDEN, 0, false, false); @@ -1195,6 +1196,7 @@ Layout::define_section_symbols(Symbol_table* symtab) symtab->define_in_output_data(start_name.c_str(), NULL, // version + Symbol_table::PREDEFINED, *p, 0, // value 0, // symsize @@ -1207,6 +1209,7 @@ Layout::define_section_symbols(Symbol_table* symtab) symtab->define_in_output_data(stop_name.c_str(), NULL, // version + Symbol_table::PREDEFINED, *p, 0, // value 0, // symsize diff --git a/gold/powerpc.cc b/gold/powerpc.cc index bd5571cbf5..f27a9f1a81 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -738,6 +738,7 @@ Target_powerpc::got_section(Symbol_table* symtab, // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, + Symbol_table::PREDEFINED, this->got_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, @@ -952,6 +953,7 @@ Target_powerpc::make_plt_entry(Symbol_table* symtab, // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, + Symbol_table::PREDEFINED, this->plt_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, @@ -1512,6 +1514,7 @@ Target_powerpc::scan_relocs( | elfcpp::SHF_WRITE, sdata, false); symtab->define_in_output_data("_SDA_BASE_", NULL, + Symbol_table::PREDEFINED, os, 32768, 0, elfcpp::STT_OBJECT, diff --git a/gold/resolve.cc b/gold/resolve.cc index 89b10b9f9a..d32b2b9712 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -304,7 +304,7 @@ Symbol_table::resolve(Sized_symbol* to, bool adjust_common_sizes; typename Sized_symbol::Size_type tosize = to->symsize(); - if (Symbol_table::should_override(to, frombits, object, + if (Symbol_table::should_override(to, frombits, OBJECT, object, &adjust_common_sizes)) { this->override(to, sym, st_shndx, is_ordinary, object, version); @@ -326,16 +326,16 @@ Symbol_table::resolve(Sized_symbol* to, Symbol_table::report_resolve_problem(false, _("common of '%s' overriding " "smaller common"), - to, object); + to, OBJECT, object); else if (tosize < sym.get_st_size()) Symbol_table::report_resolve_problem(false, _("common of '%s' overidden by " "larger common"), - to, object); + to, OBJECT, object); else Symbol_table::report_resolve_problem(false, _("multiple common of '%s'"), - to, object); + to, OBJECT, object); } // A new weak undefined reference, merging with an old weak @@ -378,7 +378,8 @@ Symbol_table::resolve(Sized_symbol* to, bool Symbol_table::should_override(const Symbol* to, unsigned int frombits, - Object* object, bool* adjust_common_sizes) + Defined defined, Object* object, + bool* adjust_common_sizes) { *adjust_common_sizes = false; @@ -436,12 +437,12 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, // --just-symbols, then don't warn. This is for compatibility // with the GNU linker. FIXME: This is a hack. if ((to->source() == Symbol::FROM_OBJECT && to->object()->just_symbols()) - || object->just_symbols()) + || (object != NULL && object->just_symbols())) return false; Symbol_table::report_resolve_problem(true, _("multiple definition of '%s'"), - to, object); + to, defined, object); return false; case WEAK_DEF * 16 + DEF: @@ -481,7 +482,7 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, Symbol_table::report_resolve_problem(false, _("definition of '%s' overriding " "common"), - to, object); + to, defined, object); return true; case DEF * 16 + WEAK_DEF: @@ -516,7 +517,7 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, Symbol_table::report_resolve_problem(false, _("definition of '%s' overriding " "dynamic common definition"), - to, object); + to, defined, object); return true; case DEF * 16 + DYN_DEF: @@ -636,7 +637,7 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, Symbol_table::report_resolve_problem(false, _("common '%s' overridden by " "previous definition"), - to, object); + to, defined, object); return false; case WEAK_DEF * 16 + COMMON: @@ -745,7 +746,8 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, // Issue an error or warning due to symbol resolution. IS_ERROR // indicates an error rather than a warning. MSG is the error // message; it is expected to have a %s for the symbol name. TO is -// the existing symbol. OBJECT is where the new symbol was found. +// the existing symbol. DEFINED/OBJECT is where the new symbol was +// found. // FIXME: We should have better location information here. When the // symbol is defined, we should be able to pull the location from the @@ -753,7 +755,8 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, void Symbol_table::report_resolve_problem(bool is_error, const char* msg, - const Symbol* to, Object* object) + const Symbol* to, Defined defined, + Object* object) { std::string demangled(to->demangled_name()); size_t len = strlen(msg) + demangled.length() + 10; @@ -761,10 +764,27 @@ Symbol_table::report_resolve_problem(bool is_error, const char* msg, snprintf(buf, len, msg, demangled.c_str()); const char* objname; - if (object != NULL) - objname = object->name().c_str(); - else - objname = _("command line"); + switch (defined) + { + case OBJECT: + objname = object->name().c_str(); + break; + case COPY: + objname = _("COPY reloc"); + break; + case DEFSYM: + case UNDEFINED: + objname = _("command line"); + break; + case SCRIPT: + objname = _("linker script"); + break; + case PREDEFINED: + objname = _("linker defined"); + break; + default: + gold_unreachable(); + } if (is_error) gold_error("%s: %s", objname, buf); @@ -785,11 +805,11 @@ Symbol_table::report_resolve_problem(bool is_error, const char* msg, // defining special symbols. bool -Symbol_table::should_override_with_special(const Symbol* to) +Symbol_table::should_override_with_special(const Symbol* to, Defined defined) { bool adjust_common_sizes; unsigned int frombits = global_flag | regular_flag | def_flag; - bool ret = Symbol_table::should_override(to, frombits, NULL, + bool ret = Symbol_table::should_override(to, frombits, defined, NULL, &adjust_common_sizes); gold_assert(!adjust_common_sizes); return ret; diff --git a/gold/script-sections.cc b/gold/script-sections.cc index f38cbd0f0f..e10643584c 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -406,7 +406,7 @@ class Sections_element_assignment : public Sections_element public: Sections_element_assignment(const char* name, size_t namelen, Expression* val, bool provide, bool hidden) - : assignment_(name, namelen, val, provide, hidden) + : assignment_(name, namelen, false, val, provide, hidden) { } // Add the symbol to the symbol table. @@ -593,7 +593,7 @@ class Output_section_element_assignment : public Output_section_element Output_section_element_assignment(const char* name, size_t namelen, Expression* val, bool provide, bool hidden) - : assignment_(name, namelen, val, provide, hidden) + : assignment_(name, namelen, false, val, provide, hidden) { } // Add the symbol to the symbol table. diff --git a/gold/script.cc b/gold/script.cc index 8839213bc2..fb35fb8b4c 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -874,6 +874,9 @@ Symbol_assignment::add_to_table(Symbol_table* symtab) elfcpp::STV vis = this->hidden_ ? elfcpp::STV_HIDDEN : elfcpp::STV_DEFAULT; this->sym_ = symtab->define_as_constant(this->name_.c_str(), NULL, // version + (this->is_defsym_ + ? Symbol_table::DEFSYM + : Symbol_table::SCRIPT), 0, // value 0, // size elfcpp::STT_NOTYPE, @@ -1051,18 +1054,21 @@ Script_options::Script_options() void Script_options::add_symbol_assignment(const char* name, size_t length, - Expression* value, bool provide, - bool hidden) + bool is_defsym, Expression* value, + bool provide, bool hidden) { if (length != 1 || name[0] != '.') { if (this->script_sections_.in_sections_clause()) - this->script_sections_.add_symbol_assignment(name, length, value, - provide, hidden); - else { - Symbol_assignment* p = new Symbol_assignment(name, length, value, + gold_assert(!is_defsym); + this->script_sections_.add_symbol_assignment(name, length, value, provide, hidden); + } + else + { + Symbol_assignment* p = new Symbol_assignment(name, length, is_defsym, + value, provide, hidden); this->symbol_assignments_.push_back(p); } } @@ -1162,13 +1168,14 @@ class Parser_closure public: Parser_closure(const char* filename, const Position_dependent_options& posdep_options, - bool in_group, bool is_in_sysroot, + bool parsing_defsym, bool in_group, bool is_in_sysroot, Command_line* command_line, Script_options* script_options, Lex* lex, bool skip_on_incompatible_target) : filename_(filename), posdep_options_(posdep_options), - in_group_(in_group), is_in_sysroot_(is_in_sysroot), + parsing_defsym_(parsing_defsym), in_group_(in_group), + is_in_sysroot_(is_in_sysroot), skip_on_incompatible_target_(skip_on_incompatible_target), found_incompatible_target_(false), command_line_(command_line), script_options_(script_options), @@ -1191,6 +1198,11 @@ class Parser_closure position_dependent_options() { return this->posdep_options_; } + // Whether we are parsing a --defsym. + bool + parsing_defsym() const + { return this->parsing_defsym_; } + // Return whether this script is being run in a group. bool in_group() const @@ -1322,6 +1334,8 @@ class Parser_closure const char* filename_; // The position dependent options. Position_dependent_options posdep_options_; + // True if we are parsing a --defsym. + bool parsing_defsym_; // Whether we are currently in a --start-group/--end-group. bool in_group_; // Whether the script was found in a sysrooted directory. @@ -1374,6 +1388,7 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout, Parser_closure closure(input_file->filename().c_str(), input_argument->file().options(), + false, input_group != NULL, input_file->is_in_sysroot(), NULL, @@ -1469,6 +1484,7 @@ read_script_file(const char* filename, Command_line* cmdline, Parser_closure closure(filename, cmdline->position_dependent_options(), + first_token == Lex::DYNAMIC_LIST, false, input_file.is_in_sysroot(), cmdline, @@ -1532,8 +1548,8 @@ Script_options::define_symbol(const char* definition) // Dummy value. Position_dependent_options posdep_options; - Parser_closure closure("command line", posdep_options, false, false, NULL, - this, &lex, false); + Parser_closure closure("command line", posdep_options, true, + false, false, NULL, this, &lex, false); if (yyparse(&closure) != 0) return false; @@ -2266,8 +2282,9 @@ script_set_symbol(void* closurev, const char* name, size_t length, Parser_closure* closure = static_cast(closurev); const bool provide = providei != 0; const bool hidden = hiddeni != 0; - closure->script_options()->add_symbol_assignment(name, length, value, - provide, hidden); + closure->script_options()->add_symbol_assignment(name, length, + closure->parsing_defsym(), + value, provide, hidden); closure->clear_skip_on_incompatible_target(); } diff --git a/gold/script.h b/gold/script.h index 755bb7947d..7129565869 100644 --- a/gold/script.h +++ b/gold/script.h @@ -200,10 +200,10 @@ class Version_script_info class Symbol_assignment { public: - Symbol_assignment(const char* name, size_t namelen, Expression* val, - bool provide, bool hidden) - : name_(name, namelen), val_(val), provide_(provide), hidden_(hidden), - sym_(NULL) + Symbol_assignment(const char* name, size_t namelen, bool is_defsym, + Expression* val, bool provide, bool hidden) + : name_(name, namelen), val_(val), is_defsym_(is_defsym), + provide_(provide), hidden_(hidden), sym_(NULL) { } // Add the symbol to the symbol table. @@ -246,6 +246,9 @@ class Symbol_assignment std::string name_; // Expression to assign to symbol. Expression* val_; + // True if this symbol is defined by a --defsym, false if it is + // defined in a linker script. + bool is_defsym_; // Whether the assignment should be provided (only set if there is // an undefined reference to the symbol. bool provide_; @@ -298,8 +301,8 @@ class Script_options // Add a symbol to be defined. void - add_symbol_assignment(const char* name, size_t length, Expression* value, - bool provide, bool hidden); + add_symbol_assignment(const char* name, size_t length, bool is_defsym, + Expression* value, bool provide, bool hidden); // Add an assertion. void diff --git a/gold/sparc.cc b/gold/sparc.cc index 8047a11536..9e1e666dcb 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -1031,6 +1031,7 @@ Target_sparc::got_section(Symbol_table* symtab, // Define _GLOBAL_OFFSET_TABLE_ at the start of the .got section. symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, + Symbol_table::PREDEFINED, this->got_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, @@ -1375,6 +1376,7 @@ Target_sparc::make_plt_entry(Symbol_table* symtab, // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section. symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL, + Symbol_table::PREDEFINED, this->plt_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, diff --git a/gold/symtab.cc b/gold/symtab.cc index 8cd4a40f1c..d8461a742d 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1686,6 +1686,7 @@ Symbol_table::define_special_symbol(const char** pname, const char** pversion, Symbol* Symbol_table::define_in_output_data(const char* name, const char* version, + Defined defined, Output_data* od, uint64_t value, uint64_t symsize, @@ -1699,7 +1700,7 @@ Symbol_table::define_in_output_data(const char* name, if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) - return this->do_define_in_output_data<32>(name, version, od, + return this->do_define_in_output_data<32>(name, version, defined, od, value, symsize, type, binding, visibility, nonvis, offset_is_from_end, @@ -1711,7 +1712,7 @@ Symbol_table::define_in_output_data(const char* name, else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) - return this->do_define_in_output_data<64>(name, version, od, + return this->do_define_in_output_data<64>(name, version, defined, od, value, symsize, type, binding, visibility, nonvis, offset_is_from_end, @@ -1731,6 +1732,7 @@ Sized_symbol* Symbol_table::do_define_in_output_data( const char* name, const char* version, + Defined defined, Output_data* od, typename elfcpp::Elf_types::Elf_Addr value, typename elfcpp::Elf_types::Elf_WXword symsize, @@ -1782,7 +1784,7 @@ Symbol_table::do_define_in_output_data( return sym; } - if (Symbol_table::should_override_with_special(oldsym)) + if (Symbol_table::should_override_with_special(oldsym, defined)) this->override_with_special(oldsym, sym); if (resolve_oldsym) @@ -1798,7 +1800,9 @@ Symbol_table::do_define_in_output_data( Symbol* Symbol_table::define_in_output_segment(const char* name, - const char* version, Output_segment* os, + const char* version, + Defined defined, + Output_segment* os, uint64_t value, uint64_t symsize, elfcpp::STT type, @@ -1811,7 +1815,7 @@ Symbol_table::define_in_output_segment(const char* name, if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) - return this->do_define_in_output_segment<32>(name, version, os, + return this->do_define_in_output_segment<32>(name, version, defined, os, value, symsize, type, binding, visibility, nonvis, offset_base, only_if_ref); @@ -1822,7 +1826,7 @@ Symbol_table::define_in_output_segment(const char* name, else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) - return this->do_define_in_output_segment<64>(name, version, os, + return this->do_define_in_output_segment<64>(name, version, defined, os, value, symsize, type, binding, visibility, nonvis, offset_base, only_if_ref); @@ -1841,6 +1845,7 @@ Sized_symbol* Symbol_table::do_define_in_output_segment( const char* name, const char* version, + Defined defined, Output_segment* os, typename elfcpp::Elf_types::Elf_Addr value, typename elfcpp::Elf_types::Elf_WXword symsize, @@ -1892,7 +1897,7 @@ Symbol_table::do_define_in_output_segment( return sym; } - if (Symbol_table::should_override_with_special(oldsym)) + if (Symbol_table::should_override_with_special(oldsym, defined)) this->override_with_special(oldsym, sym); if (resolve_oldsym) @@ -1910,6 +1915,7 @@ Symbol_table::do_define_in_output_segment( Symbol* Symbol_table::define_as_constant(const char* name, const char* version, + Defined defined, uint64_t value, uint64_t symsize, elfcpp::STT type, @@ -1922,7 +1928,7 @@ Symbol_table::define_as_constant(const char* name, if (parameters->target().get_size() == 32) { #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) - return this->do_define_as_constant<32>(name, version, value, + return this->do_define_as_constant<32>(name, version, defined, value, symsize, type, binding, visibility, nonvis, only_if_ref, force_override); @@ -1933,7 +1939,7 @@ Symbol_table::define_as_constant(const char* name, else if (parameters->target().get_size() == 64) { #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) - return this->do_define_as_constant<64>(name, version, value, + return this->do_define_as_constant<64>(name, version, defined, value, symsize, type, binding, visibility, nonvis, only_if_ref, force_override); @@ -1952,6 +1958,7 @@ Sized_symbol* Symbol_table::do_define_as_constant( const char* name, const char* version, + Defined defined, typename elfcpp::Elf_types::Elf_Addr value, typename elfcpp::Elf_types::Elf_WXword symsize, elfcpp::STT type, @@ -2008,7 +2015,8 @@ Symbol_table::do_define_as_constant( return sym; } - if (force_override || Symbol_table::should_override_with_special(oldsym)) + if (force_override + || Symbol_table::should_override_with_special(oldsym, defined)) this->override_with_special(oldsym, sym); if (resolve_oldsym) @@ -2031,14 +2039,14 @@ Symbol_table::define_symbols(const Layout* layout, int count, { Output_section* os = layout->find_output_section(p->output_section); if (os != NULL) - this->define_in_output_data(p->name, NULL, os, p->value, + this->define_in_output_data(p->name, NULL, PREDEFINED, os, p->value, p->size, p->type, p->binding, p->visibility, p->nonvis, p->offset_is_from_end, only_if_ref || p->only_if_ref); else - this->define_as_constant(p->name, NULL, 0, p->size, p->type, - p->binding, p->visibility, p->nonvis, + this->define_as_constant(p->name, NULL, PREDEFINED, 0, p->size, + p->type, p->binding, p->visibility, p->nonvis, only_if_ref || p->only_if_ref, false); } @@ -2057,14 +2065,14 @@ Symbol_table::define_symbols(const Layout* layout, int count, p->segment_flags_set, p->segment_flags_clear); if (os != NULL) - this->define_in_output_segment(p->name, NULL, os, p->value, + this->define_in_output_segment(p->name, NULL, PREDEFINED, os, p->value, p->size, p->type, p->binding, p->visibility, p->nonvis, p->offset_base, only_if_ref || p->only_if_ref); else - this->define_as_constant(p->name, NULL, 0, p->size, p->type, - p->binding, p->visibility, p->nonvis, + this->define_as_constant(p->name, NULL, PREDEFINED, 0, p->size, + p->type, p->binding, p->visibility, p->nonvis, only_if_ref || p->only_if_ref, false); } @@ -2093,7 +2101,7 @@ Symbol_table::define_with_copy_reloc( if (binding == elfcpp::STB_WEAK) binding = elfcpp::STB_GLOBAL; - this->define_in_output_data(csym->name(), csym->version(), + this->define_in_output_data(csym->name(), csym->version(), COPY, posd, value, csym->symsize(), csym->type(), binding, csym->visibility(), csym->nonvis(), diff --git a/gold/symtab.h b/gold/symtab.h index c153150e1b..ed105c7a68 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -1176,6 +1176,23 @@ class Warnings class Symbol_table { public: + // The different places where a symbol definition can come from. + enum Defined + { + // Defined in an object file--the normal case. + OBJECT, + // Defined for a COPY reloc. + COPY, + // Defined on the command line using --defsym. + DEFSYM, + // Defined (so to speak) on the command line using -u. + UNDEFINED, + // Defined in a linker script. + SCRIPT, + // Predefined by the linker. + PREDEFINED, + }; + // COUNT is an estimate of how many symbosl will be inserted in the // symbol table. It's ok to put 0 if you don't know; a correct // guess will just save some CPU by reducing hashtable resizes. @@ -1257,7 +1274,7 @@ class Symbol_table // Define a special symbol based on an Output_data. It is a // multiple definition error if this symbol is already defined. Symbol* - define_in_output_data(const char* name, const char* version, + define_in_output_data(const char* name, const char* version, Defined, Output_data*, uint64_t value, uint64_t symsize, elfcpp::STT type, elfcpp::STB binding, elfcpp::STV visibility, unsigned char nonvis, @@ -1266,7 +1283,7 @@ class Symbol_table // Define a special symbol based on an Output_segment. It is a // multiple definition error if this symbol is already defined. Symbol* - define_in_output_segment(const char* name, const char* version, + define_in_output_segment(const char* name, const char* version, Defined, Output_segment*, uint64_t value, uint64_t symsize, elfcpp::STT type, elfcpp::STB binding, elfcpp::STV visibility, unsigned char nonvis, @@ -1275,7 +1292,7 @@ class Symbol_table // Define a special symbol with a constant value. It is a multiple // definition error if this symbol is already defined. Symbol* - define_as_constant(const char* name, const char* version, + define_as_constant(const char* name, const char* version, Defined, uint64_t value, uint64_t symsize, elfcpp::STT type, elfcpp::STB binding, elfcpp::STV visibility, unsigned char nonvis, bool only_if_ref, @@ -1494,12 +1511,12 @@ class Symbol_table // Whether we should override a symbol, based on flags in // resolve.cc. static bool - should_override(const Symbol*, unsigned int, Object*, bool*); + should_override(const Symbol*, unsigned int, Defined, Object*, bool*); // Report a problem in symbol resolution. static void report_resolve_problem(bool is_error, const char* msg, const Symbol* to, - Object* object); + Defined, Object* object); // Override a symbol. template @@ -1512,7 +1529,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*); + should_override_with_special(const Symbol*, Defined); // Override a symbol with a special symbol. template @@ -1535,7 +1552,8 @@ class Symbol_table // Define a symbol in an Output_data, sized version. template Sized_symbol* - do_define_in_output_data(const char* name, const char* version, Output_data*, + do_define_in_output_data(const char* name, const char* version, Defined, + Output_data*, typename elfcpp::Elf_types::Elf_Addr value, typename elfcpp::Elf_types::Elf_WXword ssize, elfcpp::STT type, elfcpp::STB binding, @@ -1546,7 +1564,7 @@ class Symbol_table template Sized_symbol* do_define_in_output_segment( - const char* name, const char* version, Output_segment* os, + const char* name, const char* version, Defined, Output_segment* os, typename elfcpp::Elf_types::Elf_Addr value, typename elfcpp::Elf_types::Elf_WXword ssize, elfcpp::STT type, elfcpp::STB binding, @@ -1557,7 +1575,7 @@ class Symbol_table template Sized_symbol* do_define_as_constant( - const char* name, const char* version, + const char* name, const char* version, Defined, typename elfcpp::Elf_types::Elf_Addr value, typename elfcpp::Elf_types::Elf_WXword ssize, elfcpp::STT type, elfcpp::STB binding, diff --git a/gold/x86_64.cc b/gold/x86_64.cc index c31949f311..c1597c1306 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -488,6 +488,7 @@ Target_x86_64::got_section(Symbol_table* symtab, Layout* layout) // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, + Symbol_table::PREDEFINED, this->got_plt_, 0, 0, elfcpp::STT_OBJECT, elfcpp::STB_LOCAL, @@ -836,6 +837,7 @@ Target_x86_64::define_tls_base_symbol(Symbol_table* symtab, Layout* layout) { bool is_exec = parameters->options().output_is_executable(); symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL, + Symbol_table::PREDEFINED, tls_segment, 0, 0, elfcpp::STT_TLS, elfcpp::STB_LOCAL, -- cgit v1.2.1