* symtab.cc (Symbol_table::add_from_relobj): Don't set the version
[deliverable/binutils-gdb.git] / gold / object.h
index dbe0ca1390ebaf4056ae2008736765cd5595fd29..4a2ad8a3679c36b7cb437641ea8c05c097faf502 100644 (file)
@@ -1,6 +1,6 @@
 // object.h -- support for an object file for linking in gold  -*- C++ -*-
 
-// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -111,6 +111,8 @@ struct Section_relocs
   Output_section* output_section;
   // Whether this section has special handling for offsets.
   bool needs_special_offset_handling;
+  // Whether the data section is allocated (has the SHF_ALLOC flag set).
+  bool is_data_section_allocated;
 };
 
 // Relocations in an object file.  This is read in read_relocs and
@@ -190,12 +192,17 @@ class Object
   release()
   { this->input_file_->file().release(); }
 
+  // Return whether we should just read symbols from this file.
+  bool
+  just_symbols() const
+  { return this->input_file()->just_symbols(); }
+
   // Return the sized target structure associated with this object.
   // This is like the target method but it returns a pointer of
   // appropriate checked type.
   template<int size, bool big_endian>
   Sized_target<size, big_endian>*
-  sized_target(ACCEPT_SIZE_ENDIAN_ONLY) const;
+  sized_target() const;
 
   // Get the number of sections.
   unsigned int
@@ -222,6 +229,11 @@ class Object
   section_flags(unsigned int shndx)
   { return this->do_section_flags(shndx); }
 
+  // Return the section address given a section index.
+  uint64_t
+  section_address(unsigned int shndx)
+  { return this->do_section_address(shndx); }
+
   // Return the section type given a section index.
   unsigned int
   section_type(unsigned int shndx)
@@ -366,6 +378,10 @@ class Object
   virtual uint64_t
   do_section_flags(unsigned int shndx) = 0;
 
+  // Get section address--implemented by child class.
+  virtual uint64_t
+  do_section_address(unsigned int shndx) = 0;
+
   // Get section type--implemented by child class.
   virtual unsigned int
   do_section_type(unsigned int shndx) = 0;
@@ -441,7 +457,7 @@ class Object
 
 template<int size, bool big_endian>
 inline Sized_target<size, big_endian>*
-Object::sized_target(ACCEPT_SIZE_ENDIAN_ONLY) const
+Object::sized_target() const
 {
   gold_assert(this->target_->get_size() == size);
   gold_assert(this->target_->is_big_endian() ? big_endian : !big_endian);
@@ -860,6 +876,7 @@ class Symbol_value
   void
   set_needs_output_dynsym_entry()
   {
+    gold_assert(!this->is_section_symbol());
     this->output_dynsym_index_ = 0;
   }
 
@@ -883,7 +900,8 @@ class Symbol_value
   unsigned int
   output_dynsym_index() const
   {
-    gold_assert(this->output_dynsym_index_ != 0);
+    gold_assert(this->output_dynsym_index_ != 0
+                && this->output_dynsym_index_ != -1U);
     return this->output_dynsym_index_;
   }
 
@@ -910,7 +928,10 @@ class Symbol_value
   // Record that this is a section symbol.
   void
   set_is_section_symbol()
-  { this->is_section_symbol_ = true; }
+  {
+    gold_assert(!this->needs_output_dynsym_entry());
+    this->is_section_symbol_ = true;
+  }
 
   // Record that this is a TLS symbol.
   void
@@ -955,6 +976,83 @@ class Symbol_value
   } u_;
 };
 
+// A GOT offset list.  A symbol may have more than one GOT offset
+// (e.g., when mixing modules compiled with two different TLS models),
+// but will usually have at most one.  GOT_TYPE identifies the type of
+// GOT entry; its values are specific to each target.
+
+class Got_offset_list
+{
+ public:
+  Got_offset_list()
+    : got_type_(-1U), got_offset_(0), got_next_(NULL)
+  { }
+
+  Got_offset_list(unsigned int got_type, unsigned int got_offset)
+    : got_type_(got_type), got_offset_(got_offset), got_next_(NULL)
+  { }
+
+  ~Got_offset_list()
+  { 
+    if (this->got_next_ != NULL)
+      {
+        delete this->got_next_;
+        this->got_next_ = NULL;
+      }
+  }
+
+  // Initialize the fields to their default values.
+  void
+  init()
+  {
+    this->got_type_ = -1U;
+    this->got_offset_ = 0;
+    this->got_next_ = NULL;
+  }
+
+  // Set the offset for the GOT entry of type GOT_TYPE.
+  void
+  set_offset(unsigned int got_type, unsigned int got_offset)
+  {
+    if (this->got_type_ == -1U)
+      {
+        this->got_type_ = got_type;
+        this->got_offset_ = got_offset;
+      }
+    else
+      {
+        for (Got_offset_list* g = this; g != NULL; g = g->got_next_)
+          {
+            if (g->got_type_ == got_type)
+              {
+                g->got_offset_ = got_offset;
+                return;
+              }
+          }
+        Got_offset_list* g = new Got_offset_list(got_type, got_offset);
+        g->got_next_ = this->got_next_;
+        this->got_next_ = g;
+      }
+  }
+
+  // Return the offset for a GOT entry of type GOT_TYPE.
+  unsigned int
+  get_offset(unsigned int got_type) const
+  {
+    for (const Got_offset_list* g = this; g != NULL; g = g->got_next_)
+      {
+        if (g->got_type_ == got_type)
+          return g->got_offset_;
+      }
+    return -1U;
+  }
+
+ private:
+  unsigned int got_type_;
+  unsigned int got_offset_;
+  Got_offset_list* got_next_;
+};
+
 // A regular object file.  This is size and endian specific.
 
 template<int size, bool big_endian>
