Lay out object file sections when we add the symbols to the symbol
authorIan Lance Taylor <iant@google.com>
Fri, 6 Oct 2006 20:40:16 +0000 (20:40 +0000)
committerIan Lance Taylor <iant@google.com>
Fri, 6 Oct 2006 20:40:16 +0000 (20:40 +0000)
table.

gold/archive.cc
gold/archive.h
gold/gold.cc
gold/layout.cc
gold/layout.h
gold/object.cc
gold/object.h
gold/po/gold.pot
gold/readsyms.cc
gold/readsyms.h
gold/resolve.cc

index 6019325..8639643 100644 (file)
@@ -218,7 +218,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, Input_objects* input_objects)
+Archive::add_symbols(Symbol_table* symtab, Layout* layout,
+                    Input_objects* input_objects)
 {
   size_t armap_size = this->armap_.size();
   std::vector<bool> seen;
@@ -253,7 +254,7 @@ Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects)
 
          // We want to include this object in the link.
          last = this->armap_[i].offset;
-         this->include_member(symtab, input_objects, last);
+         this->include_member(symtab, layout, input_objects, last);
          added_new_object = true;
        }
     }
@@ -264,8 +265,8 @@ Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects)
 // the member header.
 
 void
-Archive::include_member(Symbol_table* symtab, Input_objects* input_objects,
-                       off_t off)
+Archive::include_member(Symbol_table* symtab, Layout* layout,
+                       Input_objects* input_objects, off_t off)
 {
   std::string n;
   this->read_header(off, &n);
@@ -305,8 +306,10 @@ Archive::include_member(Symbol_table* symtab, Input_objects* input_objects,
 
   input_objects->add_object(obj);
 
-  Read_symbols_data sd = obj->read_symbols();
-  obj->add_symbols(symtab, sd);
+  Read_symbols_data sd;
+  obj->read_symbols(&sd);
+  obj->layout(layout, &sd);
+  obj->add_symbols(symtab, &sd);
 }
 
 // Add_archive_symbols methods.
@@ -354,7 +357,8 @@ Add_archive_symbols::locks(Workqueue* workqueue)
 void
 Add_archive_symbols::run(Workqueue*)
 {
-  this->archive_->add_symbols(this->symtab_, this->input_objects_);
+  this->archive_->add_symbols(this->symtab_, this->layout_,
+                             this->input_objects_);
 }
 
 } // End namespace gold.
index 14d1c3b..b2d4c46 100644 (file)
@@ -13,6 +13,7 @@ namespace gold
 
 class Input_file;
 class Input_objects;
+class Layout;
 class Symbol_table;
 
 // This class represents an archive--generally a libNAME.a file.
@@ -61,7 +62,7 @@ class Archive
   // Select members from the archive as needed and add them to the
   // link.
   void
-  add_symbols(Symbol_table*, Input_objects*);
+  add_symbols(Symbol_table*, Layout*, Input_objects*);
 
  private:
   Archive(const Archive&);
@@ -81,7 +82,7 @@ class Archive
 
   // Include an archive member in the link.
   void
-  include_member(Symbol_table*, Input_objects*, off_t off);
+  include_member(Symbol_table*, Layout*, Input_objects*, off_t off);
 
   // An entry in the archive map of symbols to object files.
   struct Armap_entry
