Add section_size_type and section_offset_type, use them to replace a
[binutils-gdb.git] / gold / dynobj.h
index 189bf682319dbf1ebc214be18ab4ced83bba98c0..cc6ec546c15c3324e69643b5d3f0858b5ae4e920 100644 (file)
@@ -39,13 +39,38 @@ class General_options;
 class Dynobj : public Object
 {
  public:
-  Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0)
-    : Object(name, input_file, true, offset), soname_()
-  { }
+  // We keep a list of all the DT_NEEDED entries we find.
+  typedef std::vector<std::string> Needed;
+
+  Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0);
 
   // Return the name to use in a DT_NEEDED entry for this object.
   const char*
-  soname() const;
+  soname() const
+  { return this->soname_.c_str(); }
+
+  // Return the list of DT_NEEDED strings.
+  const Needed&
+  needed() const
+  { return this->needed_; }
+
+  // Return whether this dynamic object has any DT_NEEDED entries
+  // which were not seen during the link.
+  bool
+  has_unknown_needed_entries() const
+  {
+    gold_assert(this->unknown_needed_ != UNKNOWN_NEEDED_UNSET);
+    return this->unknown_needed_ == UNKNOWN_NEEDED_TRUE;
+  }
+
+  // Set whether this dynamic object has any DT_NEEDED entries which
+  // were not seen during the link.
+  void
+  set_has_unknown_needed_entries(bool set)
+  {
+    gold_assert(this->unknown_needed_ == UNKNOWN_NEEDED_UNSET);
+    this->unknown_needed_ = set ? UNKNOWN_NEEDED_TRUE : UNKNOWN_NEEDED_FALSE;
+  }
 
   // Compute the ELF hash code for a string.
   static uint32_t
@@ -56,7 +81,7 @@ class Dynobj : public Object
   // number of local dynamic symbols, which is the index of the first
   // dynamic gobal symbol.
   static void
-  create_elf_hash_table(const Target*, const std::vector<Symbol*>& dynsyms,
+  create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
                        unsigned int local_dynsym_count,
                        unsigned char** pphash,
                        unsigned int* phashlen);
@@ -66,7 +91,7 @@ class Dynobj : public Object
   // of local dynamic symbols, which is the index of the first dynamic
   // gobal symbol.
   static void
-  create_gnu_hash_table(const Target*, const std::vector<Symbol*>& dynsyms,
+  create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
                        unsigned int local_dynsym_count,
                        unsigned char** pphash, unsigned int* phashlen);
 
@@ -76,6 +101,11 @@ class Dynobj : public Object
   set_soname_string(const char* s)
   { this->soname_.assign(s); }
 
+  // Add an entry to the list of DT_NEEDED strings.
+  void
+  add_needed(const char* s)
+  { this->needed_.push_back(std::string(s)); }
+
  private:
   // Compute the GNU hash code for a string.
   static uint32_t
@@ -103,8 +133,21 @@ class Dynobj : public Object
                              unsigned char** pphash,
                              unsigned int* phashlen);
 
+  // Values for the has_unknown_needed_entries_ field.
+  enum Unknown_needed
+  {
+    UNKNOWN_NEEDED_UNSET,
+    UNKNOWN_NEEDED_TRUE,
+    UNKNOWN_NEEDED_FALSE
+  };
+
   // The DT_SONAME name, if any.
   std::string soname_;
+  // The list of DT_NEEDED entries.
+  Needed needed_;
+  // Whether this dynamic object has any DT_NEEDED entries not seen
+  // during the link.
+  Unknown_needed unknown_needed_;
 };
 
 // A dynamic object, size and endian specific version.
@@ -148,6 +191,21 @@ class Sized_dynobj : public Dynobj
   do_section_flags(unsigned int shndx)
   { return this->elf_file_.section_flags(shndx); }
 
+  // Return section type.
+  unsigned int
+  do_section_type(unsigned int shndx)
+  { return this->elf_file_.section_type(shndx); }
+
+  // Return the section link field.
+  unsigned int
+  do_section_link(unsigned int shndx)
+  { return this->elf_file_.section_link(shndx); }
+
+  // Return the section link field.
+  unsigned int
+  do_section_info(unsigned int shndx)
+  { return this->elf_file_.section_info(shndx); }
+
  private:
   // For convenience.
   typedef Sized_dynobj<size, big_endian> This;
@@ -171,15 +229,14 @@ class Sized_dynobj : public Dynobj
   void
   read_dynsym_section(const unsigned char* pshdrs, unsigned int shndx,
                      elfcpp::SHT type, unsigned int link,
-                     File_view** view, off_t* view_size,
+                     File_view** view, section_size_type* view_size,
                      unsigned int* view_info);
 
-  // Set the SONAME from the SHT_DYNAMIC section at DYNAMIC_SHNDX.
-  // The STRTAB parameters may have the relevant string table.
+  // Read the dynamic tags.
   void
-  set_soname(const unsigned char* pshdrs, unsigned int dynamic_shndx,
-            unsigned int strtab_shndx, const unsigned char* strtabu,
-            off_t strtab_size);
+  read_dynamic(const unsigned char* pshdrs, unsigned int dynamic_shndx,
+              unsigned int strtab_shndx, const unsigned char* strtabu,
+              off_t strtab_size);
 
   // Mapping from version number to version name.
   typedef std::vector<const char*> Version_map;
@@ -411,7 +468,7 @@ class Versions
   // SYM is going into the dynamic symbol table and has a version.
   // Record the appropriate version information.
   void
-  record_version(const General_options*, Stringpool*, const Symbol* sym);
+  record_version(const Symbol_table* symtab, Stringpool*, const Symbol* sym);
 
   // Set the version indexes.  DYNSYM_INDEX is the index we should use
   // for the next dynamic symbol.  We add new dynamic symbols to SYMS
@@ -434,7 +491,8 @@ class Versions
   // version section (.gnu.version).
   template<int size, bool big_endian>
   void
-  symbol_section_contents(const Stringpool*, unsigned int local_symcount,
+  symbol_section_contents(const Symbol_table*, const Stringpool*,
+                         unsigned int local_symcount,
                          const std::vector<Symbol*>& syms,
                          unsigned char**, unsigned int*
                           ACCEPT_SIZE_ENDIAN) const;
@@ -464,17 +522,21 @@ class Versions
 
   // Handle a symbol SYM defined with version VERSION.
   void
-  add_def(const General_options*, const Symbol* sym, const char* version,
-         Stringpool::Key);
+  add_def(const Symbol* sym, const char* version, Stringpool::Key);
 
   // Add a reference to version NAME in file FILENAME.
   void
   add_need(Stringpool*, const char* filename, const char* name,
           Stringpool::Key);
 
+  // Get the dynamic object to use for SYM.
+  Dynobj*
+  get_dynobj_for_sym(const Symbol_table*, const Symbol* sym) const;
+
   // Return the version index to use for SYM.
   unsigned int
-  version_index(const Stringpool*, const Symbol* sym) const;
+  version_index(const Symbol_table*, const Stringpool*,
+               const Symbol* sym) const;
 
   // We keep a hash table mapping canonicalized name/version pairs to
   // a version base.