@@ -1033,16 +1131,9 @@ class Sized_relobj : public Relobj
   // Return the appropriate Sized_target structure.
   Sized_target<size, big_endian>*
   sized_target()
-  {
-    return this->Object::sized_target
-      SELECT_SIZE_ENDIAN_NAME(size, big_endian) (
-          SELECT_SIZE_ENDIAN_ONLY(size, big_endian));
-  }
-
-  // Return the value of the local symbol symndx.
-  Address
-  local_symbol_value(unsigned int symndx) const;
+  { return this->Object::sized_target<size, big_endian>(); }
 
+  // Record that local symbol SYM needs a dynamic symbol entry.
   void
   set_needs_output_dynsym_entry(unsigned int sym)
   {
@@ -1053,84 +1144,40 @@ class Sized_relobj : public Relobj
   // Return whether the local symbol SYMNDX has a GOT offset.
   // For TLS symbols, the GOT entry will hold its tp-relative offset.
   bool
-  local_has_got_offset(unsigned int symndx) const
+  local_has_got_offset(unsigned int symndx, unsigned int got_type) const
   {
-    return (this->local_got_offsets_.find(symndx)
-            != this->local_got_offsets_.end());
+    Local_got_offsets::const_iterator p =
+        this->local_got_offsets_.find(symndx);
+    return (p != this->local_got_offsets_.end()
+            && p->second->get_offset(got_type) != -1U);
   }
 
   // Return the GOT offset of the local symbol SYMNDX.
   unsigned int
-  local_got_offset(unsigned int symndx) const
+  local_got_offset(unsigned int symndx, unsigned int got_type) const
   {
     Local_got_offsets::const_iterator p =
         this->local_got_offsets_.find(symndx);
     gold_assert(p != this->local_got_offsets_.end());
-    return p->second;
+    unsigned int off = p->second->get_offset(got_type);
+    gold_assert(off != -1U);
+    return off;
   }
 
   // Set the GOT offset of the local symbol SYMNDX to GOT_OFFSET.
   void
-  set_local_got_offset(unsigned int symndx, unsigned int got_offset)
-  {
-    std::pair<Local_got_offsets::iterator, bool> ins =
-        this->local_got_offsets_.insert(std::make_pair(symndx, got_offset));
-    gold_assert(ins.second);
-  }
-
-  // Return whether the local TLS symbol SYMNDX has a GOT offset.
-  // The GOT entry at this offset will contain a module index. If
-  // NEED_PAIR is true, a second entry immediately following the first
-  // will contain the dtv-relative offset.
-  bool
-  local_has_tls_got_offset(unsigned int symndx, bool need_pair) const
-  {
-    typename Local_tls_got_offsets::const_iterator p =
-        this->local_tls_got_offsets_.find(symndx);
-    if (p == this->local_tls_got_offsets_.end()
-        || (need_pair && !p->second.have_pair_))
-      return false;
-    return true;
-  }
-
-  // Return the offset of the GOT entry for the local TLS symbol SYMNDX.
-  // If NEED_PAIR is true, we need the offset of a pair of GOT entries;
-  // otherwise we need the offset of the GOT entry for the module index.
-  unsigned int
-  local_tls_got_offset(unsigned int symndx, bool need_pair) const
-  {
-    typename Local_tls_got_offsets::const_iterator p =
-        this->local_tls_got_offsets_.find(symndx);
-    gold_assert(p != this->local_tls_got_offsets_.end());
-    gold_assert(!need_pair || p->second.have_pair_);
-    return p->second.got_offset_;
-  }
-
-  // Set the offset of the GOT entry for the local TLS symbol SYMNDX
-  // to GOT_OFFSET. If HAVE_PAIR is true, we have a pair of GOT entries;
-  // otherwise, we have just a single entry for the module index.
-  void
-  set_local_tls_got_offset(unsigned int symndx, unsigned int got_offset,
-                           bool have_pair)
+  set_local_got_offset(unsigned int symndx, unsigned int got_type,
+                       unsigned int got_offset)
   {
-    typename Local_tls_got_offsets::iterator p =
-        this->local_tls_got_offsets_.find(symndx);
-    if (p != this->local_tls_got_offsets_.end())
-      {
-        // An entry already existed for this symbol. This can happen
-        // if we see a relocation asking for the module index before
-        // a relocation asking for the pair. In that case, the original
-        // GOT entry will remain, but won't get used by any further
-        // relocations.
-        p->second.got_offset_ = got_offset;
-       gold_assert(have_pair);
-        p->second.have_pair_ = true;
-      }
+    Local_got_offsets::const_iterator p =
+        this->local_got_offsets_.find(symndx);
+    if (p != this->local_got_offsets_.end())
+      p->second->set_offset(got_type, got_offset);
     else
       {
-        std::pair<typename Local_tls_got_offsets::iterator, bool> ins =
-            this->local_tls_got_offsets_.insert(
-              std::make_pair(symndx, Tls_got_entry(got_offset, have_pair)));
+        Got_offset_list* g = new Got_offset_list(got_type, got_offset);
+        std::pair<Local_got_offsets::iterator, bool> ins =
+            this->local_got_offsets_.insert(std::make_pair(symndx, g));
         gold_assert(ins.second);
       }
   }
@@ -1211,6 +1258,11 @@ class Sized_relobj : public Relobj
   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)