@@ -108,11 +109,13 @@ class Archive
 class Add_archive_symbols : public Task
 {
  public:
-  Add_archive_symbols(Symbol_table* symtab, Input_objects* input_objects,
+  Add_archive_symbols(Symbol_table* symtab, Layout* layout,
+                     Input_objects* input_objects,
                      Archive* archive, Task_token* this_blocker,
                      Task_token* next_blocker)
-    : symtab_(symtab), input_objects_(input_objects), archive_(archive),
-      this_blocker_(this_blocker), next_blocker_(next_blocker)
+    : symtab_(symtab), layout_(layout), input_objects_(input_objects),
+      archive_(archive), this_blocker_(this_blocker),
+      next_blocker_(next_blocker)
   { }
 
   ~Add_archive_symbols();
@@ -132,6 +135,7 @@ class Add_archive_symbols : public Task
   class Add_archive_symbols_locker;
 
   Symbol_table* symtab_;
+  Layout* layout_;
   Input_objects* input_objects_;
   Archive* archive_;
   Task_token* this_blocker_;
index f403910..6874e1b 100644 (file)
@@ -70,7 +70,7 @@ queue_initial_tasks(const General_options& options,
                    const Dirsearch& search_path,
                    const Command_line::Input_argument_list& inputs,
                    Workqueue* workqueue, Input_objects* input_objects,
-                   Symbol_table* symtab)
+                   Symbol_table* symtab, Layout* layout)
 {
   if (inputs.empty())
     gold_fatal(_("no input files"), false);
@@ -86,13 +86,13 @@ queue_initial_tasks(const General_options& options,
     {
       Task_token* next_blocker = new Task_token();
       next_blocker->add_blocker();
-      workqueue->queue(new Read_symbols(options, input_objects, symtab,
+      workqueue->queue(new Read_symbols(options, input_objects, symtab, layout,
                                        search_path, *p, this_blocker,
                                        next_blocker));
       this_blocker = next_blocker;
     }
 
-  workqueue->queue(new Layout_task(options, input_objects, symtab,
+  workqueue->queue(new Layout_task(options, input_objects, symtab, layout,
                                   this_blocker));
 }
 
@@ -170,6 +170,9 @@ main(int argc, char** argv)
   // The symbol table.
   Symbol_table symtab;
 
+  // The layout object.
+  Layout layout(command_line.options());
+
   // Get the search path from the -L options.
   Dirsearch search_path;
   search_path.add(&workqueue, command_line.options().search_path());
@@ -177,7 +180,7 @@ main(int argc, char** argv)
   // Queue up the first set of tasks.
   queue_initial_tasks(command_line.options(), search_path,
                      command_line.inputs(), &workqueue, &input_objects,
-                     &symtab);
+                     &symtab, &layout);
 
   // Run the main task processing loop.
   workqueue.process();
index 2448bf8..61b6895 100644 (file)
@@ -45,15 +45,8 @@ Layout_task::locks(Workqueue*)
 void
 Layout_task::run(Workqueue* workqueue)
 {
-  // Nothing ever frees this.
-  Layout* layout = new Layout(this->options_);
-  layout->init();
-  for (Input_objects::Object_list::const_iterator p =
-        this->input_objects_->begin();
-       p != this->input_objects_->end();
-       ++p)
-    (*p)->layout(layout);
-  off_t file_size = layout->finalize(this->input_objects_, this->symtab_);
+  off_t file_size = this->layout_->finalize(this->input_objects_,
+                                           this->symtab_);
 
   // Now we know the final size of the output file and we know where
   // each piece of information goes.
@@ -62,7 +55,7 @@ Layout_task::run(Workqueue* workqueue)
 
   // Queue up the final set of tasks.
   gold::queue_final_tasks(this->options_, this->input_objects_,
-                         this->symtab_, layout, workqueue, of);
+                         this->symtab_, this->layout_, workqueue, of);
 }
 
 // Layout methods.
@@ -72,13 +65,6 @@ Layout::Layout(const General_options& options)
     section_name_map_(), segment_list_(), section_list_(),
     special_output_list_()
 {
-}
-
-// Prepare for doing layout.
-
-void
-Layout::init()
-{
   // Make space for more than enough segments for a typical file.
   // This is just for efficiency--it's OK if we wind up needing more.
   segment_list_.reserve(12);
index 930d2b9..028d714 100644 (file)
@@ -37,9 +37,10 @@ class Layout_task : public Task
   Layout_task(const General_options& options,
              const Input_objects* input_objects,
              Symbol_table* symtab,
+             Layout* layout,
              Task_token* this_blocker)
     : options_(options), input_objects_(input_objects), symtab_(symtab),
-      this_blocker_(this_blocker)
+      layout_(layout), this_blocker_(this_blocker)
   { }
 
   ~Layout_task();
@@ -62,6 +63,7 @@ class Layout_task : public Task
   const General_options& options_;
   const Input_objects* input_objects_;
   Symbol_table* symtab_;
+  Layout* layout_;
   Task_token* this_blocker_;
 };
 
@@ -72,10 +74,6 @@ class Layout
  public:
   Layout(const General_options& options);
 
-  // Initialize the object.
-  void
-  init();
-
   // Given an input section named NAME with data in SHDR from the
   // object file OBJECT, return the output section where this input
   // section should go.  Set *OFFSET to the offset within the output
index 6186f65..d8658e9 100644 (file)
@@ -44,6 +44,7 @@ Sized_object<size, big_endian>::Sized_object(
     off_t offset,
     const elfcpp::Ehdr<size, big_endian>& ehdr)
   : Object(name, input_file, false, offset),
+    section_headers_(NULL),
     flags_(ehdr.get_e_flags()),
     shoff_(ehdr.get_e_shoff()),
     shstrndx_(0),
@@ -105,6 +106,7 @@ Sized_object<size, big_endian>::setup(
       gold_exit(false);
     }
   this->set_target(target);
+
   unsigned int shnum = ehdr.get_e_shnum();
   unsigned int shstrndx = ehdr.get_e_shstrndx();
   if ((shnum == 0 || shstrndx == elfcpp::SHN_XINDEX)
@@ -122,12 +124,19 @@ Sized_object<size, big_endian>::setup(
   if (shnum == 0)
     return;
 
-  // Find the SHT_SYMTAB section.
-  const unsigned char* p = this->get_view (this->shoff_,
-                                          shnum * This::shdr_size);
+  // We store the section headers in a File_view until do_read_symbols.
+  this->section_headers_ = this->get_lasting_view(this->shoff_,
+                                                 shnum * This::shdr_size);
+
+  // Find the SHT_SYMTAB section.  The ELF standard says that maybe in
+  // the future there can be more than one SHT_SYMTAB section.  Until
+  // somebody figures out how that could work, we assume there is only
+  // one.
+  const unsigned char* p = this->section_headers_->data();
+
   // Skip the first section, which is always empty.
   p += This::shdr_size;
-  for (unsigned int i = 1; i < shnum; ++i)
+  for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size)
     {
       typename This::Shdr shdr(p);
       if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
@@ -135,29 +144,40 @@ Sized_object<size, big_endian>::setup(
          this->symtab_shnum_ = i;
          break;
        }
-      p += This::shdr_size;
     }
 }
 
-// Read the symbols and relocations from an object file.
+// Read the sections and symbols from an object file.
 
 template<int size, bool big_endian>
-Read_symbols_data
-Sized_object<size, big_endian>::do_read_symbols()
+void
+Sized_object<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_;
+  this->section_headers_ = NULL;
+
+  // Read the section names.
+  const unsigned char* pshdrs = sd->section_headers->data();
+  const unsigned char* pshdrnames = pshdrs + this->shstrndx_ * This::shdr_size;
+  typename This::Shdr shdrnames(pshdrnames);
+  sd->section_names_size = shdrnames.get_sh_size();
+  sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(),
+                                            sd->section_names_size);
+
   if (this->symtab_shnum_ == 0)
     {
       // No symbol table.  Weird but legal.
-      Read_symbols_data ret;
-      ret.symbols = NULL;
-      ret.symbols_size = 0;
-      ret.symbol_names = NULL;
-      ret.symbol_names_size = 0;
-      return ret;
+      sd->symbols = NULL;
+      sd->symbols_size = 0;
+      sd->symbol_names = NULL;
+      sd->symbol_names_size = 0;
+      return;
     }
 
-  // Read the symbol table section header.
-  typename This::Shdr symtabshdr(this->section_header(this->symtab_shnum_));
+  // Get the symbol table section header.
+  typename This::Shdr symtabshdr(pshdrs
+                                + this->symtab_shnum_ * This::shdr_size);
   assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
 
   // We only need the external symbols.
@@ -191,49 +211,10 @@ Sized_object<size, big_endian>::do_read_symbols()
   File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
                                               strtabshdr.get_sh_size());
 
-  Read_symbols_data ret;
-  ret.symbols = fvsymtab;
-  ret.symbols_size = extsize;
-  ret.symbol_names = fvstrtab;
-  ret.symbol_names_size = strtabshdr.get_sh_size();
-
-  return ret;
-}
-
-// Add the symbols to the symbol table.
-
-template<int size, bool big_endian>
-void
-Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
-                                              Read_symbols_data sd)
-{
-  if (sd.symbols == NULL)
-    {
-      assert(sd.symbol_names == NULL);
-      return;
-    }
-
-  const int sym_size = This::sym_size;
-  size_t symcount = sd.symbols_size / sym_size;
-  if (symcount * sym_size != sd.symbols_size)
-    {
-      fprintf(stderr,
-             _("%s: %s: size of symbols is not multiple of symbol size\n"),
-             program_name, this->name().c_str());
-      gold_exit(false);
-    }
-
-  this->symbols_ = new Symbol*[symcount];
-
-  const elfcpp::Sym<size, big_endian>* syms =
-    reinterpret_cast<const elfcpp::Sym<size, big_endian>*>(sd.symbols->data());
-  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_);
-
-  delete sd.symbols;
-  delete sd.symbol_names;
+  sd->symbols = fvsymtab;
+  sd->symbols_size = extsize;
+  sd->symbol_names = fvstrtab;
+  sd->symbol_names_size = strtabshdr.get_sh_size();
 }
 
 // Return whether to include a section group in the link.  LAYOUT is
