]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Split Object into Dynobj and Relobj, incorporate elfcpp swapping changes.
authorIan Lance Taylor <iant@google.com>
Mon, 6 Nov 2006 22:46:08 +0000 (22:46 +0000)
committerIan Lance Taylor <iant@google.com>
Mon, 6 Nov 2006 22:46:08 +0000 (22:46 +0000)
23 files changed:
gold/archive.cc
gold/archive.h
gold/common.cc
gold/defstd.cc
gold/dynobj.h [new file with mode: 0644]
gold/fileread.cc
gold/gold.cc
gold/i386.cc
gold/layout.cc
gold/layout.h
gold/object.cc
gold/object.h
gold/output.cc
gold/output.h
gold/po/gold.pot
gold/readsyms.cc
gold/readsyms.h
gold/reloc.cc
gold/reloc.h
gold/symtab.cc
gold/symtab.h
gold/target-reloc.h
gold/target.h

index 031ead09a408fc1f82d1681838b0965675d0ef45..d0854036a6728b895b38dea3a640f7813b9e7476 100644 (file)
@@ -70,7 +70,7 @@ Archive::setup()
 
   // Numbers in the armap are always big-endian.
   const elfcpp::Elf_Word* pword = reinterpret_cast<const elfcpp::Elf_Word*>(p);
-  unsigned int nsyms = elfcpp::read_elf_word<true>(pword);
+  unsigned int nsyms = elfcpp::Swap<32, true>::readval(pword);
   ++pword;
 
   // Note that the addition is in units of sizeof(elfcpp::Elf_Word).
@@ -81,7 +81,7 @@ Archive::setup()
   for (unsigned int i = 0; i < nsyms; ++i)
     {
       this->armap_[i].name = pnames;
-      this->armap_[i].offset = elfcpp::read_elf_word<true>(pword);
+      this->armap_[i].offset = elfcpp::Swap<32, true>::readval(pword);
       pnames += strlen(pnames) + 1;
       ++pword;
     }
@@ -215,8 +215,8 @@ Archive::read_header(off_t off, std::string* pname)
 // may be satisfied by other objects in the archive.
 
 void
-Archive::add_symbols(Symbol_table* symtab, Layout* layout,
-                    Input_objects* input_objects)
+Archive::add_symbols(const General_options& options, Symbol_table* symtab,
+                    Layout* layout, Input_objects* input_objects)
 {
   const size_t armap_size = this->armap_.size();
 
@@ -248,7 +248,7 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout,
 
          // We want to include this object in the link.
          last = this->armap_[i].offset;
-         this->include_member(symtab, layout, input_objects, last);
+         this->include_member(options, symtab, layout, input_objects, last);
          this->seen_[i] = true;
          added_new_object = true;
        }
