From Craig Silverstein: rework handling of Script_options.
[binutils-gdb.git] / gold / dynobj.h
index d9c3e107530e576e96cd134d7beb7fb4a48e4f21..cdfa9ce6dd93eb55c56f3673654e34a6eaf16f56 100644 (file)
@@ -31,7 +31,7 @@
 namespace gold
 {
 
-class General_options;
+class Version_script_info;
 
 // A dynamic object (ET_DYN).  This is an abstract base class itself.
 // The implementations is the template class Sized_dynobj.
@@ -39,11 +39,38 @@ class General_options;
 class Dynobj : public Object
 {
  public:
+  // 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
@@ -74,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
@@ -101,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.
@@ -130,6 +175,11 @@ class Sized_dynobj : public Dynobj
   void
   do_add_symbols(Symbol_table*, Read_symbols_data*);
 
+  // Get the size of a section.
+  uint64_t
+  do_section_size(unsigned int shndx)
+  { return this->elf_file_.section_size(shndx); }
+
   // Get the name of a section.
   std::string
   do_section_name(unsigned int shndx)
@@ -146,11 +196,31 @@ class Sized_dynobj : public Dynobj
   do_section_flags(unsigned int shndx)
   { return this->elf_file_.section_flags(shndx); }
 
+  // Return section address.
+  uint64_t
+  do_section_address(unsigned int shndx)
+  { return this->elf_file_.section_addr(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); }
+
+  // Return the section alignment.
+  uint64_t
+  do_section_addralign(unsigned int shndx)
+  { return this->elf_file_.section_addralign(shndx); }
+
  private:
   // For convenience.
   typedef Sized_dynobj<size, big_endian> This;
@@ -174,15 +244,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;
@@ -255,8 +324,9 @@ class Version_base
 class Verdef : public Version_base
 {
  public:
-  Verdef(const char* name, bool is_base, bool is_weak, bool is_symbol_created)
-    : name_(name), deps_(), is_base_(is_base), is_weak_(is_weak),
+  Verdef(const char* name, const std::vector<std::string>& deps,
+         bool is_base, bool is_weak, bool is_symbol_created)
+    : name_(name), deps_(deps), is_base_(is_base), is_weak_(is_weak),
       is_symbol_created_(is_symbol_created)
   { }
 
@@ -304,7 +374,7 @@ class Verdef : public Version_base
 
   // The type of the list of version dependencies.  Each dependency
   // should be canonicalized in the dynamic Stringpool.
-  typedef std::vector<const char*> Deps;
+  typedef std::vector<std::string> Deps;
 
   // The name of this version.  This should be canonicalized in the
   // dynamic Stringpool.
@@ -405,9 +475,7 @@ class Verneed
 class Versions
 {
  public:
-  Versions()
-    : defs_(), needs_(), version_table_(), is_finalized_(false)
-  { }
+  Versions(const Version_script_info&, Stringpool*);
 
   ~Versions();
 
@@ -420,7 +488,7 @@ class Versions
   // for the next dynamic symbol.  We add new dynamic symbols to SYMS
   // and return an updated DYNSYM_INDEX.
   unsigned int
-  finalize(const Target*, Symbol_table* symtab, unsigned int dynsym_index,
+  finalize(Symbol_table* symtab, unsigned int dynsym_index,
           std::vector<Symbol*>* syms);
 
   // Return whether there are any version definitions.
@@ -459,7 +527,14 @@ class Versions
                        unsigned int* psize, unsigned int* pentries
                         ACCEPT_SIZE_ENDIAN) const;
 
+  const Version_script_info&
+  version_script() const
+  { return this->version_script_; }
+
  private:
+  Versions(const Versions&);
+  Versions& operator=(const Versions&);
+
   // The type of the list of version definitions.
   typedef std::vector<Verdef*> Defs;
 
@@ -514,6 +589,8 @@ class Versions
   Version_table version_table_;
   // Whether the version indexes have been set.
   bool is_finalized_;
+  // Contents of --version-script, if passed, or NULL.
+  const Version_script_info& version_script_;
 };
 
 } // End namespace gold.