daily update
[deliverable/binutils-gdb.git] / gold / symtab.h
index 8ccbca9a4107398876bdf3f2e0e4fdacd7daf923..c0ae35811d0cd6d5d473266e9d5da92b875ac91a 100644 (file)
@@ -582,9 +582,6 @@ class Symbol
   }
 
   // Return true if this symbol is a function that needs a PLT entry.
-  // If the symbol is defined in a dynamic object or if it is subject
-  // to pre-emption, we need to make a PLT entry. If we're doing a
-  // static link or a -pie link, we don't create PLT entries.
   bool
   needs_plt_entry() const
   {
@@ -592,25 +589,45 @@ class Symbol
     if (this->is_undefined() && !parameters->options().shared())
       return false;
 
-    return (!parameters->doing_static_link()
-           && !parameters->options().pie()
-            && this->is_func()
-            && (this->is_from_dynobj()
-                || this->is_undefined()
-                || this->is_preemptible()));
+    // An STT_GNU_IFUNC symbol always needs a PLT entry, even when
+    // doing a static link.
+    if (this->type() == elfcpp::STT_GNU_IFUNC)
+      return true;
+
+    // We only need a PLT entry for a function.
+    if (!this->is_func())
+      return false;
+
+    // If we're doing a static link or a -pie link, we don't create
+    // PLT entries.
+    if (parameters->doing_static_link()
+       || parameters->options().pie())
+      return false;
+
+    // We need a PLT entry if the function is defined in a dynamic
+    // object, or is undefined when building a shared object, or if it
+    // is subject to pre-emption.
+    return (this->is_from_dynobj()
+           || this->is_undefined()
+           || this->is_preemptible());
   }
 
   // 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
@@ -641,11 +658,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
@@ -666,24 +680,23 @@ 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.
     if (!this->has_plt_offset())
       return false;
 
+    // For a STT_GNU_IFUNC symbol we always have to use the PLT entry.
+    if (this->type() == elfcpp::STT_GNU_IFUNC)
+      return true;
+
     // 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
@@ -697,10 +710,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.
@@ -722,7 +735,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())
@@ -782,7 +795,7 @@ 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());
@@ -805,7 +818,7 @@ class Symbol
   // index rather than a special code.
   template<int size, bool big_endian>
   void
-  init_base_object(const char *name, const char* version, Object* object,
+  init_base_object(const charname, const char* version, Object* object,
                   const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
                   bool is_ordinary);
 
@@ -996,7 +1009,7 @@ class Sized_symbol : public Symbol
   // index rather than a special code.
   template<bool big_endian>
   void
-  init_object(const char *name, const char* version, Object* object,
+  init_object(const charname, const char* version, Object* object,
              const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
              bool is_ordinary);
 
@@ -1245,7 +1258,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);
@@ -1451,14 +1464,14 @@ class Symbol_table
   // local symbols.
   off_t
   finalize(off_t off, off_t dynoff, size_t dyn_global_index, size_t dyncount,
-          Stringpool* pool, unsigned int *plocal_symcount);
+          Stringpool* pool, unsigned intplocal_symcount);
 
   // 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
@@ -1528,10 +1541,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
@@ -1550,8 +1567,8 @@ class Symbol_table
   // Add a symbol.
   template<int size, bool big_endian>
   Sized_symbol<size>*
-  add_from_object(Object*, const char *name, Stringpool::Key name_key,
-                 const char *version, Stringpool::Key version_key,
+  add_from_object(Object*, const charname, Stringpool::Key name_key,
+                 const charversion, Stringpool::Key version_key,
                  bool def, const elfcpp::Sym<size, big_endian>& sym,
                  unsigned int st_shndx, bool is_ordinary,
                  unsigned int orig_st_shndx);
This page took 0.02545 seconds and 4 git commands to generate.