@@ -260,8 +260,9 @@ Archive::add_symbols(Symbol_table* symtab, Layout* layout,
 // the member header.
 
 void
-Archive::include_member(Symbol_table* symtab, Layout* layout,
-                       Input_objects* input_objects, off_t off)
+Archive::include_member(const General_options& options, Symbol_table* symtab,
+                       Layout* layout, Input_objects* input_objects,
+                       off_t off)
 {
   std::string n;
   this->read_header(off, &n);
@@ -303,7 +304,7 @@ Archive::include_member(Symbol_table* symtab, Layout* layout,
 
   Read_symbols_data sd;
   obj->read_symbols(&sd);
-  obj->layout(layout, &sd);
+  obj->layout(options, symtab, layout, &sd);
   obj->add_symbols(symtab, &sd);
 }
 
@@ -352,7 +353,7 @@ Add_archive_symbols::locks(Workqueue* workqueue)
 void
 Add_archive_symbols::run(Workqueue*)
 {
-  this->archive_->add_symbols(this->symtab_, this->layout_,
+  this->archive_->add_symbols(this->options_, this->symtab_, this->layout_,
                              this->input_objects_);
 
   if (this->input_group_ != NULL)
index f0edfcb7ffd228d9f9b20606c705ff2c095cd128..193a9e2de8203e00a9e94bc0457a62e13685cb43 100644 (file)
@@ -11,6 +11,7 @@
 namespace gold
 {
 
+class General_options;
 class Input_file;
 class Input_objects;
 class Input_group;
@@ -68,14 +69,13 @@ class Archive
   // Select members from the archive as needed and add them to the
   // link.
   void
-  add_symbols(Symbol_table*, Layout*, Input_objects*);
+  add_symbols(const General_options&, Symbol_table*, Layout*, Input_objects*);
 
  private:
   Archive(const Archive&);
   Archive& operator=(const Archive&);
 
   struct Archive_header;
-  class Add_archive_symbols_locker;
 
   // Get a view into the underlying file.
   const unsigned char*
@@ -89,7 +89,8 @@ class Archive
 
   // Include an archive member in the link.
   void
-  include_member(Symbol_table*, Layout*, Input_objects*, off_t off);
+  include_member(const General_options&, Symbol_table*, Layout*,
+                Input_objects*, off_t off);
 
   // An entry in the archive map of symbols to object files.
   struct Armap_entry
@@ -119,14 +120,15 @@ class Archive
 class Add_archive_symbols : public Task
 {
  public:
-  Add_archive_symbols(Symbol_table* symtab, Layout* layout,
-                     Input_objects* input_objects,
+  Add_archive_symbols(const General_options& options, Symbol_table* symtab,
+                     Layout* layout, Input_objects* input_objects,
                      Archive* archive, Input_group* input_group,
                      Task_token* this_blocker,
                      Task_token* next_blocker)
-    : symtab_(symtab), layout_(layout), input_objects_(input_objects),
-      archive_(archive), input_group_(input_group),
-      this_blocker_(this_blocker), next_blocker_(next_blocker)
+    : options_(options), symtab_(symtab), layout_(layout),
+      input_objects_(input_objects), archive_(archive),
+      input_group_(input_group), this_blocker_(this_blocker),
+      next_blocker_(next_blocker)
   { }
 
   ~Add_archive_symbols();
@@ -145,6 +147,7 @@ class Add_archive_symbols : public Task
  private:
   class Add_archive_symbols_locker;
 
+  const General_options& options_;
   Symbol_table* symtab_;
   Layout* layout_;
   Input_objects* input_objects_;
index 28ca2f6dab85e73862068e214dc3551a69c249ab..358ed8d0d9469613b44b8000a830692ff0fcb506 100644 (file)
@@ -7,6 +7,7 @@
 #include "workqueue.h"
 #include "layout.h"
 #include "output.h"
+#include "symtab.h"
 #include "common.h"
 
 namespace gold
index 29fd2cd8cf96d0f0a7294d1f1da607b46fa82747..50a977a3b9075652440bda0eec00ac4564d3de21 100644 (file)
@@ -93,10 +93,122 @@ const int in_section_count = sizeof in_section / sizeof in_section[0];
 
 const Define_symbol_in_segment in_segment[] =
 {
+  {
+    "__executable_start",      // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF(0),             // segment_flags_set
+    elfcpp::PF(0),             // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_START,     // offset_from_base
+    true                       // only_if_ref
+  },
+  {
+    "etext",                   // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF_W,              // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_END,       // offset_from_base
+    true                       // only_if_ref
+  },
+  {
+    "_etext",                  // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF_W,              // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_END,       // offset_from_base
+    true                       // only_if_ref
+  },
+  {
+    "__etext",                 // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF_W,              // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_END,       // offset_from_base
+    true                       // only_if_ref
+  },
+  {
+    "_edata",                  // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF(0),             // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_BSS,       // offset_from_base
+    false                      // only_if_ref
+  },
+  {
+    "edata",                   // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF(0),             // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_BSS,       // offset_from_base
+    true                       // only_if_ref
+  },
+  {
+    "__bss_start",             // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF(0),             // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_BSS,       // offset_from_base
+    false                      // only_if_ref
+  },
   {
     "_end",                    // name
     elfcpp::PT_LOAD,           // segment_type
-    elfcpp::PF_W,              // segment_flags_set
+    elfcpp::PF_X,              // segment_flags_set
+    elfcpp::PF(0),             // segment_flags_clear
+    0,                         // value
+    0,                         // size
+    elfcpp::STT_NOTYPE,                // type
+    elfcpp::STB_GLOBAL,                // binding
+    elfcpp::STV_DEFAULT,       // visibility
+    0,                         // nonvis
+    Symbol::SEGMENT_START,     // offset_from_base
+    false                      // only_if_ref
+  },
+  {
+    "end",                     // name
+    elfcpp::PT_LOAD,           // segment_type
+    elfcpp::PF_X,              // segment_flags_set
     elfcpp::PF(0),             // segment_flags_clear
     0,                         // value
     0,                         // size
@@ -104,7 +216,7 @@ const Define_symbol_in_segment in_segment[] =
     elfcpp::STB_GLOBAL,                // binding
     elfcpp::STV_DEFAULT,       // visibility
     0,                         // nonvis
-    Symbol::SEGMENT_START,     // offset_from_bas
+    Symbol::SEGMENT_START,     // offset_from_base
     false                      // only_if_ref
   }
 };
diff --git a/gold/dynobj.h b/gold/dynobj.h
new file mode 100644 (file)
index 0000000..99e7883
--- /dev/null
@@ -0,0 +1,56 @@
+// dynobj.h -- dynamic object support for gold   -*- C++ -*-
+
+#ifndef GOLD_DYNOBJ_H
+#define GOLD_DYNOBJ_H
+
+#include "object.h"
+
+namespace gold
+{
+
+// A dynamic object (ET_DYN).  This is an abstract base class itself.
+// The implementations is the template class Sized_dynobj.
+
+class Dynobj : public Object
+{
+ public:
+  Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0)
+    : Object(name, input_file, true, offset)
+  { }
+};
+
+// A dynamic object, size and endian specific version.
+
+template<int size, bool big_endian>
+class Sized_dynobj : public Dynobj
+{
+ public:
+  Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset,
+              const typename elfcpp::Ehdr<size, big_endian>&);
+
+  // Read the symbols.
+  void
+  do_read_symbols(Read_symbols_data*);
+
+  // Lay out the input sections.
+  void
+  do_layout(const General_options&, Symbol_table*, Layout*,
+           Read_symbols_data*);
+
+  // Add the symbols to the symbol table.
+  void
+  do_add_symbols(Symbol_table*, Read_symbols_data*);
+
+  // Return a view of the contents of a section.  Set *PLEN to the
+  // size.
+  const unsigned char*
+  do_section_contents(unsigned int shnum, off_t* plen) = 0;
+
+  // Get the name of a section.
+  std::string
+  do_section_name(unsigned int shnum);
+};
+
+} // End namespace gold.
+
+#endif // !defined(GOLD_DYNOBJ_H)
index 00971a76ca51874780a1222dcd947c29b91db43a..43c69b3cf417e2e6ad852687cb28cbfa8a9a5aea 100644 (file)
@@ -314,9 +314,13 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath)
       std::string n1("lib");
       n1 += this->input_argument_.name();
       std::string n2;
-      if (!options.is_static())
-       n2 = n1 + ".so";
-      n1 += ".a";
+      if (options.is_static())
+       n1 += ".a";
+      else
+       {
+         n2 = n1 + ".a";
+         n1 += ".so";
+       }
       name = dirpath.find(n1, n2);
       if (name.empty())
        {
index 31598dc9e6a0efc0d93a7722eddaa20118940930..c2372adf526bed18c35c3174542521157b13fa6d 100644 (file)
@@ -153,8 +153,8 @@ queue_middle_tasks(const General_options& options,
   // of references made to the symbols.
   Task_token* blocker = new Task_token();
   Task_token* symtab_lock = new Task_token();
-  for (Input_objects::Object_list::const_iterator p = input_objects->begin();
-       p != input_objects->end();
+  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
+       p != input_objects->relobj_end();
        ++p)
     {
       // We can read and process the relocations in any order.  But we
@@ -198,8 +198,8 @@ queue_final_tasks(const General_options& options,
 
   // Queue a task for each input object to relocate the sections and
   // write out the local symbols.
-  for (Input_objects::Object_list::const_iterator p = input_objects->begin();
-       p != input_objects->end();
+  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
+       p != input_objects->relobj_end();
        ++p)
     {
       final_blocker->add_blocker();
index 53af5eeae6f605e20273adad45113d8d0267b0ac..15376f9598ee40522089e1ebf47008251baba3e4 100644 (file)
@@ -35,7 +35,7 @@ class Target_i386 : public Sized_target<32, false>
   scan_relocs(const General_options& options,
              Symbol_table* symtab,
              Layout* layout,
-             Sized_object<32, false>* object,
+             Sized_relobj<32, false>* object,
              unsigned int sh_type,
              const unsigned char* prelocs,
              size_t reloc_count,
@@ -60,14 +60,14 @@ class Target_i386 : public Sized_target<32, false>
     inline void
     local(const General_options& options, Symbol_table* symtab,
          Layout* layout, Target_i386* target,
-         Sized_object<32, false>* object,
+         Sized_relobj<32, false>* object,
          const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
          const elfcpp::Sym<32, false>& lsym);
 
     inline void
     global(const General_options& options, Symbol_table* symtab,
           Layout* layout, Target_i386* target,
-          Sized_object<32, false>* object,
+          Sized_relobj<32, false>* object,
           const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
           Symbol* gsym);
   };
@@ -265,7 +265,7 @@ Target_i386::Scan::local(const General_options& options,
                         Symbol_table* symtab,
                         Layout* layout,
                         Target_i386* target,
-                        Sized_object<32, false>* object,
+                        Sized_relobj<32, false>* object,
                         const elfcpp::Rel<32, false>&, unsigned int r_type,
                         const elfcpp::Sym<32, false>&)
 {
@@ -368,7 +368,7 @@ Target_i386::Scan::global(const General_options& options,
                          Symbol_table* symtab,
                          Layout* layout,
                          Target_i386* target,
-                         Sized_object<32, false>* object,
+                         Sized_relobj<32, false>* object,
                          const elfcpp::Rel<32, false>&, unsigned int r_type,
                          Symbol* gsym)
 {
@@ -496,7 +496,7 @@ void
 Target_i386::scan_relocs(const General_options& options,
                         Symbol_table* symtab,
                         Layout* layout,
-                        Sized_object<32, false>* object,
+                        Sized_relobj<32, false>* object,
                         unsigned int sh_type,
                         const unsigned char* prelocs,
                         size_t reloc_count,
index 9e85f192a4c8df53039815943b940d0891ff3f88..2bdd11b4772faaf199b7d72afe22234eade2b64b 100644 (file)
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "output.h"
+#include "symtab.h"
 #include "layout.h"
 
 namespace gold
@@ -151,7 +152,7 @@ Layout::get_output_section(const char* name, elfcpp::Elf_Word type,
 
 template<int size, bool big_endian>
 Output_section*
-Layout::layout(Object* object, unsigned int shndx, const char* name,
+Layout::layout(Relobj* object, unsigned int shndx, const char* name,
               const elfcpp::Shdr<size, big_endian>& shdr, off_t* off)
 {
   if (!this->include_section(object, name, shdr))
@@ -656,8 +657,8 @@ Layout::create_symtab_sections(int size, const Input_objects* input_objects,
   // never bother to write this out--it will just be left as zero.
   off += symsize;
 
-  for (Input_objects::Object_list::const_iterator p = input_objects->begin();
-       p != input_objects->end();
+  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
+       p != input_objects->relobj_end();
        ++p)
     {
       Task_lock_obj<Object> tlo(**p);
@@ -956,22 +957,22 @@ Close_task_runner::run(Workqueue*)
 
 template
 Output_section*
-Layout::layout<32, false>(Object* object, unsigned int shndx, const char* name,
+Layout::layout<32, false>(Relobj* object, unsigned int shndx, const char* name,
                          const elfcpp::Shdr<32, false>& shdr, off_t*);
 
 template
 Output_section*
-Layout::layout<32, true>(Object* object, unsigned int shndx, const char* name,
+Layout::layout<32, true>(Relobj* object, unsigned int shndx, const char* name,
                         const elfcpp::Shdr<32, true>& shdr, off_t*);
 
 template
 Output_section*
-Layout::layout<64, false>(Object* object, unsigned int shndx, const char* name,
+Layout::layout<64, false>(Relobj* object, unsigned int shndx, const char* name,
                          const elfcpp::Shdr<64, false>& shdr, off_t*);
 
 template
 Output_section*
-Layout::layout<64, true>(Object* object, unsigned int shndx, const char* name,
+Layout::layout<64, true>(Relobj* object, unsigned int shndx, const char* name,
                         const elfcpp::Shdr<64, true>& shdr, off_t*);
 
 
index c96d47da10af806c812413fe3f5f61de5d3904f6..bb2b644bd65ebdbb04f0aa75bc0440eb406705b6 100644 (file)
@@ -70,7 +70,7 @@ class Layout
   // output section.
   template<int size, bool big_endian>
   Output_section*
-  layout(Object *object, unsigned int shndx, const char* name,
+  layout(Relobj *object, unsigned int shndx, const char* name,
         const elfcpp::Shdr<size, big_endian>& shdr, off_t* offset);
 
   // Add an Output_section_data to the layout.  This is used for
index 4e7f04c1dddff5156925a4809bedcd8385b1cccb..22e89a9604a2ea9b97fa739bd65d3f59d253f7b5 100644 (file)
@@ -6,25 +6,25 @@
 #include <cstring>
 #include <cassert>
 
-#include "object.h"
 #include "target-select.h"
 #include "layout.h"
 #include "output.h"
+#include "symtab.h"
+#include "object.h"
+#include "dynobj.h"
 
 namespace gold
 {
 
-// Class Object.
-
-// Class Sized_object.
+// Class Sized_relobj.
 
 template<int size, bool big_endian>
-Sized_object<size, big_endian>::Sized_object(
+Sized_relobj<size, big_endian>::Sized_relobj(
     const std::string& name,
     Input_file* input_file,
     off_t offset,
     const elfcpp::Ehdr<size, big_endian>& ehdr)
-  : Object(name, input_file, false, offset),
+  : Relobj(name, input_file, offset),
     section_headers_(NULL),
     flags_(ehdr.get_e_flags()),
     shoff_(ehdr.get_e_shoff()),
@@ -53,7 +53,7 @@ Sized_object<size, big_endian>::Sized_object(
 }
 
 template<int size, bool big_endian>
-Sized_object<size, big_endian>::~Sized_object()
+Sized_relobj<size, big_endian>::~Sized_relobj()
 {
 }
 
@@ -61,21 +61,20 @@ Sized_object<size, big_endian>::~Sized_object()
 
 template<int size, bool big_endian>
 inline const unsigned char*
-Sized_object<size, big_endian>::section_header(unsigned int shnum)
+Sized_relobj<size, big_endian>::section_header(unsigned int shnum)
 {
   assert(shnum < this->shnum());
   off_t symtabshdroff = this->shoff_ + shnum * This::shdr_size;
   return this->get_view(symtabshdroff, This::shdr_size);
 }
 
-// Return the name of section SHNUM.
+// Return the name of section SHNUM.  The object must already be
+// locked.
 
 template<int size, bool big_endian>
 std::string
-Sized_object<size, big_endian>::do_section_name(unsigned int shnum)
+Sized_relobj<size, big_endian>::do_section_name(unsigned int shnum)
 {
-  Task_lock_obj<Object> tl(*this);
-
   // Read the section names.
   typename This::Shdr shdrnames(this->section_header(this->shstrndx_));
   const unsigned char* pnamesu = this->get_view(shdrnames.get_sh_offset(),
@@ -95,12 +94,27 @@ Sized_object<size, big_endian>::do_section_name(unsigned int shnum)
   return std::string(pnames + shdr.get_sh_name());
 }
 
+// Return a view of the contents of section SHNUM.  The object does
+// not have to be locked.
+
+template<int size, bool big_endian>
+const unsigned char*
+Sized_relobj<size, big_endian>::do_section_contents(unsigned int shnum,
+                                                   off_t* plen)
+{
+  Task_locker_obj<Object> tl(*this);
+
+  typename This::Shdr shdr(this->section_header(shnum));
+  *plen = shdr.get_sh_size();
+  return this->get_view(shdr.get_sh_offset(), shdr.get_sh_size());
+}
+
 // Set up an object file bsaed on the file header.  This sets up the
 // target and reads the section information.
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::setup(
+Sized_relobj<size, big_endian>::setup(
     const elfcpp::Ehdr<size, big_endian>& ehdr)
 {
   int machine = ehdr.get_e_machine();
@@ -159,7 +173,7 @@ Sized_object<size, big_endian>::setup(
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
+Sized_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
 {
   // Transfer our view of the section headers to SD.
   sd->section_headers = this->section_headers_;
@@ -236,7 +250,7 @@ Sized_object<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
 
 template<int size, bool big_endian>
 bool
-Sized_object<size, big_endian>::include_section_group(
+Sized_relobj<size, big_endian>::include_section_group(
     Layout* layout,
     unsigned int index,
     const elfcpp::Shdr<size, big_endian>& shdr,
@@ -251,7 +265,7 @@ Sized_object<size, big_endian>::include_section_group(
   // The first word contains flags.  We only care about COMDAT section
   // groups.  Other section groups are always included in the link
   // just like ordinary sections.
-  elfcpp::Elf_Word flags = elfcpp::read_elf_word<big_endian>(pword);
+  elfcpp::Elf_Word flags = elfcpp::Swap<32, big_endian>::readval(pword);
   if ((flags & elfcpp::GRP_COMDAT) == 0)
     return true;
 
@@ -345,7 +359,8 @@ Sized_object<size, big_endian>::include_section_group(
   size_t count = shdr.get_sh_size() / sizeof(elfcpp::Elf_Word);
   for (size_t i = 1; i < count; ++i)
     {
-      elfcpp::Elf_Word secnum = elfcpp::read_elf_word<big_endian>(pword + i);
+      elfcpp::Elf_Word secnum =
+       elfcpp::Swap<32, big_endian>::readval(pword + i);
       if (secnum >= this->shnum())
        {
          fprintf(stderr,
@@ -377,7 +392,7 @@ Sized_object<size, big_endian>::include_section_group(
 
 template<int size, bool big_endian>
 bool
-Sized_object<size, big_endian>::include_linkonce_section(
+Sized_relobj<size, big_endian>::include_linkonce_section(
     Layout* layout,
     const char* name,
     const elfcpp::Shdr<size, big_endian>&)
@@ -395,7 +410,9 @@ Sized_object<size, big_endian>::include_linkonce_section(
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::do_layout(Layout* layout,
+Sized_relobj<size, big_endian>::do_layout(const General_options& options,
+                                         Symbol_table* symtab,
+                                         Layout* layout,
                                          Read_symbols_data* sd)
 {
   unsigned int shnum = this->shnum();
@@ -415,7 +432,12 @@ Sized_object<size, big_endian>::do_layout(Layout* layout,
   // Keep track of which sections to omit.
   std::vector<bool> omit(shnum, false);
 
-  for (unsigned int i = 0; i < shnum; ++i, pshdrs += This::shdr_size)
+  const char warn_prefix[] = ".gnu.warning.";
+  const int warn_prefix_len = sizeof warn_prefix - 1;
+
+  // Skip the first, dummy, section.
+  pshdrs += This::shdr_size;
+  for (unsigned int i = 1; i < shnum; ++i, pshdrs += This::shdr_size)
     {
       typename This::Shdr shdr(pshdrs);
 
@@ -430,6 +452,13 @@ Sized_object<size, big_endian>::do_layout(Layout* layout,
 
       const char* name = pnames + shdr.get_sh_name();
 
+      if (strncmp(name, warn_prefix, warn_prefix_len) == 0)
+       {
+         symtab->add_warning(name + warn_prefix_len, this, i);
+         if (!options.is_relocatable())
+           omit[i] = true;
+       }
+
       bool discard = omit[i];
       if (!discard)
        {
@@ -469,7 +498,7 @@ Sized_object<size, big_endian>::do_layout(Layout* layout,
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
+Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
                                               Read_symbols_data* sd)
 {
   if (sd->symbols == NULL)
@@ -490,13 +519,12 @@ Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 
   this->symbols_ = new Symbol*[symcount];
 
-  const unsigned char* psyms = sd->symbols->data();
-  const elfcpp::Sym<size, big_endian>* syms =
-    reinterpret_cast<const elfcpp::Sym<size, big_endian>*>(psyms);
   const char* sym_names =
     reinterpret_cast<const char*>(sd->symbol_names->data());
-  symtab->add_from_object(this, syms, symcount, sym_names, 
-                         sd->symbol_names_size,  this->symbols_);
+  symtab->add_from_object<size, big_endian>(this, sd->symbols->data(),
+                                           symcount, sym_names, 
+                                           sd->symbol_names_size,
+                                           this->symbols_);
 
   delete sd->symbols;
   sd->symbols = NULL;
@@ -512,7 +540,7 @@ Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
 
 template<int size, bool big_endian>
 off_t
-Sized_object<size, big_endian>::do_finalize_local_symbols(off_t off,
+Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off,
                                                          Stringpool* pool)
 {
   if (this->symtab_shnum_ == 0)
@@ -598,9 +626,12 @@ Sized_object<size, big_endian>::do_finalize_local_symbols(off_t off,
                              + sym.get_st_value());
        }
 
-      pool->add(pnames + sym.get_st_name());
-      off += sym_size;
-      ++count;
+      if (sym.get_st_type() != elfcpp::STT_SECTION)
+       {
+         pool->add(pnames + sym.get_st_name());
+         off += sym_size;
+         ++count;
+       }
     }
 
   this->output_local_symbol_count_ = count;
@@ -612,7 +643,7 @@ Sized_object<size, big_endian>::do_finalize_local_symbols(off_t off,
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::write_local_symbols(Output_file* of,
+Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
                                                    const Stringpool* sympool)
 {
   if (this->symtab_shnum_ == 0)
@@ -655,7 +686,9 @@ Sized_object<size, big_endian>::write_local_symbols(Output_file* of,
   for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
     {
       elfcpp::Sym<size, big_endian> isym(psyms);
-      elfcpp::Sym_write<size, big_endian> osym(ov);
+
+      if (isym.get_st_type() == elfcpp::STT_SECTION)
+       continue;
 
       unsigned int st_shndx = isym.get_st_shndx();
       if (st_shndx < elfcpp::SHN_LORESERVE)
@@ -666,6 +699,8 @@ Sized_object<size, big_endian>::write_local_symbols(Output_file* of,
          st_shndx = mo[st_shndx].output_section->out_shndx();
        }
 
+      elfcpp::Sym_write<size, big_endian> osym(ov);
+
       osym.put_st_name(sympool->get_offset(pnames + isym.get_st_name()));
       osym.put_st_value(this->values_[i]);
       osym.put_st_size(isym.get_st_size());
@@ -683,10 +718,15 @@ Sized_object<size, big_endian>::write_local_symbols(Output_file* of,
 
 // Input_objects methods.
 
+// Add a regular relocatable object to the list.
+
 void
 Input_objects::add_object(Object* obj)
 {
-  this->object_list_.push_back(obj);
+  if (obj->is_dynamic())
+    this->dynobj_list_.push_back(static_cast<Dynobj*>(obj));
+  else
+    this->relobj_list_.push_back(static_cast<Relobj*>(obj));
 
   Target* target = obj->target();
   if (this->target_ == NULL)
@@ -697,9 +737,6 @@ Input_objects::add_object(Object* obj)
              program_name, obj->name().c_str());
       gold_exit(false);
     }
-
-  if (obj->is_dynamic())
-    this->any_dynamic_ = true;
 }
 
 // Relocate_info methods.
@@ -752,8 +789,8 @@ make_elf_sized_object(const std::string& name, Input_file* input_file,
 
   if (et == elfcpp::ET_REL)
     {
-      Sized_object<size, big_endian>* obj =
-       new Sized_object<size, big_endian>(name, input_file, offset, ehdr);
+      Sized_relobj<size, big_endian>* obj =
+       new Sized_relobj<size, big_endian>(name, input_file, offset, ehdr);
       obj->setup(ehdr);
       return obj;
     }
@@ -881,16 +918,16 @@ make_elf_object(const std::string& name, Input_file* input_file, off_t offset,
 // script to restrict this to only the ones for implemented targets.
 
 template
-class Sized_object<32, false>;
+class Sized_relobj<32, false>;
 
 template
-class Sized_object<32, true>;
+class Sized_relobj<32, true>;
 
 template
-class Sized_object<64, false>;
+class Sized_relobj<64, false>;
 
 template
-class Sized_object<64, true>;
+class Sized_relobj<64, true>;
 
 template
 struct Relocate_info<32, false>;
index 9b23de900054b7d5815366d94e2c0ff0362a86e7..e1f56d26f6eabe6baad3637488f84ba591807d6d 100644 (file)
@@ -4,14 +4,12 @@
 #define GOLD_OBJECT_H
 
 #include <cassert>
-#include <list>
 #include <string>
 #include <vector>
 
 #include "elfcpp.h"
 #include "fileread.h"
 #include "target.h"
-#include "symtab.h"
 
 namespace gold
 {
@@ -21,6 +19,7 @@ class Stringpool;
 class Layout;
 class Output_section;
 class Output_file;
+class Dynobj;
 
 // Data to pass from read_symbols() to add_symbols().
 
@@ -71,10 +70,9 @@ struct Read_relocs_data
   File_view* local_symbols;
 };
 
-// Object is an interface which represents either a 32-bit or a 64-bit
-// input object.  This can be a regular object file (ET_REL) or a
-// shared object (ET_DYN).  The actual instantiations are
-// Sized_object<32> and Sized_object<64>
+// Object is an abstract base class which represents either a 32-bit
+// or a 64-bit input object.  This can be a regular object file
+// (ET_REL) or a shared object (ET_DYN).
 
 class Object
 {
@@ -86,8 +84,7 @@ class Object
   Object(const std::string& name, Input_file* input_file, bool is_dynamic,
         off_t offset = 0)
     : name_(name), input_file_(input_file), offset_(offset),
-      shnum_(0), is_dynamic_(is_dynamic), target_(NULL),
-      map_to_output_()
+      is_dynamic_(is_dynamic), target_(NULL)
   { }
 
   virtual ~Object()
@@ -138,14 +135,124 @@ class Object
   // Pass sections which should be included in the link to the Layout
   // object, and record where the sections go in the output file.
   void
-  layout(Layout* lay, Read_symbols_data* sd)
-  { this->do_layout(lay, sd); }
+  layout(const General_options& options, Symbol_table* symtab,
+        Layout* layout, Read_symbols_data* sd)
+  { this->do_layout(options, symtab, layout, sd); }
 
   // Add symbol information to the global symbol table.
   void
   add_symbols(Symbol_table* symtab, Read_symbols_data* sd)
   { this->do_add_symbols(symtab, sd); }
 
+  // Return a view of the contents of a section.  Set *PLEN to the
+  // size.
+  const unsigned char*
+  section_contents(unsigned int shnum, off_t* plen)
+  { return this->do_section_contents(shnum, plen); }
+
+  // Return the name of a section given a section index.  This is only
+  // used for error messages.
+  std::string
+  section_name(unsigned int shnum)
+  { return this->do_section_name(shnum); }
+
+ protected:
+  // Read the symbols--implemented by child class.
+  virtual void
+  do_read_symbols(Read_symbols_data*) = 0;
+
+  // Lay out sections--implemented by child class.
+  virtual void
+  do_layout(const General_options&, Symbol_table*, Layout*,
+           Read_symbols_data*) = 0;
+
+  // Add symbol information to the global symbol table--implemented by
+  // child class.
+  virtual void
+  do_add_symbols(Symbol_table*, Read_symbols_data*) = 0;
+
+  // Return a view of the contents of a section.  Set *PLEN to the
+  // size.  Implemented by child class.
+  virtual const unsigned char*
+  do_section_contents(unsigned int shnum, off_t* plen) = 0;
+
+  // Get the name of a section--implemented by child class.
+  virtual std::string
+  do_section_name(unsigned int shnum) = 0;
+
+  // Get the file.
+  Input_file*
+  input_file() const
+  { return this->input_file_; }
+
+  // Get the offset into the file.
+  off_t
+  offset() const
+  { return this->offset_; }
+
+  // Get a view into the underlying file.
+  const unsigned char*
+  get_view(off_t start, off_t size)
+  { return this->input_file_->file().get_view(start + this->offset_, size); }
+
+  // Get a lasting view into the underlying file.
+  File_view*
+  get_lasting_view(off_t start, off_t size)
+  {
+    return this->input_file_->file().get_lasting_view(start + this->offset_,
+                                                     size);
+  }
+
+  // Read data from the underlying file.
+  void
+  read(off_t start, off_t size, void* p)
+  { this->input_file_->file().read(start + this->offset_, size, p); }
+
+  // Set the target.
+  void
+  set_target(Target* target)
+  { this->target_ = target; }
+
+ private:
+  // This class may not be copied.
+  Object(const Object&);
+  Object& operator=(const Object&);
+
+  // Name of object as printed to user.
+  std::string name_;
+  // For reading the file.
+  Input_file* input_file_;
+  // Offset within the file--0 for an object file, non-0 for an
+  // archive.
+  off_t offset_;
+  // Whether this is a dynamic object.
+  bool is_dynamic_;
+  // Target functions--may be NULL if the target is not known.
+  Target* target_;
+};
+
+// Implement sized_target inline for efficiency.  This approach breaks
+// static type checking, but is made safe using asserts.
+
+template<int size, bool big_endian>
+inline Sized_target<size, big_endian>*
+Object::sized_target(ACCEPT_SIZE_ENDIAN_ONLY)
+{
+  assert(this->target_->get_size() == size);
+  assert(this->target_->is_big_endian() ? big_endian : !big_endian);
+  return static_cast<Sized_target<size, big_endian>*>(this->target_);
+}
+
+// A regular object (ET_REL).  This is an abstract base class itself.
+// The implementations is the template class Sized_relobj.
+
+class Relobj : public Object
+{
+ public:
+  Relobj(const std::string& name, Input_file* input_file, off_t offset = 0)
+    : Object(name, input_file, false, offset)
+  { }
+
   // Read the relocs.
   void
   read_relocs(Read_relocs_data* rd)
@@ -192,12 +299,6 @@ class Object
     this->map_to_output_[shndx].offset = off;
   }
 
-  // Return the name of a section given a section index.  This is only
-  // used for error messages.
-  std::string
-  section_name(unsigned int shnum)
-  { return this->do_section_name(shnum); }
-
  protected:
   // What we need to know to map an input section to an output
   // section.  We keep an array of these, one for each input section,
@@ -211,15 +312,6 @@ class Object
     off_t offset;
   };
 
-  // Read the symbols--implemented by child class.
-  virtual void
-  do_read_symbols(Read_symbols_data*) = 0;
-
-  // Add symbol information to the global symbol table--implemented by
-  // child class.
-  virtual void
-  do_add_symbols(Symbol_table*, Read_symbols_data*) = 0;
-
   // Read the relocs--implemented by child class.
   virtual void
   do_read_relocs(Read_relocs_data*) = 0;
@@ -229,10 +321,6 @@ class Object
   do_scan_relocs(const General_options&, Symbol_table*, Layout*,
                 Read_relocs_data*) = 0;
 
-  // Lay out sections--implemented by child class.
-  virtual void
-  do_layout(Layout*, Read_symbols_data*) = 0;
-
   // Finalize local symbols--implemented by child class.
   virtual off_t
   do_finalize_local_symbols(off_t, Stringpool*) = 0;
@@ -243,25 +331,6 @@ class Object
   do_relocate(const General_options& options, const Symbol_table* symtab,
              const Layout*, Output_file* of) = 0;
 
-  // Get the name of a section--implemented by child class.
-  virtual std::string
-  do_section_name(unsigned int shnum) = 0;
-
-  // Get the file.
-  Input_file*
-  input_file() const
-  { return this->input_file_; }
-
-  // Get the offset into the file.
-  off_t
-  offset() const
-  { return this->offset_; }
-
-  // Get a view into the underlying file.
-  const unsigned char*
-  get_view(off_t start, off_t size)
-  { return this->input_file_->file().get_view(start + this->offset_, size); }
-
   // Get the number of sections.
   unsigned int
   shnum() const
@@ -272,66 +341,21 @@ class Object
   set_shnum(int shnum)
   { this->shnum_ = shnum; }
 
-  // Set the target.
-  void
-  set_target(Target* target)
-  { this->target_ = target; }
-
-  // Read data from the underlying file.
-  void
-  read(off_t start, off_t size, void* p)
-  { this->input_file_->file().read(start + this->offset_, size, p); }
-
-  // Get a lasting view into the underlying file.
-  File_view*
-  get_lasting_view(off_t start, off_t size)
-  {
-    return this->input_file_->file().get_lasting_view(start + this->offset_,
-                                                     size);
-  }
-
   // Return the vector mapping input sections to output sections.
   std::vector<Map_to_output>&
   map_to_output()
   { return this->map_to_output_; }
 
  private:
-  // This class may not be copied.
-  Object(const Object&);
-  Object& operator=(const Object&);
-
-  // Name of object as printed to user.
-  std::string name_;
-  // For reading the file.
-  Input_file* input_file_;
-  // Offset within the file--0 for an object file, non-0 for an
-  // archive.
-  off_t offset_;
   // Number of input sections.
   unsigned int shnum_;
-  // Whether this is a dynamic object.
-  bool is_dynamic_;
-  // Target functions--may be NULL if the target is not known.
-  Target* target_;
   // Mapping from input sections to output section.
   std::vector<Map_to_output> map_to_output_;
 };
 
-// Implement sized_target inline for efficiency.  This approach breaks
-// static type checking, but is made safe using asserts.
-
-template<int size, bool big_endian>
-inline Sized_target<size, big_endian>*
-Object::sized_target(ACCEPT_SIZE_ENDIAN_ONLY)
-{
-  assert(this->target_->get_size() == size);
-  assert(this->target_->is_big_endian() ? big_endian : !big_endian);
-  return static_cast<Sized_target<size, big_endian>*>(this->target_);
-}
-
 // Implement Object::output_section inline for efficiency.
 inline Output_section*
-Object::output_section(unsigned int shnum, off_t* poff)
+Relobj::output_section(unsigned int shnum, off_t* poff)
 {
   assert(shnum < this->map_to_output_.size());
   const Map_to_output& mo(this->map_to_output_[shnum]);
@@ -342,13 +366,13 @@ Object::output_section(unsigned int shnum, off_t* poff)
 // A regular object file.  This is size and endian specific.
 
 template<int size, bool big_endian>
-class Sized_object : public Object
+class Sized_relobj : public Relobj
 {
  public:
-  Sized_object(const std::string& name, Input_file* input_file, off_t offset,
+  Sized_relobj(const std::string& name, Input_file* input_file, off_t offset,
               const typename elfcpp::Ehdr<size, big_endian>&);
 
-  ~Sized_object();
+  ~Sized_relobj();
 
   // Set up the object file based on the ELF header.
   void
@@ -373,7 +397,8 @@ class Sized_object : public Object
 
   // Lay out the input sections.
   void
-  do_layout(Layout*, Read_symbols_data*);
+  do_layout(const General_options&, Symbol_table*, Layout*,
+           Read_symbols_data*);
 
   // Finalize the local symbols.
   off_t
@@ -388,6 +413,11 @@ class Sized_object : public Object
   std::string
   do_section_name(unsigned int shnum);
 
+  // Return a view of the contents of a section.  Set *PLEN to the
+  // size.
+  const unsigned char*
+  do_section_contents(unsigned int shnum, off_t* plen);
+
   // Return the appropriate Sized_target structure.
   Sized_target<size, big_endian>*
   sized_target()
@@ -398,12 +428,8 @@ class Sized_object : public Object
   }
 
  private:
-  // This object may not be copied.
-  Sized_object(const Sized_object&);
-  Sized_object& operator=(const Sized_object&);
-
   // For convenience.
-  typedef Sized_object<size, big_endian> This;
+  typedef Sized_relobj<size, big_endian> This;
   static const int ehdr_size = elfcpp::Elf_sizes<size>::ehdr_size;
   static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
   static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
@@ -477,11 +503,16 @@ class Input_objects
 {
  public:
   Input_objects()
-    : object_list_(), target_(NULL), any_dynamic_(false)
+    : relobj_list_(), target_(NULL)
   { }
 
-  // The type of the list of input objects.
-  typedef std::list<Object*> Object_list;
+  // The type of the list of input relocateable objects.
+  typedef std::vector<Relobj*> Relobj_list;
+  typedef Relobj_list::const_iterator Relobj_iterator;
+
+  // The type of the list of input dynamic objects.
+  typedef std::vector<Dynobj*> Dynobj_list;
+  typedef Dynobj_list::const_iterator Dynobj_iterator;
 
   // Add an object to the list.
   void
@@ -492,27 +523,38 @@ class Input_objects
   target() const
   { return this->target_; }
 
-  // Iterate over all objects.
-  Object_list::const_iterator
-  begin() const
-  { return this->object_list_.begin(); }
+  // Iterate over all regular objects.
+
+  Relobj_iterator
+  relobj_begin() const
+  { return this->relobj_list_.begin(); }
+
+  Relobj_iterator
+  relobj_end() const
+  { return this->relobj_list_.end(); }
+
+  // Iterate over all dynamic objects.
+
+  Dynobj_iterator
+  dynobj_begin() const
+  { return this->dynobj_list_.begin(); }
 
-  Object_list::const_iterator
-  end() const
-  { return this->object_list_.end(); }
+  Dynobj_iterator
+  dynobj_end() const
+  { return this->dynobj_list_.end(); }
 
   // Return whether we have seen any dynamic objects.
   bool
   any_dynamic() const
-  { return this->any_dynamic_; }
+  { return !this->dynobj_list_.empty(); }
 
  private:
   Input_objects(const Input_objects&);
   Input_objects& operator=(const Input_objects&);
 
-  Object_list object_list_;
+  Relobj_list relobj_list_;
+  Dynobj_list dynobj_list_;
   Target* target_;
-  bool any_dynamic_;
 };
 
 // Some of the information we pass to the relocation routines.  We
@@ -528,7 +570,7 @@ struct Relocate_info
   // Layout.
   const Layout* layout;
   // Object being relocated.
-  Sized_object<size, big_endian>* object;
+  Sized_relobj<size, big_endian>* object;
   // Number of local symbols.
   unsigned int local_symbol_count;
   // Values of local symbols.
index 220a4f6b9e5bc0f250dd937293e543ab65a25796..40d58668c0771258bcc5d1c438eee03545b3a00c 100644 (file)
@@ -399,7 +399,7 @@ Output_section_got<size, big_endian>::Got_entry::write(unsigned char* pov)
     }
 
   Valtype* povv = reinterpret_cast<Valtype*>(pov);
-  Swap<size, big_endian>::writeval(povv, val);
+  elfcpp::Swap<size, big_endian>::writeval(povv, val);
 }
 
 // Output_section_data methods.
@@ -509,7 +509,7 @@ Output_section::~Output_section()
 
 template<int size, bool big_endian>
 off_t
-Output_section::add_input_section(Object* object, unsigned int shndx,
+Output_section::add_input_section(Relobj* object, unsigned int shndx,
                                  const char* secname,
                                  const elfcpp::Shdr<size, big_endian>& shdr)
 {
@@ -1091,7 +1091,7 @@ Output_file::close()
 template
 off_t
 Output_section::add_input_section<32, false>(
-    Object* object,
+    Relobj* object,
     unsigned int shndx,
     const char* secname,
     const elfcpp::Shdr<32, false>& shdr);
@@ -1099,7 +1099,7 @@ Output_section::add_input_section<32, false>(
 template
 off_t
 Output_section::add_input_section<32, true>(
-    Object* object,
+    Relobj* object,
     unsigned int shndx,
     const char* secname,
     const elfcpp::Shdr<32, true>& shdr);
@@ -1107,7 +1107,7 @@ Output_section::add_input_section<32, true>(
 template
 off_t
 Output_section::add_input_section<64, false>(
-    Object* object,
+    Relobj* object,
     unsigned int shndx,
     const char* secname,
     const elfcpp::Shdr<64, false>& shdr);
@@ -1115,7 +1115,7 @@ Output_section::add_input_section<64, false>(
 template
 off_t
 Output_section::add_input_section<64, true>(
-    Object* object,
+    Relobj* object,
     unsigned int shndx,
     const char* secname,
     const elfcpp::Shdr<64, true>& shdr);
index 5c72c02608d474a13885bae8e1933bfb98b2db21..dc1653a987ccf9a46a252252c65799ccb49beae2 100644 (file)
@@ -504,7 +504,7 @@ class Output_section : public Output_data
   // object OBJECT.  Return the offset within the output section.
   template<int size, bool big_endian>
   off_t
-  add_input_section(Object* object, unsigned int shndx, const char *name,
+  add_input_section(Relobj* object, unsigned int shndx, const char *name,
                    const elfcpp::Shdr<size, big_endian>& shdr);
 
   // Add generated data ODATA to this output section.
@@ -613,7 +613,7 @@ class Output_section : public Output_data
       : shndx_(0), p2align_(0), data_size_(0)
     { this->u_.object = NULL; }
 
-    Input_section(Object* object, unsigned int shndx, off_t data_size,
+    Input_section(Relobj* object, unsigned int shndx, off_t data_size,
                  uint64_t addralign)
       : shndx_(shndx),
        p2align_(ffsll(static_cast<long long>(addralign))),
@@ -665,7 +665,7 @@ class Output_section : public Output_data
     {
       // If shndx_ != -1U, this points to the object which holds the
       // input section.
-      Object* object;
+      Relobj* object;
       // If shndx_ == -1U, this is the data to write out.
       Output_section_data* posd;
     } u_;
index 522e25a5e2db017e064b78afe13766a608456ef1..4f00da433c0c854a2c8622f730e0f6f7142bac28 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-11-03 10:45-0800\n"
+"POT-Creation-Date: 2006-11-06 13:40-0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -51,7 +51,7 @@ msgstr ""
 msgid "%s: %s: bad extended name entry at header %ld\n"
 msgstr ""
 
-#: archive.cc:279 archive.cc:292
+#: archive.cc:280 archive.cc:293
 #, c-format
 msgid "%s: %s: member at %ld is not an ELF object"
 msgstr ""
@@ -81,12 +81,12 @@ msgstr ""
 msgid "%s: %s: file too short: read only %lld of %lld bytes at %lld\n"
 msgstr ""
 
-#: fileread.cc:323
+#: fileread.cc:327
 #, c-format
 msgid "%s: cannot find %s\n"
 msgstr ""
 
-#: fileread.cc:331
+#: fileread.cc:335
 #, c-format
 msgid "%s: cannot open %s: %s\n"
 msgstr ""
@@ -205,103 +205,103 @@ msgstr ""
 msgid "%s: %s: bad e_shentsize field (%d != %d)\n"
 msgstr ""
 
-#: object.cc:89 object.cc:329 object.cc:425
+#: object.cc:88 object.cc:343 object.cc:447
 #, c-format
 msgid "%s: %s: bad section name offset for section %u: %lu\n"
 msgstr ""
 
-#: object.cc:112
+#: object.cc:126
 #, c-format
 msgid "%s: %s: unsupported ELF machine number %d\n"
 msgstr ""
 
-#: object.cc:207
+#: object.cc:221
 #, c-format
 msgid "%s: %s: invalid symbol table name index: %u\n"
 msgstr ""
 
-#: object.cc:215
+#: object.cc:229
 #, c-format
 msgid "%s: %s: symbol table name section has wrong type: %u\n"
 msgstr ""
 
-#: object.cc:267
+#: object.cc:281
 #, c-format
 msgid "%s: %s: section group %u link %u out of range\n"
 msgstr ""
 
-#: object.cc:277
+#: object.cc:291
 #, c-format
 msgid "%s: %s: section group %u info %u out of range\n"
 msgstr ""
 
-#: object.cc:288
+#: object.cc:302
 #, c-format
 msgid "%s; %s: symtab section %u link %u out of range\n"
 msgstr ""
 
-#: object.cc:304
+#: object.cc:318
 #, c-format
 msgid "%s: %s: symbol %u name offset %u out of range\n"
 msgstr ""
 
-#: object.cc:352
+#: object.cc:367
 #, c-format
 msgid "%s: %s: section %u in section group %u out of range"
 msgstr ""
 
-#: object.cc:486
+#: object.cc:515
 #, c-format
 msgid "%s: %s: size of symbols is not multiple of symbol size\n"
 msgstr ""
 
-#: object.cc:573
+#: object.cc:601
 #, c-format
 msgid "%s: %s: unknown section index %u for local symbol %u\n"
 msgstr ""
 
-#: object.cc:584
+#: object.cc:612
 #, c-format
 msgid "%s: %s: local symbol %u section index %u out of range\n"
 msgstr ""
 
 #. elfcpp::ET_DYN
-#: object.cc:763
+#: object.cc:800
 #, c-format
 msgid "%s: %s: dynamic objects are not yet supported\n"
 msgstr ""
 
-#: object.cc:787 object.cc:840 object.cc:861
+#: object.cc:824 object.cc:877 object.cc:898
 #, c-format
 msgid "%s: %s: ELF file too short\n"
 msgstr ""
 
-#: object.cc:796
+#: object.cc:833
 #, c-format
 msgid "%s: %s: invalid ELF version 0\n"
 msgstr ""
 
-#: object.cc:799
+#: object.cc:836
 #, c-format
 msgid "%s: %s: unsupported ELF version %d\n"
 msgstr ""
 
-#: object.cc:807
+#: object.cc:844
 #, c-format
 msgid "%s: %s: invalid ELF class 0\n"
 msgstr ""
 
-#: object.cc:814
+#: object.cc:851
 #, c-format
 msgid "%s: %s: unsupported ELF class %d\n"
 msgstr ""
 
-#: object.cc:822
+#: object.cc:859
 #, c-format
 msgid "%s: %s: invalid ELF data encoding\n"
 msgstr ""
 
-#: object.cc:829
+#: object.cc:866
 #, c-format
 msgid "%s: %s: unsupported ELF data encoding %d\n"
 msgstr ""
@@ -436,13 +436,13 @@ msgstr ""
 msgid "%s: %s: close: %s\n"
 msgstr ""
 
-#: readsyms.cc:84
+#: readsyms.cc:85
 #, c-format
 msgid "%s: %s: ordinary object found in input group\n"
 msgstr ""
 
 #. Here we have to handle any other input file types we need.
-#: readsyms.cc:126
+#: readsyms.cc:129
 #, c-format
 msgid "%s: %s: not an object or archive\n"
 msgstr ""
@@ -477,21 +477,26 @@ msgstr ""
 msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
 msgstr ""
 
-#: symtab.cc:429
+#: symtab.cc:432
 #, c-format
 msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
 msgstr ""
 
-#: symtab.cc:446
+#: symtab.cc:449
 #, c-format
 msgid "%s: %s: bad global symbol name offset %u at %lu\n"
 msgstr ""
 
-#: symtab.cc:854 symtab.cc:989
+#: symtab.cc:865 symtab.cc:1004
 #, c-format
 msgid "%s: %s: unsupported symbol section 0x%x\n"
 msgstr ""
 
+#: symtab.cc:1114
+#, c-format
+msgid "%s: %s: warning: %s\n"
+msgstr ""
+
 #: target-reloc.h:181
 #, c-format
 msgid "%s: %s: reloc has bad offset %zu\n"
index 9ff7ab7d2b14fed605877f22ac1391ee359d921e..c120fcb7ccdaa8fe257a4d2bb5b723f1c747ce30 100644 (file)
@@ -7,6 +7,7 @@
 #include "elfcpp.h"
 #include "options.h"
 #include "dirsearch.h"
+#include "symtab.h"
 #include "object.h"
 #include "archive.h"
 #include "readsyms.h"
@@ -91,7 +92,8 @@ Read_symbols::run(Workqueue* workqueue)
 
          Read_symbols_data* sd = new Read_symbols_data;
          obj->read_symbols(sd);
-         workqueue->queue_front(new Add_symbols(this->input_objects_,
+         workqueue->queue_front(new Add_symbols(this->options_,
+                                                this->input_objects_,
                                                 this->symtab_, this->layout_,
                                                 obj, sd,
                                                 this->this_blocker_,
@@ -111,7 +113,8 @@ Read_symbols::run(Workqueue* workqueue)
          // This is an archive.
          Archive* arch = new Archive(this->input_.file().name(), input_file);
          arch->setup();
-         workqueue->queue(new Add_archive_symbols(this->symtab_,
+         workqueue->queue(new Add_archive_symbols(this->options_,
+                                                  this->symtab_,
                                                   this->layout_,
                                                   this->input_objects_,
                                                   arch,
@@ -159,7 +162,8 @@ Read_symbols::do_group(Workqueue* workqueue)
     }
 
   const int saw_undefined = this->symtab_->saw_undefined();
-  workqueue->queue(new Finish_group(this->input_objects_,
+  workqueue->queue(new Finish_group(this->options_,
+                                   this->input_objects_,
                                    this->symtab_,
                                    this->layout_,
                                    input_group,
@@ -217,7 +221,8 @@ void
 Add_symbols::run(Workqueue*)
 {
   this->input_objects_->add_object(this->object_);
-  this->object_->layout(this->layout_, this->sd_);
+  this->object_->layout(this->options_, this->symtab_, this->layout_,
+                       this->sd_);
   this->object_->add_symbols(this->symtab_, this->sd_);
   delete this->sd_;
   this->sd_ = NULL;
@@ -265,7 +270,7 @@ Finish_group::run(Workqueue*)
        {
          Task_lock_obj<Archive> tl(**p);
 
-         (*p)->add_symbols(this->symtab_, this->layout_,
+         (*p)->add_symbols(this->options_, this->symtab_, this->layout_,
                            this->input_objects_);
        }
     }
index 2348c3237c641860d5f6ff3063d6c4edc29f0c44..6631011eb4033c64473e1d4f9352eea1494f0771 100644 (file)
@@ -83,11 +83,12 @@ class Add_symbols : public Task
   // THIS_BLOCKER is used to prevent this task from running before the
   // one for the previous input file.  NEXT_BLOCKER is used to prevent
   // the next task from running.
-  Add_symbols(Input_objects* input_objects, Symbol_table* symtab,
-             Layout* layout, Object* object, Read_symbols_data* sd,
-             Task_token* this_blocker, Task_token* next_blocker)
-    : input_objects_(input_objects), symtab_(symtab), layout_(layout),
-      object_(object), sd_(sd), this_blocker_(this_blocker),
+  Add_symbols(const General_options& options, Input_objects* input_objects,
+             Symbol_table* symtab, Layout* layout, Object* object,
+             Read_symbols_data* sd, Task_token* this_blocker,
+             Task_token* next_blocker)
+    : options_(options), input_objects_(input_objects), symtab_(symtab),
+      layout_(layout), object_(object), sd_(sd), this_blocker_(this_blocker),
       next_blocker_(next_blocker)
   { }
 
@@ -107,6 +108,7 @@ class Add_symbols : public Task
 private:
   class Add_symbols_locker;
 
+  const General_options& options_;
   Input_objects* input_objects_;
   Symbol_table* symtab_;
   Layout* layout_;
@@ -153,13 +155,14 @@ class Input_group
 class Finish_group : public Task
 {
  public:
-  Finish_group(Input_objects* input_objects, Symbol_table* symtab,
-              Layout* layout, Input_group* input_group,
+  Finish_group(const General_options& options, Input_objects* input_objects,
+              Symbol_table* symtab, Layout* layout, Input_group* input_group,
               int saw_undefined, Task_token* this_blocker,
               Task_token* next_blocker)
-    : input_objects_(input_objects), symtab_(symtab), layout_(layout),
-      input_group_(input_group), saw_undefined_(saw_undefined),
-      this_blocker_(this_blocker), next_blocker_(next_blocker)
+    : options_(options), input_objects_(input_objects), symtab_(symtab),
+      layout_(layout), input_group_(input_group),
+      saw_undefined_(saw_undefined), this_blocker_(this_blocker),
+      next_blocker_(next_blocker)
   { }
 
   ~Finish_group();
@@ -176,6 +179,7 @@ class Finish_group : public Task
   run(Workqueue*);
 
  private:
+  const General_options& options_;
   Input_objects* input_objects_;
   Symbol_table* symtab_;
   Layout* layout_;
index ca5e380dd9e70ac3a5d7a3ff68c43a68d7bb06d4..7233266fa3f3c22f6418a3b6e55eb04182eec14a 100644 (file)
@@ -140,7 +140,7 @@ Relocate_task::run(Workqueue*)
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
+Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
 {
   rd->relocs.clear();
 
@@ -248,7 +248,7 @@ Sized_object<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::do_scan_relocs(const General_options& options,
+Sized_relobj<size, big_endian>::do_scan_relocs(const General_options& options,
                                               Symbol_table* symtab,
                                               Layout* layout,
                                               Read_relocs_data* rd)
@@ -285,7 +285,7 @@ Sized_object<size, big_endian>::do_scan_relocs(const General_options& options,
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::do_relocate(const General_options& options,
+Sized_relobj<size, big_endian>::do_relocate(const General_options& options,
                                            const Symbol_table* symtab,
                                            const Layout* layout,
                                            Output_file* of)
@@ -327,7 +327,7 @@ Sized_object<size, big_endian>::do_relocate(const General_options& options,
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::write_sections(const unsigned char* pshdrs,
+Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
                                               Output_file* of,
                                               Views* pviews)
 {
@@ -374,7 +374,7 @@ Sized_object<size, big_endian>::write_sections(const unsigned char* pshdrs,
 
 template<int size, bool big_endian>
 void
-Sized_object<size, big_endian>::relocate_sections(
+Sized_relobj<size, big_endian>::relocate_sections(
     const General_options& options,
     const Symbol_table* symtab,
     const Layout* layout,
@@ -475,72 +475,72 @@ Sized_object<size, big_endian>::relocate_sections(
 
 template
 void
-Sized_object<32, false>::do_read_relocs(Read_relocs_data* rd);
+Sized_relobj<32, false>::do_read_relocs(Read_relocs_data* rd);
 
 template
 void
-Sized_object<32, true>::do_read_relocs(Read_relocs_data* rd);
+Sized_relobj<32, true>::do_read_relocs(Read_relocs_data* rd);
 
 template
 void
-Sized_object<64, false>::do_read_relocs(Read_relocs_data* rd);
+Sized_relobj<64, false>::do_read_relocs(Read_relocs_data* rd);
 
 template
 void
-Sized_object<64, true>::do_read_relocs(Read_relocs_data* rd);
+Sized_relobj<64, true>::do_read_relocs(Read_relocs_data* rd);
 
 template
 void
-Sized_object<32, false>::do_scan_relocs(const General_options& options,
+Sized_relobj<32, false>::do_scan_relocs(const General_options& options,
                                        Symbol_table* symtab,
                                        Layout* layout,
                                        Read_relocs_data* rd);
 
 template
 void
-Sized_object<32, true>::do_scan_relocs(const General_options& options,
+Sized_relobj<32, true>::do_scan_relocs(const General_options& options,
                                       Symbol_table* symtab,
                                       Layout* layout,
                                       Read_relocs_data* rd);
 
 template
 void
-Sized_object<64, false>::do_scan_relocs(const General_options& options,
+Sized_relobj<64, false>::do_scan_relocs(const General_options& options,
                                        Symbol_table* symtab,
                                        Layout* layout,
                                        Read_relocs_data* rd);
 
 template
 void
-Sized_object<64, true>::do_scan_relocs(const General_options& options,
+Sized_relobj<64, true>::do_scan_relocs(const General_options& options,
                                       Symbol_table* symtab,
                                       Layout* layout,
                                       Read_relocs_data* rd);
 
 template
 void
-Sized_object<32, false>::do_relocate(const General_options& options,
+Sized_relobj<32, false>::do_relocate(const General_options& options,
                                     const Symbol_table* symtab,
                                     const Layout* layout,
                                     Output_file* of);
 
 template
 void
-Sized_object<32, true>::do_relocate(const General_options& options,
+Sized_relobj<32, true>::do_relocate(const General_options& options,
                                    const Symbol_table* symtab,
                                    const Layout* layout,
                                    Output_file* of);
 
 template
 void
-Sized_object<64, false>::do_relocate(const General_options& options,
+Sized_relobj<64, false>::do_relocate(const General_options& options,
                                     const Symbol_table* symtab,
                                     const Layout* layout,
                                     Output_file* of);
 
 template
 void
-Sized_object<64, true>::do_relocate(const General_options& options,
+Sized_relobj<64, true>::do_relocate(const General_options& options,
                                    const Symbol_table* symtab,
                                    const Layout* layout,
                                    Output_file* of);
index f8f07b8b19e9b4cc65d32b4ff215abf709dac98a..9b0518e5d90d1ee5f3538fc8d087f77fbc93f1a8 100644 (file)
@@ -10,7 +10,7 @@
 namespace gold
 {
 
-class Object;
+class Relobj;
 class Read_relocs_data;
 class Stringpool;
 class Layout;
@@ -25,7 +25,7 @@ class Read_relocs : public Task
   // SYMTAB_LOCK is used to lock the symbol table.  BLOCKER should be
   // unblocked when the Scan_relocs task completes.
   Read_relocs(const General_options& options, Symbol_table* symtab,
-             Layout* layout, Object* object, Task_token* symtab_lock,
+             Layout* layout, Relobj* object, Task_token* symtab_lock,
              Task_token* blocker)
     : options_(options), symtab_(symtab), layout_(layout), object_(object),
       symtab_lock_(symtab_lock), blocker_(blocker)
@@ -46,7 +46,7 @@ class Read_relocs : public Task
   const General_options& options_;
   Symbol_table* symtab_;
   Layout* layout_;
-  Object* object_;
+  Relobj* object_;
   Task_token* symtab_lock_;
   Task_token* blocker_;
 };
@@ -60,7 +60,7 @@ class Scan_relocs : public Task
   // SYMTAB_LOCK is used to lock the symbol table.  BLOCKER should be
   // unblocked when the task completes.
   Scan_relocs(const General_options& options, Symbol_table* symtab,
-             Layout* layout, Object* object, Read_relocs_data* rd,
+             Layout* layout, Relobj* object, Read_relocs_data* rd,
              Task_token* symtab_lock, Task_token* blocker)
     : options_(options), symtab_(symtab), layout_(layout), object_(object),
       rd_(rd), symtab_lock_(symtab_lock), blocker_(blocker)
@@ -83,7 +83,7 @@ class Scan_relocs : public Task
   const General_options& options_;
   Symbol_table* symtab_;
   Layout* layout_;
-  Object* object_;
+  Relobj* object_;
   Read_relocs_data* rd_;
   Task_token* symtab_lock_;
   Task_token* blocker_;
@@ -95,7 +95,7 @@ class Relocate_task : public Task
 {
  public:
   Relocate_task(const General_options& options, const Symbol_table* symtab,
-               const Layout* layout, Object* object, Output_file* of,
+               const Layout* layout, Relobj* object, Output_file* of,
                Task_token* final_blocker)
     : options_(options), symtab_(symtab), layout_(layout), object_(object),
       of_(of), final_blocker_(final_blocker)
@@ -118,327 +118,11 @@ class Relocate_task : public Task
   const General_options& options_;
   const Symbol_table* symtab_;
   const Layout* layout_;
-  Object* object_;
+  Relobj* object_;
   Output_file* of_;
   Task_token* final_blocker_;
 };
 
-// Integer swapping routines used by relocation functions.  FIXME:
-// Maybe these should be more general, and/or shared with elfcpp.
-
-// Endian simply indicates whether the host is big endian or not,
-// based on the results of the configure script.
-
-struct Endian
-{
- public:
-  // Used for template specializations.
-#ifdef WORDS_BIGENDIAN
-  static const bool host_big_endian = true;
-#else
-  static const bool host_big_endian = false;
-#endif
-};
-
-// Valtype_base is a template based on size (8, 16, 32, 64) which
-// defines a typedef Valtype for the unsigned integer of the specified
-// size.
-
-template<int size>
-struct Valtype_base;
-
-template<>
-struct Valtype_base<8>
-{
-  typedef unsigned char Valtype;
-};
-
-template<>
-struct Valtype_base<16>
-{
-  typedef uint16_t Valtype;
-};
-
-template<>
-struct Valtype_base<32>
-{
-  typedef uint32_t Valtype;
-};
-
-template<>
-struct Valtype_base<64>
-{
-  typedef uint64_t Valtype;
-};
-
-// Convert_host is a template based on size and on whether the host
-// and target have the same endianness.  It defines the type Valtype,
-// and defines a function convert_host which takes an argument of type
-// Valtype and swaps it if the host and target have different
-// endianness.
-
-template<int size, bool same_endian>
-struct Convert_host;
-
-template<int size>
-struct Convert_host<size, true>
-{
-  typedef typename Valtype_base<size>::Valtype Valtype;
-
-  static inline Valtype
-  convert_host(Valtype v)
-  { return v; }
-};
-
-template<>
-struct Convert_host<8, false>
-{
-  typedef Valtype_base<8>::Valtype Valtype;
-
-  static inline Valtype
-  convert_host(Valtype v)
-  { return v; }
-};
-
-template<>
-struct Convert_host<16, false>
-{
-  typedef Valtype_base<16>::Valtype Valtype;
-
-  static inline Valtype
-  convert_host(Valtype v)
-  { return bswap_16(v); }
-};
-
-template<>
-struct Convert_host<32, false>
-{
-  typedef Valtype_base<32>::Valtype Valtype;
-
-  static inline Valtype
-  convert_host(Valtype v)
-  { return bswap_32(v); }
-};
-
-template<>
-struct Convert_host<64, false>
-{
-  typedef Valtype_base<64>::Valtype Valtype;
-
-  static inline Valtype
-  convert_host(Valtype v)
-  { return bswap_64(v); }
-};
-
-// Convert is a template based on size and on whether we have a big
-// endian target.  It defines Valtype and convert_host like
-// Convert_host.  That is, it is just like Convert_host except in the
-// meaning of the second template parameter.
-
-template<int size, bool big_endian>
-struct Convert
-{
-  typedef typename Valtype_base<size>::Valtype Valtype;
-
-  static inline Valtype
-  convert_host(Valtype v)
-  { return Convert_host<size, big_endian == Endian::host_big_endian>
-      ::convert_host(v); }
-};
-
-// Swap is a template based on size and on whether the target is big
-// endian.  It defines the type Valtype and the functions readval and
-// writeval.  The functions read and write values of the appropriate
-// size out of buffers, swapping them if necessary.
-
-template<int size, bool big_endian>
-struct Swap
-{
-  typedef typename Valtype_base<size>::Valtype Valtype;
-
-  static inline Valtype
-  readval(const Valtype* wv)
-  { return Convert<size, big_endian>::convert_host(*wv); }
-
-  static inline void
-  writeval(Valtype* wv, Valtype v)
-  { *wv = Convert<size, big_endian>::convert_host(v); }
-};
-
-// Swap_unaligned is a template based on size and on whether the
-// target is big endian.  It defines the type Valtype and the
-// functions readval_unaligned and writeval_unaligned.  The functions
-// read and write values of the appropriate size out of buffers which
-// may be misaligned.
-
-template<int size, bool big_endian>
-class Swap_unaligned;
-
-template<bool big_endian>
-class Swap_unaligned<8, big_endian>
-{
-public:
-  typedef typename Valtype_base<8>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  { return *wv; }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  { *wv = v; }
-};
-
-template<>
-class Swap_unaligned<16, false>
-{
-public:
-  typedef Valtype_base<16>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  {
-    return (wv[1] << 8) | wv[0];
-  }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  {
-    wv[1] = v >> 8;
-    wv[0] = v;
-  }
-};
-
-template<>
-class Swap_unaligned<16, true>
-{
-public:
-  typedef Valtype_base<16>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  {
-    return (wv[0] << 8) | wv[1];
-  }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  {
-    wv[0] = v >> 8;
-    wv[1] = v;
-  }
-};
-
-template<>
-class Swap_unaligned<32, false>
-{
-public:
-  typedef Valtype_base<32>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  {
-    return (wv[3] << 24) | (wv[2] << 16) | (wv[1] << 8) | wv[0];
-  }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  {
-    wv[3] = v >> 24;
-    wv[2] = v >> 16;
-    wv[1] = v >> 8;
-    wv[0] = v;
-  }
-};
-
-template<>
-class Swap_unaligned<32, true>
-{
-public:
-  typedef Valtype_base<32>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  {
-    return (wv[0] << 24) | (wv[1] << 16) | (wv[2] << 8) | wv[3];
-  }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  {
-    wv[0] = v >> 24;
-    wv[1] = v >> 16;
-    wv[2] = v >> 8;
-    wv[3] = v;
-  }
-};
-
-template<>
-class Swap_unaligned<64, false>
-{
-public:
-  typedef Valtype_base<64>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  {
-    return ((static_cast<Valtype>(wv[7]) << 56)
-           | (static_cast<Valtype>(wv[6]) << 48)
-           | (static_cast<Valtype>(wv[5]) << 40)
-           | (static_cast<Valtype>(wv[4]) << 32)
-           | (static_cast<Valtype>(wv[3]) << 24)
-           | (static_cast<Valtype>(wv[2]) << 16)
-           | (static_cast<Valtype>(wv[1]) << 8)
-           | static_cast<Valtype>(wv[0]));
-  }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  {
-    wv[7] = v >> 56;
-    wv[6] = v >> 48;
-    wv[5] = v >> 40;
-    wv[4] = v >> 32;
-    wv[3] = v >> 24;
-    wv[2] = v >> 16;
-    wv[1] = v >> 8;
-    wv[0] = v;
-  }
-};
-
-template<>
-class Swap_unaligned<64, true>
-{
-public:
-  typedef Valtype_base<64>::Valtype Valtype;
-
-  static inline Valtype
-  readval_unaligned(const unsigned char* wv)
-  {
-    return ((static_cast<Valtype>(wv[0]) << 56)
-           | (static_cast<Valtype>(wv[1]) << 48)
-           | (static_cast<Valtype>(wv[2]) << 40)
-           | (static_cast<Valtype>(wv[3]) << 32)
-           | (static_cast<Valtype>(wv[4]) << 24)
-           | (static_cast<Valtype>(wv[5]) << 16)
-           | (static_cast<Valtype>(wv[6]) << 8)
-           | static_cast<Valtype>(wv[7]));
-  }
-
-  static inline void
-  writeval_unaligned(unsigned char* wv, Valtype v)
-  {
-    wv[7] = v >> 56;
-    wv[6] = v >> 48;
-    wv[5] = v >> 40;
-    wv[4] = v >> 32;
-    wv[3] = v >> 24;
-    wv[2] = v >> 16;
-    wv[1] = v >> 8;
-    wv[0] = v;
-  }
-};
-
 // Standard relocation routines which are used on many targets.  Here
 // SIZE and BIG_ENDIAN refer to the target, not the relocation type.
 
@@ -450,25 +134,27 @@ private:
   // VALSIZE is the size of the value.
   template<int valsize>
   static inline void
-  rel(unsigned char* view, typename Swap<valsize, big_endian>::Valtype value)
+  rel(unsigned char* view,
+      typename elfcpp::Swap<valsize, big_endian>::Valtype value)
   {
-    typedef typename Swap<valsize, big_endian>::Valtype Valtype;
+    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
-    Valtype x = Swap<valsize, big_endian>::readval(wv);
-    Swap<valsize, big_endian>::writeval(wv, x + value);
+    Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
+    elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value);
   }
 
   // Do a simple PC relative relocation with the addend in the section
   // contents.  VALSIZE is the size of the value.
   template<int valsize>
   static inline void
-  pcrel(unsigned char* view, typename Swap<valsize, big_endian>::Valtype value,
+  pcrel(unsigned char* view,
+       typename elfcpp::Swap<valsize, big_endian>::Valtype value,
        typename elfcpp::Elf_types<size>::Elf_Addr address)
   {
-    typedef typename Swap<valsize, big_endian>::Valtype Valtype;
+    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
     Valtype* wv = reinterpret_cast<Valtype*>(view);
-    Valtype x = Swap<valsize, big_endian>::readval(wv);
-    Swap<valsize, big_endian>::writeval(wv, x + value - address);
+    Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
+    elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address);
   }
 
   typedef Relocate_functions<size, big_endian> This;
@@ -528,7 +214,7 @@ public:
   // Do a simple 64-bit REL relocation with the addend in the section
   // contents.
   static inline void
-  rel64(unsigned char* view, elfcpp::Elf_Word value)
+  rel64(unsigned char* view, elfcpp::Elf_Xword value)
   {
     This::template rel<64>(view, value);
   }
@@ -536,7 +222,7 @@ public:
   // Do a simple 64-bit PC relative REL relocation with the addend in
   // the section contents.
   static inline void
-  pcrel64(unsigned char* view, elfcpp::Elf_Word value,
+  pcrel64(unsigned char* view, elfcpp::Elf_Xword value,
          typename elfcpp::Elf_types<size>::Elf_Addr address)
   {
     This::template pcrel<64>(view, value, address);
index 9adb9defc5aed25e753a58f907cfca432fd85d4e..091144a75ca5ae135c9ff674d823c0503122fd04 100644 (file)
@@ -37,6 +37,7 @@ Symbol::init_fields(const char* name, const char* version,
   this->is_forwarder_ = false;
   this->in_dyn_ = false;
   this->has_got_offset_ = false;
+  this->has_warning_ = false;
 }
 
 // Initialize the fields in the base class Symbol for SYM in OBJECT.
@@ -159,7 +160,7 @@ Sized_symbol<size>::init(const char* name, Value_type value, Size_type symsize,
 
 Symbol_table::Symbol_table()
   : size_(0), saw_undefined_(0), offset_(0), table_(), namepool_(),
-    forwarders_(), commons_()
+    forwarders_(), commons_(), warnings_()
 {
 }
 
@@ -279,7 +280,7 @@ Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from
 
 template<int size, bool big_endian>
 Symbol*
-Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
+Symbol_table::add_from_object(Object* object,
                              const char *name,
                              const char *version, bool def,
                              const elfcpp::Sym<size, big_endian>& sym)
@@ -360,7 +361,9 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
        }
       else
        {
-         Sized_target<size, big_endian>* target = object->sized_target();
+         Sized_target<size, big_endian>* target =
+           object->sized_target SELECT_SIZE_ENDIAN_NAME(size, big_endian) (
+               SELECT_SIZE_ENDIAN_ONLY(size, big_endian));
          if (!target->has_make_symbol())
            ret = new Sized_symbol<size>();
          else
@@ -408,13 +411,13 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
   return ret;
 }
 
-// Add all the symbols in an object to the hash table.
+// Add all the symbols in a relocatable object to the hash table.
 
 template<int size, bool big_endian>
 void
 Symbol_table::add_from_object(
-    Sized_object<size, big_endian>* object,
-    const elfcpp::Sym<size, big_endian>* syms,
+    Relobj* object,
+    const unsigned char* syms,
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
@@ -433,7 +436,7 @@ Symbol_table::add_from_object(
 
   const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
 
-  const unsigned char* p = reinterpret_cast<const unsigned char*>(syms);
+  const unsigned char* p = syms;
   for (size_t i = 0; i < count; ++i, p += sym_size)
     {
       elfcpp::Sym<size, big_endian> sym(p);
@@ -512,7 +515,7 @@ Symbol_table::define_special_symbol(Target* target, const char* name,
   if (only_if_ref)
     {
       oldsym = this->lookup(name, NULL);
-      if (oldsym == NULL)
+      if (oldsym == NULL || !oldsym->is_undefined())
        return NULL;
       sym = NULL;
 
@@ -810,12 +813,20 @@ Symbol_table::define_symbols(const Layout* layout, Target* target, int count,
 off_t
 Symbol_table::finalize(off_t off, Stringpool* pool)
 {
+  off_t ret;
+
   if (this->size_ == 32)
-    return this->sized_finalize<32>(off, pool);
+    ret = this->sized_finalize<32>(off, pool);
   else if (this->size_ == 64)
-    return this->sized_finalize<64>(off, pool);
+    ret = this->sized_finalize<64>(off, pool);
   else
     abort();
+
+  // Now that we have the final symbol table, we can reliably note
+  // which symbols should get warnings.
+  this->warnings_.note_warnings(this);
+
+  return ret;
 }
 
 // Set the final value for all the symbols.  This is called after
@@ -856,15 +867,21 @@ Symbol_table::sized_finalize(off_t off, Stringpool* pool)
                gold_exit(false);
              }
 
-           if (shnum == elfcpp::SHN_UNDEF)
+           Object* symobj = sym->object();
+           if (symobj->is_dynamic())
+             {
+               value = 0;
+               shnum = elfcpp::SHN_UNDEF;
+             }
+           else if (shnum == elfcpp::SHN_UNDEF)
              value = 0;
            else if (shnum == elfcpp::SHN_ABS)
              value = sym->value();
            else
              {
+               Relobj* relobj = static_cast<Relobj*>(symobj);
                off_t secoff;
-               Output_section* os = sym->object()->output_section(shnum,
-                                                                  &secoff);
+               Output_section* os = relobj->output_section(shnum, &secoff);
 
                if (os == NULL)
                  {
@@ -973,8 +990,6 @@ Symbol_table::sized_write_globals(const Target*,
     {
       Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(p->second);
 
-      // FIXME: This repeats sized_finalize().
-
       unsigned int shndx;
       switch (sym->source())
        {
@@ -991,13 +1006,19 @@ Symbol_table::sized_write_globals(const Target*,
                gold_exit(false);
              }
 
-           if (shnum == elfcpp::SHN_UNDEF || shnum == elfcpp::SHN_ABS)
+           Object* symobj = sym->object();
+           if (symobj->is_dynamic())
+             {
+               // FIXME.
+               shndx = elfcpp::SHN_UNDEF;
+             }
+           else if (shnum == elfcpp::SHN_UNDEF || shnum == elfcpp::SHN_ABS)
              shndx = shnum;
            else
              {
+               Relobj* relobj = static_cast<Relobj*>(symobj);
                off_t secoff;
-               Output_section* os = sym->object()->output_section(shnum,
-                                                                  &secoff);
+               Output_section* os = relobj->output_section(shnum, &secoff);
                if (os == NULL)
                  continue;
 
@@ -1037,6 +1058,63 @@ Symbol_table::sized_write_globals(const Target*,
   of->write_output_view(this->offset_, this->output_count_ * sym_size, psyms);
 }
 
+// Warnings functions.
+
+// Add a new warning.
+
+void
+Warnings::add_warning(Symbol_table* symtab, const char* name, Object* obj,
+                     unsigned int shndx)
+{
+  name = symtab->canonicalize_name(name);
+  this->warnings_[name].set(obj, shndx);
+}
+
+// Look through the warnings and mark the symbols for which we should
+// warn.  This is called during Layout::finalize when we know the
+// sources for all the symbols.
+
+void
+Warnings::note_warnings(Symbol_table* symtab)
+{
+  for (Warning_table::iterator p = this->warnings_.begin();
+       p != this->warnings_.end();
+       ++p)
+    {
+      Symbol* sym = symtab->lookup(p->first, NULL);
+      if (sym != NULL
+         && sym->source() == Symbol::FROM_OBJECT
+         && sym->object() == p->second.object)
+       {
+         sym->set_has_warning();
+
+         // Read the section contents to get the warning text.  It
+         // would be nicer if we only did this if we have to actually
+         // issue a warning.  Unfortunately, warnings are issued as
+         // we relocate sections.  That means that we can not lock
+         // the object then, as we might try to issue the same
+         // warning multiple times simultaneously.
+         const unsigned char* c;
+         off_t len;
+         c = p->second.object->section_contents(p->second.shndx, &len);
+         p->second.set_text(reinterpret_cast<const char*>(c), len);
+       }
+    }
+}
+
+// Issue a warning.  This is called when we see a relocation against a
+// symbol for which has a warning.
+
+void
+Warnings::issue_warning(Symbol* sym, const std::string& location) const
+{
+  assert(sym->has_warning());
+  Warning_table::const_iterator p = this->warnings_.find(sym->name());
+  assert(p != this->warnings_.end());
+  fprintf(stderr, _("%s: %s: warning: %s\n"), program_name, location.c_str(),
+         p->second.text.c_str());
+}
+
 // Instantiate the templates we need.  We could use the configure
 // script to restrict this to only the ones needed for implemented
 // targets.
@@ -1044,8 +1122,8 @@ Symbol_table::sized_write_globals(const Target*,
 template
 void
 Symbol_table::add_from_object<32, true>(
-    Sized_object<32, true>* object,
-    const elfcpp::Sym<32, true>* syms,
+    Relobj* object,
+    const unsigned char* syms,
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
@@ -1054,8 +1132,8 @@ Symbol_table::add_from_object<32, true>(
 template
 void
 Symbol_table::add_from_object<32, false>(
-    Sized_object<32, false>* object,
-    const elfcpp::Sym<32, false>* syms,
+    Relobj* object,
+    const unsigned char* syms,
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
@@ -1064,8 +1142,8 @@ Symbol_table::add_from_object<32, false>(
 template
 void
 Symbol_table::add_from_object<64, true>(
-    Sized_object<64, true>* object,
-    const elfcpp::Sym<64, true>* syms,
+    Relobj* object,
+    const unsigned char* syms,
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
@@ -1074,8 +1152,8 @@ Symbol_table::add_from_object<64, true>(
 template
 void
 Symbol_table::add_from_object<64, false>(
-    Sized_object<64, false>* object,
-    const elfcpp::Sym<64, false>* syms,
+    Relobj* object,
+    const unsigned char* syms,
     size_t count,
     const char* sym_names,
     size_t sym_name_size,
index 2fa3396a5ce8cf3cf918ff108fd1e9edff7baf5f..f544e0664df2c8dd6347b2f99f44f4ed46d835a7 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "elfcpp.h"
 #include "stringpool.h"
+#include "object.h"
 
 #ifndef GOLD_SYMTAB_H
 #define GOLD_SYMTAB_H
@@ -18,14 +19,13 @@ namespace gold
 {
 
 class Object;
+class Relobj;
+class Dynobj;
 class Output_data;
 class Output_segment;
 class Output_file;
 class Target;
 
-template<int size, bool big_endian>
-class Sized_object;
-
 // The base class of an entry in the symbol table.  The symbol table
 // can have a lot of entries, so we don't want this class to big.
 // Size dependent fields can be found in the template class
@@ -40,7 +40,8 @@ class Symbol
   // sources of symbols we support.
   enum Source
   {
-    // Symbol defined in an input file--this is the most common case.
+    // Symbol defined in a relocatable or dynamic input file--this is
+    // the most common case.
     FROM_OBJECT,
     // Symbol defined in an Output_data, a special section created by
     // the target.
@@ -89,7 +90,8 @@ class Symbol
     return this->u_.from_object.object;
   }
 
-  // Return the index of the section in the input object file.
+  // Return the index of the section in the input relocatable or
+  // dynamic object file.
   unsigned int
   shnum() const
   {
@@ -167,12 +169,12 @@ class Symbol
   set_forwarder()
   { this->is_forwarder_ = true; }
 
-  // Return whether this symbol was seen in a dynamic object.
+  // Return whether this symbol was ever seen in a dynamic object.
   bool
   in_dyn() const
   { return this->in_dyn_; }
 
-  // Mark this symbol as seen in a dynamic object.
+  // Mark this symbol as having been seen in a dynamic object.
   void
   set_in_dyn()
   { this->in_dyn_ = true; }
@@ -207,6 +209,16 @@ class Symbol
   is_resolved_locally() const
   { return !this->in_dyn_; }
 
+  // Return whether this is a defined symbol (not undefined or
+  // common).
+  bool
+  is_defined() const
+  {
+    return (this->source_ != FROM_OBJECT
+           || (this->u_.from_object.shnum != elfcpp::SHN_UNDEF
+               && this->u_.from_object.shnum != elfcpp::SHN_COMMON));
+  }
+
   // Return whether this is an undefined symbol.
   bool
   is_undefined() const
@@ -218,14 +230,27 @@ class Symbol
   bool
   is_common() const
   {
-    return this->source_ == FROM_OBJECT && this->shnum() == elfcpp::SHN_COMMON;
+    return (this->source_ == FROM_OBJECT
+           && (this->u_.from_object.shnum == elfcpp::SHN_COMMON
+               || this->type_ == elfcpp::STT_COMMON));
   }
 
+  // Return whether there should be a warning for references to this
+  // symbol.
+  bool
+  has_warning() const
+  { return this->has_warning_; }
+
+  // Mark this symbol as having a warning.
+  void
+  set_has_warning()
+  { this->has_warning_ = true; }
+
  protected:
   // Instances of this class should always be created at a specific
   // size.
   Symbol()
-  { }
+  { memset(this, 0, sizeof *this); }
 
   // Initialize the general fields.
   void
@@ -317,7 +342,7 @@ class Symbol
   // Rest of symbol st_other field.
   unsigned int nonvis_ : 6;
   // The type of symbol.
-  Source source_ : 2;
+  Source source_ : 3;
   // True if this symbol always requires special target-specific
   // handling.
   bool is_target_special_ : 1;
@@ -335,6 +360,8 @@ class Symbol
   bool in_dyn_ : 1;
   // True if the symbol has an entry in the GOT section.
   bool has_got_offset_ : 1;
+  // True if there is a warning for this symbol.
+  bool has_warning_ : 1;
 };
 
 // The parts of a symbol which are size specific.  Using a template
@@ -484,6 +511,78 @@ struct Define_symbol_in_segment
   bool only_if_ref;
 };
 
+// This class manages warnings.  Warnings are a GNU extension.  When
+// we see a section named .gnu.warning.SYM in an object file, and if
+// we wind using the definition of SYM from that object file, then we
+// will issue a warning for any relocation against SYM from a
+// different object file.  The text of the warning is the contents of
+// the section.  This is not precisely the definition used by the old
+// GNU linker; the old GNU linker treated an occurrence of
+// .gnu.warning.SYM as defining a warning symbol.  A warning symbol
+// would trigger a warning on any reference.  However, it was
+// inconsistent in that a warning in a dynamic object only triggered
+// if there was no definition in a regular object.  This linker is
+// different in that we only issue a warning if we use the symbol
+// definition from the same object file as the warning section.
+
+class Warnings
+{
+ public:
+  Warnings()
+    : warnings_()
+  { }
+
+  // Add a warning for symbol NAME in section SHNDX in object OBJ.
+  void
+  add_warning(Symbol_table* symtab, const char* name, Object* obj,
+             unsigned int shndx);
+
+  // For each symbol for which we should give a warning, make a note
+  // on the symbol.
+  void
+  note_warnings(Symbol_table* symtab);
+
+  // Issue a warning for a reference to SYM at LOCATION.
+  void
+  issue_warning(Symbol* sym, const std::string& location) const;
+
+ private:
+  Warnings(const Warnings&);
+  Warnings& operator=(const Warnings&);
+
+  // What we need to know to get the warning text.
+  struct Warning_location
+  {
+    // The object the warning is in.
+    Object* object;
+    // The index of the warning section.
+    unsigned int shndx;
+    // The warning text if we have already loaded it.
+    std::string text;
+
+    Warning_location()
+      : object(NULL), shndx(0), text()
+    { }
+
+    void
+    set(Object* o, unsigned int s)
+    {
+      this->object = o;
+      this->shndx = s;
+    }
+
+    void
+    set_text(const char* t, off_t l)
+    { this->text.assign(t, l); }
+  };
+
+  // A mapping from warning symbol names (canonicalized in
+  // Symbol_table's namepool_ field) to 
+  typedef Unordered_map<const char*, Warning_location> Warning_table;
+
+  Warning_table warnings_;
+};
+
 // The main linker symbol table.
 
 class Symbol_table
@@ -493,14 +592,13 @@ class Symbol_table
 
   ~Symbol_table();
 
-  // Add COUNT external symbols from OBJECT 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.
+  // Add COUNT external symbols from the relocatable object OBJECT 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(Sized_object<size, big_endian>* object,
-                 const elfcpp::Sym<size, big_endian>* syms,
+  add_from_object(Relobj* object, const unsigned char* syms,
                  size_t count, const char* sym_names, size_t sym_name_size,
                  Symbol** sympointers);
 
@@ -577,6 +675,22 @@ class Symbol_table
   void
   allocate_commons(const General_options&, Layout*);
 
+  // Add a warning for symbol NAME in section SHNDX in object OBJ.
+  void
+  add_warning(const char* name, Object* obj, unsigned int shndx)
+  { this->warnings_.add_warning(this, name, obj, shndx); }
+
+  // Canonicalize a symbol name for use in the hash table.
+  const char*
+  canonicalize_name(const char* name)
+  { return this->namepool_.add(name); }
+
+  // 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
+  { this->warnings_.issue_warning(sym, location); }
+
   // 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
@@ -604,7 +718,7 @@ class Symbol_table
   // Add a symbol.
   template<int size, bool big_endian>
   Symbol*
-  add_from_object(Sized_object<size, big_endian>*, const char *name,
+  add_from_object(Object*, const char *name,
                  const char *version, bool def,
                  const elfcpp::Sym<size, big_endian>& sym);
 
@@ -720,6 +834,9 @@ class Symbol_table
   // symbol is no longer a common symbol.  It may also have become a
   // forwarder.
   Commons_type commons_;
+
+  // Manage symbol warnings.
+  Warnings warnings_;
 };
 
 // We inline get_sized_symbol for efficiency.
index ebaa8276cf05e5d5737472fde449e8c34ad8be3a..70692783e08a2314ddf1693ac8f8a3a46f184ef4 100644 (file)
@@ -44,7 +44,7 @@ scan_relocs(
     Symbol_table* symtab,
     Layout* layout,
     Target_type* target,
-    Sized_object<size, big_endian>* object,
+    Sized_relobj<size, big_endian>* object,
     const unsigned char* prelocs,
     size_t reloc_count,
     size_t local_count,
@@ -193,6 +193,9 @@ relocate_section(
                  sym->name());
          // gold_exit(false);
        }
+
+      if (sym != NULL && sym->has_warning())
+       relinfo->symtab->issue_warning(sym, relinfo->location(i, offset));
     }
 }
 
index b72998da359eab1eb0c2878969e744c325142f2b..8e00a4da5ab8472b2a68412a4cf82d99714daef7 100644 (file)
@@ -16,7 +16,6 @@
 #include <cassert>
 
 #include "elfcpp.h"
-#include "symtab.h"
 
 namespace gold
 {
@@ -24,9 +23,13 @@ namespace gold
 class General_options;
 class Object;
 template<int size, bool big_endian>
-class Sized_object;
+class Sized_relobj;
 template<int size, bool big_endian>
 struct Relocate_info;
+class Symbol;
+template<int size>
+class Sized_symbol;
+class Symbol_table;
 
 // The abstract class for target specific handling.
 
@@ -150,7 +153,7 @@ class Sized_target : public Target
   scan_relocs(const General_options& options,
              Symbol_table* symtab,
              Layout* layout,
-             Sized_object<size, big_endian>* object,
+             Sized_relobj<size, big_endian>* object,
              unsigned int sh_type,
              const unsigned char* prelocs,
              size_t reloc_count,