OSDN Git Service

* symtab.h (class Symbol_table): Add enum Defined.
authorian <ian>
Tue, 29 Dec 2009 09:31:48 +0000 (09:31 +0000)
committerian <ian>
Tue, 29 Dec 2009 09:31:48 +0000 (09:31 +0000)
* 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.

14 files changed:
gold/ChangeLog
gold/arm.cc
gold/dynobj.cc
gold/i386.cc
gold/layout.cc
gold/powerpc.cc
gold/resolve.cc
gold/script-sections.cc
gold/script.cc
gold/script.h
gold/sparc.cc
gold/symtab.cc
gold/symtab.h
gold/x86_64.cc

index 3292a51..ed7f31d 100644 (file)
@@ -1,5 +1,29 @@
 2009-12-28  Ian Lance Taylor  <iant@google.com>
 
+       * 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  <iant@google.com>
+
        * gold.cc (queue_middle_tasks): Fix formatting.
        * object.cc (Relobj::is_section_name_included): Likewise.
 
index b02afbe..afe1bc0 100644 (file)
@@ -2611,6 +2611,7 @@ Target_arm<big_endian>::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<big_endian>::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);
 
index 1b0dad9..ebb5f33 100644 (file)
@@ -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,
index bf7c695..43edd65 100644 (file)
@@ -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,
index 914de92..17477bb 100644 (file)
@@ -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
index bd5571c..f27a9f1 100644 (file)
@@ -738,6 +738,7 @@ Target_powerpc<size, big_endian>::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<size, big_endian>::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<size, big_endian>::scan_relocs(
                                                         | elfcpp::SHF_WRITE,
                                                         sdata, false);
     symtab->define_in_output_data("_SDA_BASE_", NULL,
+                                 Symbol_table::PREDEFINED,
                                  os,
                                  32768, 0,
                                  elfcpp::STT_OBJECT,
index 89b10b9..d32b2b9 100644 (file)
@@ -304,7 +304,7 @@ Symbol_table::resolve(Sized_symbol<size>* to,
 
   bool adjust_common_sizes;
   typename Sized_symbol<size>::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<size>* 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<size>* 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;
index f38cbd0..e106435 100644 (file)
@@ -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.
index 8839213..fb35fb8 100644 (file)
@@ -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<Parser_closure*>(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();
 }
 
index 755bb79..7129565 100644 (file)
@@ -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
index 8047a11..9e1e666 100644 (file)
@@ -1031,6 +1031,7 @@ Target_sparc<size, big_endian>::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<size, big_endian>::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,
index 8cd4a40..d8461a7 100644 (file)
@@ -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<size>*
 Symbol_table::do_define_in_output_data(
     const char* name,
     const char* version,
+    Defined defined,
     Output_data* od,
     typename elfcpp::Elf_types<size>::Elf_Addr value,
     typename elfcpp::Elf_types<size>::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<size>*
 Symbol_table::do_define_in_output_segment(
     const char* name,
     const char* version,
+    Defined defined,
     Output_segment* os,
     typename elfcpp::Elf_types<size>::Elf_Addr value,
     typename elfcpp::Elf_types<size>::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<size>*
 Symbol_table::do_define_as_constant(
     const char* name,
     const char* version,
+    Defined defined,
     typename elfcpp::Elf_types<size>::Elf_Addr value,
     typename elfcpp::Elf_types<size>::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(),
index c153150..ed105c7 100644 (file)
@@ -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<int size, bool big_endian>
@@ -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<int size>
@@ -1535,7 +1552,8 @@ class Symbol_table
   // Define a symbol in an Output_data, sized version.
   template<int size>
   Sized_symbol<size>*
-  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<size>::Elf_Addr value,
                           typename elfcpp::Elf_types<size>::Elf_WXword ssize,
                           elfcpp::STT type, elfcpp::STB binding,
@@ -1546,7 +1564,7 @@ class Symbol_table
   template<int size>
   Sized_symbol<size>*
   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<size>::Elf_Addr value,
     typename elfcpp::Elf_types<size>::Elf_WXword ssize,
     elfcpp::STT type, elfcpp::STB binding,
@@ -1557,7 +1575,7 @@ class Symbol_table
   template<int size>
   Sized_symbol<size>*
   do_define_as_constant(
-    const char* name, const char* version,
+    const char* name, const char* version, Defined,
     typename elfcpp::Elf_types<size>::Elf_Addr value,
     typename elfcpp::Elf_types<size>::Elf_WXword ssize,
     elfcpp::STT type, elfcpp::STB binding,
index c31949f..c1597c1 100644 (file)
@@ -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,