@@ -1288,6 +1340,42 @@ class Sized_relobj : public Relobj
   relocate_sections(const General_options& options, const Symbol_table*,
                    const Layout*, const unsigned char* pshdrs, Views*);
 
+  // Scan the input relocations for --emit-relocs.
+  void
+  emit_relocs_scan(const General_options&, Symbol_table*, Layout*,
+                  const unsigned char* plocal_syms,
+                  const Read_relocs_data::Relocs_list::iterator&);
+
+  // Scan the input relocations for --emit-relocs, templatized on the
+  // type of the relocation section.
+  template<int sh_type>
+  void
+  emit_relocs_scan_reltype(const General_options&, Symbol_table*, Layout*,
+                          const unsigned char* plocal_syms,
+                          const Read_relocs_data::Relocs_list::iterator&,
+                          Relocatable_relocs*);
+
+  // Emit the relocs for --emit-relocs.
+  void
+  emit_relocs(const Relocate_info<size, big_endian>*, unsigned int,
+             unsigned int sh_type, const unsigned char* prelocs,
+             size_t reloc_count, Output_section*, off_t output_offset,
+             unsigned char* view, Address address,
+             section_size_type view_size,
+             unsigned char* reloc_view, section_size_type reloc_view_size);
+
+  // Emit the relocs for --emit-relocs, templatized on the type of the
+  // relocation section.
+  template<int sh_type>
+  void
+  emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int,
+                     const unsigned char* prelocs, size_t reloc_count,
+                     Output_section*, off_t output_offset,
+                     unsigned char* view, Address address,
+                     section_size_type view_size,
+                     unsigned char* reloc_view,
+                     section_size_type reloc_view_size);
+
   // Initialize input to output maps for section symbols in merged
   // sections.
   void
@@ -1310,12 +1398,11 @@ class Sized_relobj : public Relobj
   {
     this->local_values_.clear();
     this->local_got_offsets_.clear();
-    this->local_tls_got_offsets_.clear();
   }
 
   // The GOT offsets of local symbols. This map also stores GOT offsets
   // for tp-relative offsets for TLS symbols.
-  typedef Unordered_map<unsigned int, unsigned int> Local_got_offsets;
+  typedef Unordered_map<unsigned int, Got_offset_list*> Local_got_offsets;
 
   // The TLS GOT offsets of local symbols. The map stores the offsets
   // for either a single GOT entry that holds the module index of a TLS
@@ -1354,9 +1441,6 @@ class Sized_relobj : public Relobj
   // GOT offsets for local non-TLS symbols, and tp-relative offsets
   // for TLS symbols, indexed by symbol number.
   Local_got_offsets local_got_offsets_;
-  // GOT offsets for local TLS symbols, indexed by symbol number
-  // and GOT entry type.
-  Local_tls_got_offsets local_tls_got_offsets_;
   // Whether this object has a GNU style .eh_frame section.
   bool has_eh_frame_;
 };
@@ -1367,8 +1451,7 @@ class Input_objects
 {
  public:
   Input_objects()
-    : relobj_list_(), dynobj_list_(), target_(NULL), sonames_(),
-      system_library_directory_()
+    : relobj_list_(), dynobj_list_(), sonames_(), system_library_directory_()
   { }
 
   // The type of the list of input relocateable objects.
@@ -1384,11 +1467,6 @@ class Input_objects
   bool
   add_object(Object*);
 
-  // Get the target we should use for the output file.
-  Target*
-  target() const
-  { return this->target_; }
-
   // For each dynamic object, check whether we've seen all of its
   // explicit dependencies.
   void
@@ -1437,8 +1515,6 @@ class Input_objects
   Relobj_list relobj_list_;
   // The list of dynamic objects included in the link.
   Dynobj_list dynobj_list_;
-  // The target.
-  Target* target_;
   // SONAMEs that we have seen.
   Unordered_set<std::string> sonames_;
   // The directory in which we find the libc.so.
This page took 0.027513 seconds and 4 git commands to generate.