@@ -377,24 +358,18 @@ 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_object<size, big_endian>::do_layout(Layout* layout,
+                                         Read_symbols_data* sd)
 {
-  // This is always called from the main thread.  Lock the file to
-  // keep the error checks happy.
-  Task_locker_obj<File_read> frl(this->input_file()->file());
+  unsigned int shnum = this->shnum();
+  if (shnum == 0)
+    return;
 
   // Get the section headers.
-  unsigned int shnum = this->shnum();
-  const unsigned char* pshdrs = this->get_view(this->shoff_,
-                                              shnum * This::shdr_size);
+  const unsigned char* pshdrs = sd->section_headers->data();
 
   // Get the section names.
-  const unsigned char* pshdrnames = pshdrs + this->shstrndx_ * This::shdr_size;
-  typename This::Shdr shdrnames(pshdrnames);
-  typename elfcpp::Elf_types<size>::Elf_WXword names_size =
-    shdrnames.get_sh_size();
-  const unsigned char* pnamesu = this->get_view(shdrnames.get_sh_offset(),
-                                               shdrnames.get_sh_size());
+  const unsigned char* pnamesu = sd->section_names->data();
   const char* pnames = reinterpret_cast<const char*>(pnamesu);
 
   std::vector<Map_to_output>& map_sections(this->map_to_output());
@@ -403,11 +378,11 @@ 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)
+  for (unsigned int i = 0; i < shnum; ++i, pshdrs += This::shdr_size)
     {
       typename This::Shdr shdr(pshdrs);
 
-      if (shdr.get_sh_name() >= names_size)
+      if (shdr.get_sh_name() >= sd->section_names_size)
        {
          fprintf(stderr,
                  _("%s: %s: bad section name offset for section %u: %lu\n"),
@@ -445,9 +420,51 @@ Sized_object<size, big_endian>::do_layout(Layout* layout)
 
       map_sections[i].output_section = os;
       map_sections[i].offset = offset;
+    }
+
+  delete sd->section_headers;
+  sd->section_headers = NULL;
+  delete sd->section_names;
+  sd->section_names = NULL;
+}
+
+// Add the symbols to the symbol table.
 
-      pshdrs += This::shdr_size;
+template<int size, bool big_endian>
+void
+Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
+                                              Read_symbols_data* sd)
+{
+  if (sd->symbols == NULL)
+    {
+      assert(sd->symbol_names == NULL);
+      return;
     }
+
+  const int sym_size = This::sym_size;
+  size_t symcount = sd->symbols_size / sym_size;
+  if (symcount * sym_size != sd->symbols_size)
+    {
+      fprintf(stderr,
+             _("%s: %s: size of symbols is not multiple of symbol size\n"),
+             program_name, this->name().c_str());
+      gold_exit(false);
+    }
+
+  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_);
+
+  delete sd->symbols;
+  sd->symbols = NULL;
+  delete sd->symbol_names;
+  sd->symbol_names = NULL;
 }
 
 // Finalize the local symbols.  Here we record the file offset at
