opcodes/
[deliverable/binutils-gdb.git] / gold / symtab.h
index e64fa1ac052225c02e51f6142aba54a0807e0574..9299ea8abe9bb36ab4ab24b3e60fcb43342e6c97 100644 (file)
@@ -1,6 +1,6 @@
 // symtab.h -- the gold symbol table   -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -42,12 +42,14 @@ class Mapfile;
 class Object;
 class Relobj;
 template<int size, bool big_endian>
-class Sized_relobj;
+class Sized_relobj_file;
 template<int size, bool big_endian>
 class Sized_pluginobj;
 class Dynobj;
 template<int size, bool big_endian>
 class Sized_dynobj;
+template<int size, bool big_endian>
+class Sized_incrobj;
 class Versions;
 class Version_script_info;
 class Input_objects;
@@ -60,7 +62,7 @@ class Garbage_collection;
 class Icf;
 
 // The base class of an entry in the symbol table.  The symbol table
-// can have a lot of entries, so we don't want this class to big.
+// can have a lot of entries, so we don't want this class too big.
 // Size dependent fields can be found in the template class
 // Sized_symbol.  Targets may support their own derived classes.
 
@@ -119,6 +121,10 @@ class Symbol
   version() const
   { return this->version_; }
 
+  void
+  clear_version()
+  { this->version_ = NULL; }
+
   // Return whether this version is the default for this symbol name
   // (eg, "foo@@V2" is a default version; "foo@V1" is not).  Only
   // meaningful for versioned symbols.
@@ -134,6 +140,10 @@ class Symbol
   set_is_default()
   { this->is_def_ = true; }
 
+  // Return the symbol's name as name@version (or name@@version).
+  std::string
+  versioned_name() const;
+
   // Return the symbol source.
   Source
   source() const
@@ -532,8 +542,9 @@ class Symbol
   bool
   is_externally_visible() const
   {
-    return (this->visibility_ == elfcpp::STV_DEFAULT
-            || this->visibility_ == elfcpp::STV_PROTECTED);
+    return ((this->visibility_ == elfcpp::STV_DEFAULT
+             || this->visibility_ == elfcpp::STV_PROTECTED)
+           && !this->is_forced_local_);
   }
 
   // Return true if this symbol can be preempted by a definition in
@@ -614,15 +625,20 @@ class Symbol
 
   // When determining whether a reference to a symbol needs a dynamic
   // relocation, we need to know several things about the reference.
-  // These flags may be or'ed together.
+  // These flags may be or'ed together.  0 means that the symbol
+  // isn't referenced at all.
   enum Reference_flags
   {
-    // Reference to the symbol's absolute address.
+    // A reference to the symbol's absolute address.  This includes
+    // references that cause an absolute address to be stored in the GOT.
     ABSOLUTE_REF = 1,
-    // A non-PIC reference.
-    NON_PIC_REF = 2,
-    // A function call.
-    FUNCTION_CALL = 4
+    // A reference that calculates the offset of the symbol from some
+    // anchor point, such as the PC or GOT.
+    RELATIVE_REF = 2,
+    // A TLS-related reference.
+    TLS_REF = 4,
+    // A reference that can always be treated as a function call.
+    FUNCTION_CALL = 8
   };
 
   // Given a direct absolute or pc-relative static relocation against
@@ -653,11 +669,8 @@ class Symbol
       return true;
 
     // A function call that can branch to a local PLT entry does not need
-    // a dynamic relocation.  A non-pic pc-relative function call in a
-    // shared library cannot use a PLT entry.
-    if ((flags & FUNCTION_CALL)
-        && this->has_plt_offset()
-        && !((flags & NON_PIC_REF) && parameters->options().shared()))
+    // a dynamic relocation.
+    if ((flags & FUNCTION_CALL) && this->has_plt_offset())
       return false;
 
     // A reference to any PLT entry in a non-position-independent executable
@@ -678,12 +691,10 @@ class Symbol
   }
 
   // Whether we should use the PLT offset associated with a symbol for
-  // a relocation.  IS_NON_PIC_REFERENCE is true if this is a non-PIC
-  // reloc--the same set of relocs for which we would pass NON_PIC_REF
-  // to the needs_dynamic_reloc function.
+  // a relocation.  FLAGS is a set of Reference_flags.
 
   bool
-  use_plt_offset(bool is_non_pic_reference) const
+  use_plt_offset(int flags) const
   {
     // If the symbol doesn't have a PLT offset, then naturally we
     // don't want to use it.
@@ -696,10 +707,7 @@ class Symbol
 
     // If we are going to generate a dynamic relocation, then we will
     // wind up using that, so no need to use the PLT entry.
-    if (this->needs_dynamic_reloc(FUNCTION_CALL
-                                 | (is_non_pic_reference
-                                    ? NON_PIC_REF
-                                    : 0)))
+    if (this->needs_dynamic_reloc(flags))
       return false;
 
     // If the symbol is from a dynamic object, we need to use the PLT
@@ -713,10 +721,10 @@ class Symbol
        && (this->is_undefined() || this->is_preemptible()))
       return true;
 
-    // If this is a weak undefined symbol, we need to use the PLT
-    // entry; the symbol may be defined by a library loaded at
-    // runtime.
-    if (this->is_weak_undefined())
+    // If this is a call to a weak undefined symbol, we need to use
+    // the PLT entry; the symbol may be defined by a library loaded
+    // at runtime.
+    if ((flags & FUNCTION_CALL) && this->is_weak_undefined())
       return true;
 
     // Otherwise we can use the regular definition.
@@ -738,7 +746,7 @@ class Symbol
       return true;
 
     // A reference to a symbol defined in a dynamic object or to a
-    // symbol that is preemptible can not use a RELATIVE relocaiton.
+    // symbol that is preemptible can not use a RELATIVE relocation.
     if (this->is_from_dynobj()
         || this->is_undefined()
         || this->is_preemptible())
@@ -798,12 +806,22 @@ class Symbol
   bool
   may_need_copy_reloc() const
   {
-    return (!parameters->options().shared()
+    return (!parameters->options().output_is_position_independent()
            && parameters->options().copyreloc()
            && this->is_from_dynobj()
            && !this->is_func());
   }
 
+  // Return true if this symbol was predefined by the linker.
+  bool
+  is_predefined() const
+  { return this->is_predefined_; }
+
+  // Return true if this is a C++ vtable symbol.
+  bool
+  is_cxx_vtable() const
+  { return is_prefix_of("_ZTV", this->name_); }
+
  protected:
   // Instances of this class should always be created at a specific
   // size.
@@ -829,7 +847,8 @@ class Symbol
   void
   init_base_output_data(const char* name, const char* version, Output_data*,
                        elfcpp::STT, elfcpp::STB, elfcpp::STV,
-                       unsigned char nonvis, bool offset_is_from_end);
+                       unsigned char nonvis, bool offset_is_from_end,
+                       bool is_predefined);
 
   // Initialize fields for an Output_segment.
   void
@@ -837,13 +856,14 @@ class Symbol
                           Output_segment* os, elfcpp::STT type,
                           elfcpp::STB binding, elfcpp::STV visibility,
                           unsigned char nonvis,
-                          Segment_offset_base offset_base);
+                          Segment_offset_base offset_base,
+                          bool is_predefined);
 
   // Initialize fields for a constant.
   void
   init_base_constant(const char* name, const char* version, elfcpp::STT type,
                     elfcpp::STB binding, elfcpp::STV visibility,
-                    unsigned char nonvis);
+                    unsigned char nonvis, bool is_predefined);
 
   // Initialize fields for an undefined symbol.
   void
@@ -982,7 +1002,12 @@ class Symbol
   // index, not one of the special codes from SHN_LORESERVE to
   // SHN_HIRESERVE (bit 29).
   bool is_ordinary_shndx_ : 1;
-  // True if we've seen this symbol in a real ELF object (bit 30).
+  // True if we've seen this symbol in a "real" ELF object (bit 30).
+  // If the symbol has been seen in a relocatable, non-IR, object file,
+  // it's known to be referenced from outside the IR.  A reference from
+  // a dynamic object doesn't count as a "real" ELF, and we'll simply
+  // mark the symbol as "visible" from outside the IR.  The compiler
+  // can use this distinction to guide its handling of COMDAT symbols.
   bool in_real_elf_ : 1;
   // True if this symbol is defined in a section which was discarded
   // (bit 31).
@@ -992,6 +1017,8 @@ class Symbol
   // True if this symbol was a weak undef resolved by a dynamic def
   // (bit 33).
   bool undef_binding_weak_ : 1;
+  // True if this symbol is a predefined linker symbol (bit 34).
+  bool is_predefined_ : 1;
 };
 
 // The parts of a symbol which are size specific.  Using a template
@@ -1021,20 +1048,20 @@ class Sized_symbol : public Symbol
   init_output_data(const char* name, const char* version, Output_data*,
                   Value_type value, Size_type symsize, elfcpp::STT,
                   elfcpp::STB, elfcpp::STV, unsigned char nonvis,
-                  bool offset_is_from_end);
+                  bool offset_is_from_end, bool is_predefined);
 
   // Initialize fields for an Output_segment.
   void
   init_output_segment(const char* name, const char* version, Output_segment*,
                      Value_type value, Size_type symsize, elfcpp::STT,
                      elfcpp::STB, elfcpp::STV, unsigned char nonvis,
-                     Segment_offset_base offset_base);
+                     Segment_offset_base offset_base, bool is_predefined);
 
   // Initialize fields for a constant.
   void
   init_constant(const char* name, const char* version, Value_type value,
                Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV,
-               unsigned char nonvis);
+               unsigned char nonvis, bool is_predefined);
 
   // Initialize fields for an undefined symbol.
   void
@@ -1162,6 +1189,25 @@ struct Define_symbol_in_segment
   bool only_if_ref;
 };
 
+// Specify an object/section/offset location.  Used by ODR code.
+
+struct Symbol_location
+{
+  // Object where the symbol is defined.
+  Object* object;
+  // Section-in-object where the symbol is defined.
+  unsigned int shndx;
+  // For relocatable objects, offset-in-section where the symbol is defined.
+  // For dynamic objects, address where the symbol is defined.
+  off_t offset;
+  bool operator==(const Symbol_location& that) const
+  {
+    return (this->object == that.object
+           && this->shndx == that.shndx
+           && this->offset == that.offset);
+  }
+};
+
 // This class manages warnings.  Warnings are a GNU extension.  When
 // we see a section named .gnu.warning.SYM in an object file, and if
 // we wind using the definition of SYM from that object file, then we
@@ -1251,6 +1297,9 @@ class Symbol_table
     SCRIPT,
     // Predefined by the linker.
     PREDEFINED,
+    // Defined by the linker during an incremental base link, but not
+    // a predefined symbol (e.g., common, defined in script).
+    INCREMENTAL_BASE,
   };
 
   // The order in which we sort common symbols.
@@ -1261,7 +1310,7 @@ class Symbol_table
     SORT_COMMONS_BY_ALIGNMENT_ASCENDING
   };
 
-  // COUNT is an estimate of how many symbosl will be inserted in the
+  // COUNT is an estimate of how many symbols 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.
   Symbol_table(unsigned int count, const Version_script_info& version_script);
@@ -1292,10 +1341,9 @@ class Symbol_table
   void
   gc_mark_undef_symbols(Layout*);
 
-  // During garbage collection, this ensures externally visible symbols
-  // are not treated as garbage while building shared objects.
+  // This tells garbage collection that this symbol is referenced.
   void
-  gc_mark_symbol_for_shlib(Symbol* sym);
+  gc_mark_symbol(Symbol* sym);
 
   // During garbage collection, this keeps sections that correspond to 
   // symbols seen in dynamic objects.
@@ -1310,11 +1358,11 @@ class Symbol_table
   // *DEFINED to the number of defined symbols.
   template<int size, bool big_endian>
   void
-  add_from_relobj(Sized_relobj<size, big_endian>* relobj,
+  add_from_relobj(Sized_relobj_file<size, big_endian>* relobj,
                  const unsigned char* syms, size_t count,
                  size_t symndx_offset, const char* sym_names,
                  size_t sym_name_size,
-                 typename Sized_relobj<size, big_endian>::Symbols*,
+                 typename Sized_relobj_file<size, big_endian>::Symbols*,
                  size_t* defined);
 
   // Add one external symbol from the plugin object OBJ to the symbol table.
@@ -1336,9 +1384,16 @@ class Symbol_table
                  const char* sym_names, size_t sym_name_size,
                  const unsigned char* versym, size_t versym_size,
                  const std::vector<const char*>*,
-                 typename Sized_relobj<size, big_endian>::Symbols*,
+                 typename Sized_relobj_file<size, big_endian>::Symbols*,
                  size_t* defined);
 
+  // Add one external symbol from the incremental object OBJ to the symbol
+  // table.  Returns a pointer to the resolved symbol in the symbol table.
+  template<int size, bool big_endian>
+  Sized_symbol<size>*
+  add_from_incrobj(Object* obj, const char* name,
+                  const char* ver, elfcpp::Sym<size, big_endian>* sym);
+
   // Define a special symbol based on an Output_data.  It is a
   // multiple definition error if this symbol is already defined.
   Symbol*
@@ -1469,12 +1524,17 @@ class Symbol_table
   finalize(off_t off, off_t dynoff, size_t dyn_global_index, size_t dyncount,
           Stringpool* pool, unsigned int* plocal_symcount);
 
+  // Set the final file offset of the symbol table.
+  void
+  set_file_offset(off_t off)
+  { this->offset_ = off; }
+
   // Status code of Symbol_table::compute_final_value.
   enum Compute_final_value_status
   {
     // No error.
     CFVS_OK,
-    // Unspported symbol section.
+    // Unsupported symbol section.
     CFVS_UNSUPPORTED_SYMBOL_SECTION,
     // No output section.
     CFVS_NO_OUTPUT_SECTION
@@ -1544,10 +1604,14 @@ class Symbol_table
 
   typedef std::pair<Stringpool::Key, Stringpool::Key> Symbol_table_key;
 
+  // The hash function.  The key values are Stringpool keys.
   struct Symbol_table_hash
   {
-    size_t
-    operator()(const Symbol_table_key&) const;
+    inline size_t
+    operator()(const Symbol_table_key& key) const
+    {
+      return key.first ^ key.second;
+    }
   };
 
   struct Symbol_table_eq
@@ -1559,6 +1623,20 @@ class Symbol_table
   typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
                        Symbol_table_eq> Symbol_table_type;
 
+  // A map from symbol name (as a pointer into the namepool) to all
+  // the locations the symbols is (weakly) defined (and certain other
+  // conditions are met).  This map will be used later to detect
+  // possible One Definition Rule (ODR) violations.
+  struct Symbol_location_hash
+  {
+    size_t operator()(const Symbol_location& loc) const
+    { return reinterpret_cast<uintptr_t>(loc.object) ^ loc.offset ^ loc.shndx; }
+  };
+
+  typedef Unordered_map<const char*,
+                        Unordered_set<Symbol_location, Symbol_location_hash> >
+  Odr_map;
+
   // Make FROM a forwarder symbol to TO.
   void
   make_forwarder(Symbol* from, Symbol* to);
@@ -1603,7 +1681,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
@@ -1621,7 +1700,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>
@@ -1706,6 +1785,12 @@ class Symbol_table
   do_allocate_commons_list(Layout*, Commons_section_type, Commons_type*,
                           Mapfile*, Sort_commons_order);
 
+  // Returns all of the lines attached to LOC, not just the one the
+  // instruction actually came from.  This helps the ODR checker avoid
+  // false positives.
+  static std::vector<std::string>
+  linenos_from_loc(const Task* task, const Symbol_location& loc);
+
   // Implement detect_odr_violations.
   template<int size, bool big_endian>
   void
@@ -1759,33 +1844,6 @@ class Symbol_table
   // they are defined.
   typedef Unordered_map<const Symbol*, Dynobj*> Copied_symbol_dynobjs;
 
-  // A map from symbol name (as a pointer into the namepool) to all
-  // the locations the symbols is (weakly) defined (and certain other
-  // conditions are met).  This map will be used later to detect
-  // possible One Definition Rule (ODR) violations.
-  struct Symbol_location
-  {
-    Object* object;         // Object where the symbol is defined.
-    unsigned int shndx;     // Section-in-object where the symbol is defined.
-    off_t offset;           // Offset-in-section where the symbol is defined.
-    bool operator==(const Symbol_location& that) const
-    {
-      return (this->object == that.object
-              && this->shndx == that.shndx
-              && this->offset == that.offset);
-    }
-  };
-
-  struct Symbol_location_hash
-  {
-    size_t operator()(const Symbol_location& loc) const
-    { return reinterpret_cast<uintptr_t>(loc.object) ^ loc.offset ^ loc.shndx; }
-  };
-
-  typedef Unordered_map<const char*,
-                        Unordered_set<Symbol_location, Symbol_location_hash> >
-  Odr_map;
-
   // We increment this every time we see a new undefined symbol, for
   // use in archive groups.
   size_t saw_undefined_;
This page took 0.028407 seconds and 4 git commands to generate.