* configure.tgt (powerpc64-*): Fix targ_obj.
[binutils-gdb.git] / gold / symtab.h
index 9afdfe92996bcbde8e2779fe67ca17e57fd8b21f..cfd0c73d42313451596012328dd60ca1b4408864 100644 (file)
@@ -43,6 +43,8 @@ class Object;
 class Relobj;
 template<int size, bool big_endian>
 class Sized_relobj;
+template<int size, bool big_endian>
+class Sized_pluginobj;
 class Dynobj;
 template<int size, bool big_endian>
 class Sized_dynobj;
@@ -273,6 +275,18 @@ class Symbol
   set_in_dyn()
   { this->in_dyn_ = true; }
 
+  // Return whether this symbol has been seen in a real ELF object.
+  // (IN_REG will return TRUE if the symbol has been seen in either
+  // a real ELF object or an object claimed by a plugin.)
+  bool
+  in_real_elf() const
+  { return this->in_real_elf_; }
+
+  // Mark this symbol as having been seen in a real ELF object.
+  void
+  set_in_real_elf()
+  { this->in_real_elf_ = true; }
+
   // Return the index of this symbol in the output file symbol table.
   // A value of -1U means that this symbol is not going into the
   // output file.  This starts out as zero, and is set to a non-zero
@@ -577,6 +591,48 @@ class Symbol
     return false;
   }
 
+  // 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.
+
+  bool
+  use_plt_offset(bool is_non_pic_reference) 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;
+
+    // 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)))
+      return false;
+
+    // If the symbol is from a dynamic object, we need to use the PLT
+    // entry.
+    if (this->is_from_dynobj())
+      return true;
+
+    // If we are generating a shared object, and this symbol is
+    // undefined or preemptible, we need to use the PLT entry.
+    if (parameters->options().shared()
+       && (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())
+      return true;
+
+    // Otherwise we can use the regular definition.
+    return false;
+  }
+
   // Given a direct absolute static relocation against
   // the global symbol, where a dynamic relocation is needed, this
   // function returns whether a relative dynamic relocation can be used.
@@ -829,8 +885,10 @@ class Symbol
   bool is_forced_local_ : 1;
   // True if the field u_.from_object.shndx is an ordinary section
   // index, not one of the special codes from SHN_LORESERVE to
-  // SHN_HIRESERVE.
+  // SHN_HIRESERVE (bit 31).
   bool is_ordinary_shndx_ : 1;
+  // True if we've seen this symbol in a real ELF object.
+  bool in_real_elf_ : 1;
 };
 
 // The parts of a symbol which are size specific.  Using a template
@@ -1097,6 +1155,14 @@ class Symbol_table
                  typename Sized_relobj<size, big_endian>::Symbols*,
                  size_t* defined);
 
+  // Add one external symbol from the plugin object OBJ to the symbol table.
+  // Returns a pointer to the resolved symbol in the symbol table.
+  template<int size, bool big_endian>
+  Symbol*
+  add_from_pluginobj(Sized_pluginobj<size, big_endian>* obj,
+                     const char* name, const char* ver,
+                     elfcpp::Sym<size, big_endian>* sym);
+
   // Add COUNT dynamic symbols from the dynamic object DYNOBJ to the
   // symbol table.  SYMS is the symbols.  SYM_NAMES is their names.
   // SYM_NAME_SIZE is the size of SYM_NAMES.  The other parameters are
@@ -1292,8 +1358,7 @@ class Symbol_table
 
   template<int size, bool big_endian>
   void
-  resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
-          const char* version);
+  resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
 
   // Record that a symbol is forced to be local by a version script.
   void