index cea0f06..dfcb944 100644 (file)
@@ -23,6 +23,12 @@ class Output_file;
 
 struct Read_symbols_data
 {
+  // Section headers.
+  File_view* section_headers;
+  // Section names.
+  File_view* section_names;
+  // Size of section name data in bytes.
+  off_t section_names_size;
   // Symbol data.
   File_view* symbols;
   // Size of symbol data in bytes.
@@ -93,20 +99,20 @@ class Object
   sized_target(ACCEPT_SIZE_ENDIAN_ONLY);
 
   // Read the symbol and relocation information.
-  Read_symbols_data
-  read_symbols()
-  { return this->do_read_symbols(); }
+  void
+  read_symbols(Read_symbols_data* sd)
+  { return this->do_read_symbols(sd); }
 
   // Add symbol information to the global symbol table.
   void
-  add_symbols(Symbol_table* symtab, Read_symbols_data rd)
-  { this->do_add_symbols(symtab, rd); }
+  add_symbols(Symbol_table* symtab, Read_symbols_data* sd)
+  { this->do_add_symbols(symtab, sd); }
 
   // 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)
-  { this->do_layout(lay); }
+  layout(Layout* lay, Read_symbols_data* sd)
+  { this->do_layout(lay, sd); }
 
   // Initial local symbol processing: set the offset where local
   // symbol information will be stored; add local symbol names to
@@ -144,17 +150,17 @@ class Object
 
  protected:
   // Read the symbols--implemented by child class.
-  virtual Read_symbols_data
-  do_read_symbols() = 0;
+  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;
+  do_add_symbols(Symbol_table*, Read_symbols_data*) = 0;
 
   // Lay out sections--implemented by child class.
   virtual void
-  do_layout(Layout*) = 0;
+  do_layout(Layout*, Read_symbols_data*) = 0;
 
   // Finalize local symbols--implemented by child class.
   virtual off_t
@@ -258,16 +264,16 @@ class Sized_object : public Object
   setup(const typename elfcpp::Ehdr<size, big_endian>&);
 
   // Read the symbols.
-  Read_symbols_data
-  do_read_symbols();
-
-  // Add the symbols to the symbol table.
   void
-  do_add_symbols(Symbol_table*, Read_symbols_data);
+  do_read_symbols(Read_symbols_data*);
 
   // Lay out the input sections.
   void
-  do_layout(Layout*);
+  do_layout(Layout*, Read_symbols_data*);
+
+  // Add the symbols to the symbol table.
+  void
+  do_add_symbols(Symbol_table*, Read_symbols_data*);
 
   // Finalize the local symbols.
   off_t
@@ -337,6 +343,8 @@ class Sized_object : public Object
   void
   write_local_symbols(Output_file*, const Stringpool*);
 
+  // If non-NULL, a view of the section header data.
+  File_view* section_headers_;
   // ELF file header e_flags field.
   unsigned int flags_;
   // File offset of section header table.
index 83ad026..48bc987 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-09-29 12:54-0700\n"
+"POT-Creation-Date: 2006-10-04 08:37-0700\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:283 archive.cc:296
+#: archive.cc:284 archive.cc:297
 #, c-format
 msgid "%s: %s: member at %ld is not an ELF object"
 msgstr ""
@@ -149,113 +149,113 @@ msgstr ""
 msgid "%s: %s: unsupported RELA reloc section\n"
 msgstr ""
 
-#: object.cc:59
+#: object.cc:60
 #, c-format
 msgid "%s: %s: bad e_ehsize field (%d != %d)\n"
 msgstr ""
 
-#: object.cc:66
+#: object.cc:67
 #, c-format
 msgid "%s: %s: bad e_shentsize field (%d != %d)\n"
 msgstr ""
 
-#: object.cc:103
+#: object.cc:104
 #, c-format
 msgid "%s: %s: unsupported ELF machine number %d\n"
 msgstr ""
 
-#: object.cc:176
+#: object.cc:196
 #, c-format
 msgid "%s: %s: invalid symbol table name index: %u\n"
 msgstr ""
 
-#: object.cc:184
+#: object.cc:204
 #, c-format
 msgid "%s: %s: symbol table name section has wrong type: %u\n"
 msgstr ""
 
-#: object.cc:221
-#, c-format
-msgid "%s: %s: size of symbols is not multiple of symbol size\n"
-msgstr ""
-
-#: object.cc:275
+#: object.cc:256
 #, c-format
 msgid "%s: %s: section group %u link %u out of range\n"
 msgstr ""
 
-#: object.cc:285
+#: object.cc:266
 #, c-format
 msgid "%s: %s: section group %u info %u out of range\n"
 msgstr ""
 
-#: object.cc:296
+#: object.cc:277
 #, c-format
 msgid "%s; %s: symtab section %u link %u out of range\n"
 msgstr ""
 
-#: object.cc:312
+#: object.cc:293
 #, c-format
 msgid "%s: %s: symbol %u name offset %u out of range\n"
 msgstr ""
 
-#: object.cc:334
+#: object.cc:315
 #, c-format
 msgid "%s: %s: section %u in section group %u out of range"
 msgstr ""
 
-#: object.cc:413
+#: object.cc:388
 #, c-format
 msgid "%s: %s: bad section name offset for section %u: %lu\n"
 msgstr ""
 
-#: object.cc:520
+#: object.cc:449
+#, c-format
+msgid "%s: %s: size of symbols is not multiple of symbol size\n"
+msgstr ""
+
+#: object.cc:537
 #, c-format
 msgid "%s: %s: unknown section index %u for local symbol %u\n"
 msgstr ""
 
-#: object.cc:531
+#: object.cc:548
 #, c-format
 msgid "%s: %s: local symbol %u section index %u out of range\n"
 msgstr ""
 
 #. elfcpp::ET_DYN
-#: object.cc:684
+#: object.cc:701
 #, c-format
 msgid "%s: %s: dynamic objects are not yet supported\n"
 msgstr ""
 
-#: object.cc:708 object.cc:761 object.cc:782
+#: object.cc:725 object.cc:778 object.cc:799
 #, c-format
 msgid "%s: %s: ELF file too short\n"
 msgstr ""
 
-#: object.cc:717
+#: object.cc:734
 #, c-format
 msgid "%s: %s: invalid ELF version 0\n"
 msgstr ""
 
-#: object.cc:720
+#: object.cc:737
 #, c-format
 msgid "%s: %s: unsupported ELF version %d\n"
 msgstr ""
 
-#: object.cc:728
+#: object.cc:745
 #, c-format
 msgid "%s: %s: invalid ELF class 0\n"
 msgstr ""
 
-#: object.cc:735
+#: object.cc:752
 #, c-format
 msgid "%s: %s: unsupported ELF class %d\n"
 msgstr ""
 
-#: object.cc:743
+#: object.cc:760
 #, c-format
 msgid "%s: %s: invalid ELF data encoding\n"
 msgstr ""
 
-#: object.cc:750
+#: object.cc:767
 #, c-format
 msgid "%s: %s: unsupported ELF data encoding %d\n"
 msgstr ""
@@ -326,44 +326,44 @@ msgstr ""
 msgid "%s: -%c: %s\n"
 msgstr ""
 
-#: output.cc:383
+#: output.cc:385
 #, c-format
 msgid "%s: %s: invalid alignment %lu for section \"%s\"\n"
 msgstr ""
 
-#: output.cc:773
+#: output.cc:775
 #, c-format
 msgid "%s: %s: open: %s\n"
 msgstr ""
 
-#: output.cc:782
+#: output.cc:784
 #, c-format
 msgid "%s: %s: lseek: %s\n"
 msgstr ""
 
-#: output.cc:789
+#: output.cc:791
 #, c-format
 msgid "%s: %s: write: %s\n"
 msgstr ""
 
-#: output.cc:799
+#: output.cc:801
 #, c-format
 msgid "%s: %s: mmap: %s\n"
 msgstr ""
 
-#: output.cc:813
+#: output.cc:815
 #, c-format
 msgid "%s: %s: munmap: %s\n"
 msgstr ""
 
-#: output.cc:821
+#: output.cc:823
 #, c-format
 msgid "%s: %s: close: %s\n"
 msgstr ""
 
 #. Here we have to handle archives and any other input file
 #. types we need.
-#: readsyms.cc:107
+#: readsyms.cc:110
 #, c-format
 msgid "%s: %s: not an object or archive\n"
 msgstr ""
@@ -388,22 +388,22 @@ msgstr ""
 msgid "%s: %s: reloc section %u size %lu uneven"
 msgstr ""
 
-#: resolve.cc:144
+#: resolve.cc:138
 #, c-format
 msgid "%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"
 msgstr ""
 
-#: resolve.cc:150
+#: resolve.cc:144
 #, c-format
 msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
 msgstr ""
 
-#: symtab.cc:347
+#: symtab.cc:303
 #, c-format
 msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
 msgstr ""
 
-#: symtab.cc:361
+#: symtab.cc:317
 #, c-format
 msgid "%s: %s: bad global symbol name offset %u at %lu\n"
 msgstr ""
index ee0e063..adc8fac 100644 (file)
@@ -74,8 +74,10 @@ Read_symbols::run(Workqueue* workqueue)
 
          this->input_objects_->add_object(obj);
 
-         Read_symbols_data sd = obj->read_symbols();
-         workqueue->queue(new Add_symbols(this->symtab_, obj, sd,
+         Read_symbols_data* sd = new Read_symbols_data;
+         obj->read_symbols(sd);
+         workqueue->queue(new Add_symbols(this->symtab_, this->layout_,
+                                          obj, sd,
                                           this->this_blocker_,
                                           this->next_blocker_));
 
@@ -94,6 +96,7 @@ Read_symbols::run(Workqueue* workqueue)
          Archive* arch = new Archive(this->input_.name(), input_file);
          arch->setup();
          workqueue->queue(new Add_archive_symbols(this->symtab_,
+                                                  this->layout_,
                                                   this->input_objects_,
                                                   arch,
                                                   this->this_blocker_,
@@ -155,7 +158,10 @@ Add_symbols::locks(Workqueue* workqueue)
 void
 Add_symbols::run(Workqueue*)
 {
+  this->object_->layout(this->layout_, this->sd_);
   this->object_->add_symbols(this->symtab_, this->sd_);
+  delete this->sd_;
+  this->sd_ = NULL;
 }
 
 } // End namespace gold.
index 46d73c8..2077d47 100644 (file)
@@ -29,12 +29,12 @@ class Read_symbols : public Task
   // has completed; it will be NULL for the first task.  NEXT_BLOCKER
   // is used to block the next input file from adding symbols.
   Read_symbols(const General_options& options, Input_objects* input_objects,
-              Symbol_table* symtab, const Dirsearch& dirpath,
+              Symbol_table* symtab, Layout* layout, const Dirsearch& dirpath,
               const Input_argument& input,
               Task_token* this_blocker, Task_token* next_blocker)
     : options_(options), input_objects_(input_objects), symtab_(symtab),
-      dirpath_(dirpath), input_(input), this_blocker_(this_blocker),
-      next_blocker_(next_blocker)
+      layout_(layout), dirpath_(dirpath), input_(input),
+      this_blocker_(this_blocker), next_blocker_(next_blocker)
   { }
 
   ~Read_symbols();
@@ -54,6 +54,7 @@ class Read_symbols : public Task
   const General_options& options_;
   Input_objects* input_objects_;
   Symbol_table* symtab_;
+  Layout* layout_;
   const Dirsearch& dirpath_;
   const Input_argument& input_;
   Task_token* this_blocker_;
@@ -70,10 +71,11 @@ 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(Symbol_table* symtab, Object* object, Read_symbols_data sd,
-             Task_token* this_blocker, Task_token* next_blocker)
-    : symtab_(symtab), object_(object), sd_(sd), this_blocker_(this_blocker),
-      next_blocker_(next_blocker)
+  Add_symbols(Symbol_table* symtab, Layout* layout, Object* object,
+             Read_symbols_data* sd, Task_token* this_blocker,
+             Task_token* next_blocker)
+    : symtab_(symtab), layout_(layout), object_(object), sd_(sd),
+      this_blocker_(this_blocker), next_blocker_(next_blocker)
   { }
 
   ~Add_symbols();
@@ -93,8 +95,9 @@ private:
   class Add_symbols_locker;
 
   Symbol_table* symtab_;
+  Layout* layout_;
   Object* object_;
-  Read_symbols_data sd_;
+  Read_symbols_data* sd_;
   Task_token* this_blocker_;
   Task_token* next_blocker_;
 };
index 98e93f0..6b8199c 100644 (file)
@@ -184,9 +184,10 @@ Symbol_table::resolve(Sized_symbol<size>* to,
   switch (tobits * 16 + frombits)
     {
     case DEF * 16 + DEF:
-      // Two definitions of the same symbol.  We can't give an error
-      // here, because we have not yet discarded linkonce and comdat
-      // sections.  FIXME.
+      // Two definitions of the same symbol.
+      fprintf(stderr, "%s: %s: multiple definition of %s\n",
+             program_name, object->name().c_str(), to->name());
+      // FIXME: Report locations.  Record that we have seen an error.
       return;
 
     case WEAK_DEF * 16 + DEF: