*** empty log message ***
[deliverable/binutils-gdb.git] / gold / symtab.h
index f544e0664df2c8dd6347b2f99f44f4ed46d835a7..f7a5c4c65039d2532308a9f3e14316ea085170b0 100644 (file)
@@ -6,7 +6,6 @@
 #include <string>
 #include <utility>
 #include <vector>
-#include <cassert>
 
 #include "elfcpp.h"
 #include "stringpool.h"
@@ -20,8 +19,13 @@ namespace gold
 
 class Object;
 class Relobj;
+template<int size, bool big_endian>
+class Sized_relobj;
 class Dynobj;
+template<int size, bool big_endian>
+class Sized_dynobj;
 class Output_data;
+class Output_section;
 class Output_segment;
 class Output_file;
 class Target;
@@ -86,17 +90,17 @@ class Symbol
   Object*
   object() const
   {
-    assert(this->source_ == FROM_OBJECT);
+    gold_assert(this->source_ == FROM_OBJECT);
     return this->u_.from_object.object;
   }
 
   // Return the index of the section in the input relocatable or
   // dynamic object file.
   unsigned int
-  shnum() const
+  shndx() const
   {
-    assert(this->source_ == FROM_OBJECT);
-    return this->u_.from_object.shnum;
+    gold_assert(this->source_ == FROM_OBJECT);
+    return this->u_.from_object.shndx;
   }
 
   // Return the output data section with which this symbol is
@@ -105,7 +109,7 @@ class Symbol
   Output_data*
   output_data() const
   {
-    assert(this->source_ == IN_OUTPUT_DATA);
+    gold_assert(this->source_ == IN_OUTPUT_DATA);
     return this->u_.in_output_data.output_data;
   }
 
@@ -114,7 +118,7 @@ class Symbol
   bool
   offset_is_from_end() const
   {
-    assert(this->source_ == IN_OUTPUT_DATA);
+    gold_assert(this->source_ == IN_OUTPUT_DATA);
     return this->u_.in_output_data.offset_is_from_end;
   }
 
@@ -124,7 +128,7 @@ class Symbol
   Output_segment*
   output_segment() const
   {
-    assert(this->source_ == IN_OUTPUT_SEGMENT);
+    gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
     return this->u_.in_output_segment.output_segment;
   }
 
@@ -133,7 +137,7 @@ class Symbol
   Segment_offset_base
   offset_base() const
   {
-    assert(this->source_ == IN_OUTPUT_SEGMENT);
+    gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
     return this->u_.in_output_segment.offset_base;
   }
 
@@ -169,16 +173,74 @@ class Symbol
   set_forwarder()
   { this->is_forwarder_ = true; }
 
-  // Return whether this symbol was ever seen in a dynamic object.
+  // Return whether this symbol needs an entry in the dynamic symbol
+  // table.
   bool
-  in_dyn() const
-  { return this->in_dyn_; }
+  needs_dynsym_entry() const
+  { return this->needs_dynsym_entry_; }
+
+  // Mark this symbol as needing an entry in the dynamic symbol table.
+  void
+  set_needs_dynsym_entry()
+  { this->needs_dynsym_entry_ = true; }
 
   // Mark this symbol as having been seen in a dynamic object.
   void
   set_in_dyn()
   { this->in_dyn_ = 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
+  // value by Symbol_table::finalize.  It is an error to ask for the
+  // symbol table index before it has been set.
+  unsigned int
+  symtab_index() const
+  {
+    gold_assert(this->symtab_index_ != 0);
+    return this->symtab_index_;
+  }
+
+  // Set the index of the symbol in the output file symbol table.
+  void
+  set_symtab_index(unsigned int index)
+  {
+    gold_assert(index != 0);
+    this->symtab_index_ = index;
+  }
+
+  // Return whether this symbol already has an index in the output
+  // file symbol table.
+  bool
+  has_symtab_index() const
+  { return this->symtab_index_ != 0; }
+
+  // Return the index of this symbol in the dynamic symbol table.  A
+  // value of -1U means that this symbol is not going into the dynamic
+  // symbol table.  This starts out as zero, and is set to a non-zero
+  // during Layout::finalize.  It is an error to ask for the dynamic
+  // symbol table index before it has been set.
+  unsigned int
+  dynsym_index() const
+  {
+    gold_assert(this->dynsym_index_ != 0);
+    return this->dynsym_index_;
+  }
+
+  // Set the index of the symbol in the dynamic symbol table.
+  void
+  set_dynsym_index(unsigned int index)
+  {
+    gold_assert(index != 0);
+    this->dynsym_index_ = index;
+  }
+
+  // Return whether this symbol already has an index in the dynamic
+  // symbol table.
+  bool
+  has_dynsym_index() const
+  { return this->dynsym_index_ != 0; }
+
   // Return whether this symbol has an entry in the GOT section.
   bool
   has_got_offset() const
@@ -188,7 +250,7 @@ class Symbol
   unsigned int
   got_offset() const
   {
-    assert(this->has_got_offset());
+    gold_assert(this->has_got_offset());
     return this->got_offset_;
   }
 
@@ -200,14 +262,36 @@ class Symbol
     this->got_offset_ = got_offset;
   }
 
-  // Return whether this symbol is resolved locally.  This is always
-  // true when linking statically.  It is true for a symbol defined in
-  // this object when using -Bsymbolic.  It is true for a symbol
-  // marked local in a version file.  FIXME: This needs to be
-  // completed.
+  // Return whether this symbol has an entry in the PLT section.
+  bool
+  has_plt_offset() const
+  { return this->has_plt_offset_; }
+
+  // Return the offset into the PLT section of this symbol.
+  unsigned int
+  plt_offset() const
+  {
+    gold_assert(this->has_plt_offset());
+    return this->plt_offset_;
+  }
+
+  // Set the PLT offset of this symbol.
+  void
+  set_plt_offset(unsigned int plt_offset)
+  {
+    this->has_plt_offset_ = true;
+    this->plt_offset_ = plt_offset;
+  }
+
+  // Return true if the final value of this symbol is known at link
+  // time.
   bool
-  is_resolved_locally() const
-  { return !this->in_dyn_; }
+  final_value_is_known(const General_options* options) const
+  {
+    if (options->is_shared())
+      return false;
+    return this->source_ != FROM_OBJECT || !this->object()->is_dynamic();
+  }
 
   // Return whether this is a defined symbol (not undefined or
   // common).
@@ -215,15 +299,24 @@ class Symbol
   is_defined() const
   {
     return (this->source_ != FROM_OBJECT
-           || (this->u_.from_object.shnum != elfcpp::SHN_UNDEF
-               && this->u_.from_object.shnum != elfcpp::SHN_COMMON));
+           || (this->shndx() != elfcpp::SHN_UNDEF
+               && this->shndx() != elfcpp::SHN_COMMON));
+  }
+
+  // Return whether this symbol is defined in a dynamic object.
+  bool
+  is_defined_in_dynobj() const
+  {
+    return (this->source_ == FROM_OBJECT
+           && this->object()->is_dynamic()
+           && this->is_defined());
   }
 
   // Return whether this is an undefined symbol.
   bool
   is_undefined() const
   {
-    return this->source_ == FROM_OBJECT && this->shnum() == elfcpp::SHN_UNDEF;
+    return this->source_ == FROM_OBJECT && this->shndx() == elfcpp::SHN_UNDEF;
   }
 
   // Return whether this is a common symbol.
@@ -231,7 +324,7 @@ class Symbol
   is_common() const
   {
     return (this->source_ == FROM_OBJECT
-           && (this->u_.from_object.shnum == elfcpp::SHN_COMMON
+           && (this->shndx() == elfcpp::SHN_COMMON
                || this->type_ == elfcpp::STT_COMMON));
   }
 
@@ -304,7 +397,7 @@ class Symbol
       // seen.
       Object* object;
       // Section number in object_ in which symbol is defined.
-      unsigned int shnum;
+      unsigned int shndx;
     } from_object;
 
     // This struct is used if SOURCE_ == IN_OUTPUT_DATA.
@@ -330,9 +423,27 @@ class Symbol
     } in_output_segment;
   } u_;
 
+  // The index of this symbol in the output file.  If the symbol is
+  // not going into the output file, this value is -1U.  This field
+  // starts as always holding zero.  It is set to a non-zero value by
+  // Symbol_table::finalize.
+  unsigned int symtab_index_;
+
+  // The index of this symbol in the dynamic symbol table.  If the
+  // symbol is not going into the dynamic symbol table, this value is
+  // -1U.  This field starts as always holding zero.  It is set to a
+  // non-zero value during Layout::finalize.
+  unsigned int dynsym_index_;
+
   // If this symbol has an entry in the GOT section (has_got_offset_
-  // is true), this is the offset.
+  // is true), this is the offset from the start of the GOT section.
   unsigned int got_offset_;
+
+  // If this symbol has an entry in the PLT section (has_plt_offset_
+  // is true), then this is the offset from the start of the PLT
+  // section.
+  unsigned int plt_offset_;
+
   // Symbol type.
   elfcpp::STT type_ : 4;
   // Symbol binding.
@@ -356,10 +467,14 @@ class Symbol
   // It forwards to the symbol found in the forwarders_ map of
   // Symbol_table.
   bool is_forwarder_ : 1;
+  // True if this symbol needs to be in the dynamic symbol table.
+  bool needs_dynsym_entry_ : 1;
   // True if we've seen this symbol in a dynamic object.
   bool in_dyn_ : 1;
   // True if the symbol has an entry in the GOT section.
   bool has_got_offset_ : 1;
+  // True if the symbol has an entry in the PLT section.
+  bool has_plt_offset_ : 1;
   // True if there is a warning for this symbol.
   bool has_warning_ : 1;
 };
@@ -544,7 +659,7 @@ class Warnings
 
   // Issue a warning for a reference to SYM at LOCATION.
   void
-  issue_warning(Symbol* sym, const std::string& location) const;
+  issue_warning(const Symbol* sym, const std::string& location) const;
 
  private:
   Warnings(const Warnings&);
@@ -592,16 +707,29 @@ class Symbol_table
 
   ~Symbol_table();
 
-  // Add COUNT external symbols from the relocatable object OBJECT to
+  // Add COUNT external symbols from the relocatable object RELOBJ to
   // the symbol table.  SYMS is the symbols, SYM_NAMES is their names,
   // SYM_NAME_SIZE is the size of SYM_NAMES.  This sets SYMPOINTERS to
   // point to the symbols in the symbol table.
   template<int size, bool big_endian>
   void
-  add_from_object(Relobj* object, const unsigned char* syms,
-                 size_t count, const char* sym_names, size_t sym_name_size,
+  add_from_relobj(Sized_relobj<size, big_endian>* relobj,
+                 const unsigned char* syms, size_t count,
+                 const char* sym_names, size_t sym_name_size,
                  Symbol** sympointers);
 
+  // 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
+  // symbol version data.
+  template<int size, bool big_endian>
+  void
+  add_from_dynobj(Sized_dynobj<size, big_endian>* dynobj,
+                 const unsigned char* syms, size_t count,
+                 const char* sym_names, size_t sym_name_size,
+                 const unsigned char* versym, size_t versym_size,
+                 const std::vector<const char*>*);
+
   // Define a special symbol.
   template<int size, bool big_endian>
   Sized_symbol<size>*
@@ -650,9 +778,9 @@ class Symbol_table
 
   // Return the real symbol associated with the forwarder symbol FROM.
   Symbol*
-  resolve_forwards(Symbol* from) const;
+  resolve_forwards(const Symbol* from) const;
 
-  // Return the size of the symbols in the table.
+  // Return the bitsize (32 or 64) of the symbols in the table.
   int
   get_size() const
   { return this->size_; }
@@ -683,30 +811,49 @@ class Symbol_table
   // Canonicalize a symbol name for use in the hash table.
   const char*
   canonicalize_name(const char* name)
-  { return this->namepool_.add(name); }
+  { return this->namepool_.add(name, NULL); }
 
   // Possibly issue a warning for a reference to SYM at LOCATION which
   // is in OBJ.
   void
-  issue_warning(Symbol* sym, const std::string& location) const
+  issue_warning(const Symbol* sym, const std::string& location) const
   { this->warnings_.issue_warning(sym, location); }
 
+  // Set the dynamic symbol indexes.  INDEX is the index of the first
+  // global dynamic symbol.  Pointers to the symbols are stored into
+  // the vector.  The names are stored into the Stringpool.  This
+  // returns an updated dynamic symbol index.
+  unsigned int
+  set_dynsym_indexes(unsigned int index, std::vector<Symbol*>*,
+                    Stringpool*);
+
   // Finalize the symbol table after we have set the final addresses
-  // of all the input sections.  This sets the final symbol values and
-  // adds the names to *POOL.  It records the file offset OFF, and
-  // returns the new file offset.
+  // of all the input sections.  This sets the final symbol indexes,
+  // values and adds the names to *POOL.  INDEX is the index of the
+  // first global symbol.  OFF is the file offset of the global symbol
+  // table, DYNOFF is the offset of the globals in the dynamic symbol
+  // table, DYN_GLOBAL_INDEX is the index of the first global dynamic
+  // symbol, and DYNCOUNT is the number of global dynamic symbols.
+  // This records the parameters, and returns the new file offset.
   off_t
-  finalize(off_t, Stringpool*);
+  finalize(unsigned int index, off_t off, off_t dynoff,
+          size_t dyn_global_index, size_t dyncount, Stringpool* pool);
 
   // Write out the global symbols.
   void
-  write_globals(const Target*, const Stringpool*, Output_file*) const;
+  write_globals(const Target*, const Stringpool*, const Stringpool*,
+               Output_file*) const;
+
+  // Write out a section symbol.  Return the updated offset.
+  void
+  write_section_symbol(const Target*, const Output_section*, Output_file*,
+                      off_t) const;
 
  private:
   Symbol_table(const Symbol_table&);
   Symbol_table& operator=(const Symbol_table&);
 
-  // Set the size of the symbols in the table.
+  // Set the size (32 or 64) of the symbols in the table.
   void
   set_size(int size)
   { this->size_ = size; }
@@ -718,9 +865,9 @@ class Symbol_table
   // Add a symbol.
   template<int size, bool big_endian>
   Symbol*
-  add_from_object(Object*, const char *name,
-                 const char *version, bool def,
-                 const elfcpp::Sym<size, big_endian>& sym);
+  add_from_object(Object*, const char *name, Stringpool::Key name_key,
+                 const char *version, Stringpool::Key version_key,
+                 bool def, const elfcpp::Sym<size, big_endian>& sym);
 
   // Resolve symbols.
   template<int size, bool big_endian>
@@ -774,16 +921,29 @@ class Symbol_table
   // Finalize symbols specialized for size.
   template<int size>
   off_t
-  sized_finalize(off_t, Stringpool*);
+  sized_finalize(unsigned int, off_t, Stringpool*);
 
   // Write globals specialized for size and endianness.
   template<int size, bool big_endian>
   void
-  sized_write_globals(const Target*, const Stringpool*, Output_file*) const;
+  sized_write_globals(const Target*, const Stringpool*, const Stringpool*,
+                     Output_file*) const;
+
+  // Write out a symbol to P.
+  template<int size, bool big_endian>
+  void
+  sized_write_symbol(Sized_symbol<size>*, unsigned int shndx,
+                    const Stringpool*, unsigned char* p
+                     ACCEPT_SIZE_ENDIAN) const;
+
+  // Write out a section symbol, specialized for size and endianness.
+  template<int size, bool big_endian>
+  void
+  sized_write_section_symbol(const Output_section*, Output_file*, off_t) const;
 
   // The type of the symbol hash table.
 
-  typedef std::pair<const char*, const char*> Symbol_table_key;
+  typedef std::pair<Stringpool::Key, Stringpool::Key> Symbol_table_key;
 
   struct Symbol_table_hash
   {
@@ -811,6 +971,9 @@ class Symbol_table
   // use in archive groups.
   int saw_undefined_;
 
+  // The index of the first global symbol in the output file.
+  unsigned int first_global_index_;
+
   // The file offset within the output symtab section where we should
   // write the table.
   off_t offset_;
@@ -818,6 +981,15 @@ class Symbol_table
   // The number of global symbols we want to write out.
   size_t output_count_;
 
+  // The file offset of the global dynamic symbols, or 0 if none.
+  off_t dynamic_offset_;
+
+  // The index of the first global dynamic symbol.
+  unsigned int first_dynamic_global_index_;
+
+  // The number of global dynamic symbols, or 0 if none.
+  off_t dynamic_count_;
+
   // The symbol hash table.
   Symbol_table_type table_;
 
@@ -826,7 +998,7 @@ class Symbol_table
   Stringpool namepool_;
 
   // Forwarding symbols.
-  Unordered_map<Symbol*, Symbol*> forwarders_;
+  Unordered_map<const Symbol*, Symbol*> forwarders_;
 
   // We don't expect there to be very many common symbols, so we keep
   // a list of them.  When we find a common symbol we add it to this
@@ -845,7 +1017,7 @@ template<int size>
 Sized_symbol<size>*
 Symbol_table::get_sized_symbol(Symbol* sym ACCEPT_SIZE) const
 {
-  assert(size == this->get_size());
+  gold_assert(size == this->get_size());
   return static_cast<Sized_symbol<size>*>(sym);
 }
 
@@ -853,7 +1025,7 @@ template<int size>
 const Sized_symbol<size>*
 Symbol_table::get_sized_symbol(const Symbol* sym ACCEPT_SIZE) const
 {
-  assert(size == this->get_size());
+  gold_assert(size == this->get_size());
   return static_cast<const Sized_symbol<size>*>(sym);
 }
 
This page took 0.030025 seconds and 4 git commands to generate.