* archive.cc (Archive::get_elf_object_for_member): Remove call
authorCary Coutant <ccoutant@google.com>
Thu, 15 Jan 2009 01:29:25 +0000 (01:29 +0000)
committerCary Coutant <ccoutant@google.com>
Thu, 15 Jan 2009 01:29:25 +0000 (01:29 +0000)
to File_read::claim_for_plugin.
* descriptors.cc (Descriptors::open): Remove reference to
is_claimed.
(Descriptors::claim_for_plugin): Remove.
* descriptors.h (Descriptors::claim_for_plugin): Remove.
(Descriptors::is_claimed): Remove.
(claim_descriptor_for_plugin): Remove.
* fileread.cc (File_read::claim_for_plugin): Remove.
* fileread.h (File_read::claim_for_plugin): Remove.
(File_read::descriptor): Reopen descriptor if necessary.
* plugin.cc  (Plugin::load): Add two new APIs to transfer vector.
(Plugin_manager::all_symbols_read): Add task parameter. Change
all callers.
(Plugin_manager::get_input_file): New function.
(Plugin_manager::release_input_file): New function.
(Pluginobj::Pluginobj): Add filesize parameter and initialize
corresponding data member.
(Sized_pluginobj::Sized_pluginobj): Add filesize parameter
and pass to base constructor. Change all callers.
(get_input_file, release_input_file): New functions.
(make_sized_plugin_object): Add filesize parameter. Change all callers.
* plugin.h (Plugin_manager::Plugin_manager): Initialize task_ member.
(Plugin_manager::all_symbols_read): Add task parameter.
(Plugin_manager::get_input_file): New function.
(Plugin_manager::release_input_file): New function.
(Plugin_manager::task_): New data member.
(Pluginobj::Pluginobj): Add filesize parameter.
(Pluginobj::filename): New function.
(Pluginobj::descriptor): New function.
(Pluginobj::filesize): New function.
(Pluginobj::filesize_): New data member.
(Sized_pluginobj::Sized_pluginobj): Add filesize parameter.
* readsyms.cc (Read_symbols::do_read_symbols): Remove call to
File_read::claim_for_plugin; use Object::unlock to unlock the file.

* testsuite/Makefile.am (plugin_test_4): New test case for plugins
with archive libraries.
* testsuite/Makefile.in: Regenerate.
* testsuite/plugin_test.c (struct sym_info): New type.
(get_input_file, release_input_file): New static variables.
(onload): Capture new transfer vector entries.
(claim_file_hook): Stop reading at end of file according to filesize.
Factor out parsing of readelf output into separate function.
(all_symbols_read_hook): Exercise get_input_file and release_input_file
APIs and get the source file name from the symbol table.  Convert
source file name to corresponding object file name.  Print info
message when adding new input files.
(parse_readelf_line): New function.
* testsuite/plugin_test_1.sh: Add checks for new info messages.
* testsuite/plugin_test_2.sh: Likewise.
* testsuite/plugin_test_3.sh: Likewise.
* testsuite/plugin_test_4.sh: New test case.

16 files changed:
gold/ChangeLog
gold/archive.cc
gold/descriptors.cc
gold/descriptors.h
gold/fileread.cc
gold/fileread.h
gold/plugin.cc
gold/plugin.h
gold/readsyms.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/plugin_test.c
gold/testsuite/plugin_test_1.sh
gold/testsuite/plugin_test_2.sh
gold/testsuite/plugin_test_3.sh
gold/testsuite/plugin_test_4.sh [new file with mode: 0755]

index 9e2d1e0eb827acc29c44f728d9a151804e4b0b88..cf06e1f1b7a67ad6c0d7181086c06e69e4fdbe33 100644 (file)
@@ -1,3 +1,59 @@
+2009-01-14  Cary Coutant  <ccoutant@google.com>
+
+       * archive.cc (Archive::get_elf_object_for_member): Remove call
+       to File_read::claim_for_plugin.
+       * descriptors.cc (Descriptors::open): Remove reference to
+       is_claimed.
+       (Descriptors::claim_for_plugin): Remove.
+       * descriptors.h (Descriptors::claim_for_plugin): Remove.
+       (Descriptors::is_claimed): Remove.
+       (claim_descriptor_for_plugin): Remove.
+       * fileread.cc (File_read::claim_for_plugin): Remove.
+       * fileread.h (File_read::claim_for_plugin): Remove.
+       (File_read::descriptor): Reopen descriptor if necessary.
+       * plugin.cc  (Plugin::load): Add two new APIs to transfer vector.
+       (Plugin_manager::all_symbols_read): Add task parameter. Change
+       all callers.
+       (Plugin_manager::get_input_file): New function.
+       (Plugin_manager::release_input_file): New function.
+       (Pluginobj::Pluginobj): Add filesize parameter and initialize
+       corresponding data member.
+       (Sized_pluginobj::Sized_pluginobj): Add filesize parameter
+       and pass to base constructor. Change all callers.
+       (get_input_file, release_input_file): New functions.
+       (make_sized_plugin_object): Add filesize parameter. Change all callers.
+       * plugin.h (Plugin_manager::Plugin_manager): Initialize task_ member.
+       (Plugin_manager::all_symbols_read): Add task parameter.
+       (Plugin_manager::get_input_file): New function.
+       (Plugin_manager::release_input_file): New function.
+       (Plugin_manager::task_): New data member.
+       (Pluginobj::Pluginobj): Add filesize parameter.
+       (Pluginobj::filename): New function.
+       (Pluginobj::descriptor): New function.
+       (Pluginobj::filesize): New function.
+       (Pluginobj::filesize_): New data member.
+       (Sized_pluginobj::Sized_pluginobj): Add filesize parameter.
+       * readsyms.cc (Read_symbols::do_read_symbols): Remove call to
+       File_read::claim_for_plugin; use Object::unlock to unlock the file.
+
+       * testsuite/Makefile.am (plugin_test_4): New test case for plugins
+       with archive libraries.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/plugin_test.c (struct sym_info): New type.
+       (get_input_file, release_input_file): New static variables.
+       (onload): Capture new transfer vector entries.
+       (claim_file_hook): Stop reading at end of file according to filesize.
+       Factor out parsing of readelf output into separate function.
+       (all_symbols_read_hook): Exercise get_input_file and release_input_file
+       APIs and get the source file name from the symbol table.  Convert
+       source file name to corresponding object file name.  Print info
+       message when adding new input files.
+       (parse_readelf_line): New function.
+       * testsuite/plugin_test_1.sh: Add checks for new info messages.
+       * testsuite/plugin_test_2.sh: Likewise.
+       * testsuite/plugin_test_3.sh: Likewise.
+       * testsuite/plugin_test_4.sh: New test case.
+
 2009-01-07  Ian Lance Taylor  <iant@google.com>
 
        * version.cc (version_string): Bump to 1.8.
index 7e2d143de992473f16a1beadeb6d63ffbb78f5c5..b1ba6d91ad1bf0fd30d6be255a16a1ece1a48d5f 100644 (file)
@@ -1,6 +1,6 @@
 // archive.cc -- archive support for gold
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -535,7 +535,6 @@ Archive::get_elf_object_for_member(off_t off, Input_objects* input_objects)
         {
           // The input file was claimed by a plugin, and its symbols
           // have been provided by the plugin.
-         input_file->file().claim_for_plugin();
           return obj;
         }
     }
index 73c03bf4a457552baafd7e13ba6e9a3b3c3e458c..18498efd7c7ef9ca32bb49546c26f7ae1181147e 100644 (file)
@@ -1,6 +1,6 @@
 // descriptors.cc -- manage file descriptors for gold
 
-// Copyright 2008 Free Software Foundation, Inc.
+// Copyright 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -115,9 +115,7 @@ Descriptors::open(int descriptor, const char* name, int flags, int mode)
          pod->inuse = true;
          pod->is_write = (flags & O_ACCMODE) != O_RDONLY;
 
-          if (!pod->is_claimed)
-           ++this->current_;
-          pod->is_claimed = false;
+         ++this->current_;
          if (this->current_ >= this->limit_)
            this->close_some_descriptor();
 
@@ -168,24 +166,6 @@ Descriptors::release(int descriptor, bool permanent)
     }
 }
 
-// Claim the file descriptor DESCRIPTOR for a plugin.  This effectively
-// removes the descriptor from the pool of linker-managed descriptors,
-// as the plugin will assume responsibility for closing it.
-// The IS_CLAIMED flag allows us to recognize when a file descriptor
-// has been reused after being closed by the plugin.
-
-void
-Descriptors::claim_for_plugin(int descriptor)
-{
-  Hold_lock hl(*this->lock_);
-
-  gold_assert(descriptor >= 0
-             && (static_cast<size_t>(descriptor)
-                 < this->open_descriptors_.size()));
-  Open_descriptor* pod = &this->open_descriptors_[descriptor];
-  pod->is_claimed = true;
-}
-
 // Close some descriptor.  The lock is held when this is called.  We
 // close the descriptor on the top of the free stack.  Note that this
 // is the opposite of an LRU algorithm--we close the most recently
index 359008c1f077e8b77a3291ca88c412cdfd6ca1c1..19333149287637dd9b22748ce9e324e03a00da45 100644 (file)
@@ -1,6 +1,6 @@
 // descriptors.h -- manage file descriptors for gold   -*- C++ -*-
 
-// Copyright 2008 Free Software Foundation, Inc.
+// Copyright 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -56,12 +56,6 @@ class Descriptors
   void
   release(int descriptor, bool permanent);
 
-  // Claim the file descriptor DESCRIPTOR for a plugin.  This effectively
-  // removes the descriptor from the pool of linker-managed descriptors,
-  // as the plugin will assume responsibility for closing it.
-  void
-  claim_for_plugin(int descriptor);
-
  private:
   // Information kept for a descriptor.
   struct Open_descriptor
@@ -75,8 +69,6 @@ class Descriptors
     bool inuse;
     // Whether this is a write descriptor.
     bool is_write;
-    // Whether the descriptor has been claimed for a plugin.
-    bool is_claimed;
   };
 
   bool
@@ -108,10 +100,6 @@ inline void
 release_descriptor(int descriptor, bool permanent)
 { descriptors.release(descriptor, permanent); }
 
-inline void
-claim_descriptor_for_plugin(int descriptor)
-{ descriptors.claim_for_plugin(descriptor); }
-
 } // End namespace gold.
 
 #endif // !defined(GOLD_DESCRIPTORS_H)
index 72abd6bc2edbdec3a024e5d3e8f07a0fdb5f5c4d..36eee6c0ab638fdfd212d29ac879b9044628c0ec 100644 (file)
@@ -1,6 +1,6 @@
 // fileread.cc -- read files for gold
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -191,19 +191,6 @@ File_read::release()
   this->released_ = true;
 }
 
-// Claim the file for a plugin.  This effectively releases the file without
-// closing it; the plugin will assume responsibility for closing it.
-
-void
-File_read::claim_for_plugin()
-{
-  gold_assert(this->is_locked());
-  claim_descriptor_for_plugin(this->descriptor_);
-  this->descriptor_ = -1;
-  this->is_descriptor_opened_ = false;
-  this->released_ = true;
-}
-
 // Lock the file.
 
 void
index 1b776f1c16744fdf8e1dc8430a13349d1b18fb89..3afba862676c9594ed6ef70fdf9ab41921fa812e 100644 (file)
@@ -1,6 +1,6 @@
 // fileread.h -- read files for gold   -*- C++ -*-
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -109,11 +109,6 @@ class File_read
   void
   release();
 
-  // Claim the file for a plugin.  This effectively releases the file without
-  // closing it; the plugin will assume responsibility for closing it.
-  void
-  claim_for_plugin();
-
   // Return the size of the file.
   off_t
   filesize() const
@@ -190,9 +185,9 @@ class File_read
 
   // Return the open file descriptor (for plugins).
   int
-  descriptor() const
+  descriptor()
   {
-    gold_assert(this->descriptor_ >= 0);
+    this->reopen_descriptor();
     return this->descriptor_;
   }
 
index e2a9e60010caf6f9226916cfbba3f68344e359e6..7d5b1b7f46356794cb9db0e752bdbbb1974817a9 100644 (file)
@@ -1,6 +1,6 @@
 // plugin.c -- plugin manager for gold      -*- C++ -*-
 
-// Copyright 2008 Free Software Foundation, Inc.
+// Copyright 2008, 2009 Free Software Foundation, Inc.
 // Written by Cary Coutant <ccoutant@google.com>.
 
 // This file is part of gold.
@@ -61,6 +61,12 @@ register_cleanup(ld_plugin_cleanup_handler handler);
 static enum ld_plugin_status
 add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);
 
+static enum ld_plugin_status
+get_input_file(const void *handle, struct ld_plugin_input_file *file);
+
+static enum ld_plugin_status
+release_input_file(const void *handle);
+
 static enum ld_plugin_status
 get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
 
@@ -75,7 +81,7 @@ message(int level, const char *format, ...);
 #endif // ENABLE_PLUGINS
 
 static Pluginobj* make_sized_plugin_object(Input_file* input_file,
-                                           off_t offset);
+                                           off_t offset, off_t filesize);
 
 // Plugin methods.
 
@@ -112,7 +118,7 @@ Plugin::load()
   sscanf(ver, "%d.%d", &major, &minor);
 
   // Allocate and populate a transfer vector.
-  const int tv_fixed_size = 11;
+  const int tv_fixed_size = 13;
   int tv_size = this->args_.size() + tv_fixed_size;
   ld_plugin_tv *tv = new ld_plugin_tv[tv_size];
 
@@ -162,6 +168,14 @@ Plugin::load()
   tv[i].tv_tag = LDPT_ADD_SYMBOLS;
   tv[i].tv_u.tv_add_symbols = add_symbols;
 
+  ++i;
+  tv[i].tv_tag = LDPT_GET_INPUT_FILE;
+  tv[i].tv_u.tv_get_input_file = get_input_file;
+
+  ++i;
+  tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
+  tv[i].tv_u.tv_release_input_file = release_input_file;
+
   ++i;
   tv[i].tv_tag = LDPT_GET_SYMBOLS;
   tv[i].tv_u.tv_get_symbols = get_symbols;
@@ -283,7 +297,7 @@ Plugin_manager::claim_file(Input_file* input_file, off_t offset,
 // Call the all-symbols-read handlers.
 
 void
-Plugin_manager::all_symbols_read(Workqueue* workqueue,
+Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
                                  Input_objects* input_objects,
                                 Symbol_table* symtab, Layout* layout,
                                 Dirsearch* dirpath, Mapfile* mapfile,
@@ -291,6 +305,7 @@ Plugin_manager::all_symbols_read(Workqueue* workqueue,
 {
   this->in_replacement_phase_ = true;
   this->workqueue_ = workqueue;
+  this->task_ = task;
   this->input_objects_ = input_objects;
   this->symtab_ = symtab;
   this->layout_ = layout;
@@ -344,11 +359,45 @@ Plugin_manager::make_plugin_object(unsigned int handle)
     return NULL;
 
   Pluginobj* obj = make_sized_plugin_object(this->input_file_,
-                                            this->plugin_input_file_.offset);
+                                            this->plugin_input_file_.offset,
+                                            this->plugin_input_file_.filesize);
   this->objects_.push_back(obj);
   return obj;
 }
 
+// Get the input file information with an open (possibly re-opened)
+// file descriptor.
+
+ld_plugin_status
+Plugin_manager::get_input_file(unsigned int handle,
+                               struct ld_plugin_input_file *file)
+{
+  Pluginobj* obj = this->object(handle);
+  if (obj == NULL)
+    return LDPS_BAD_HANDLE;
+
+  obj->lock(this->task_);
+  file->name = obj->filename().c_str();
+  file->fd = obj->descriptor();
+  file->offset = obj->offset();
+  file->filesize = obj->filesize();
+  file->handle = reinterpret_cast<void*>(handle);
+  return LDPS_OK;
+}
+
+// Release the input file.
+
+ld_plugin_status
+Plugin_manager::release_input_file(unsigned int handle)
+{
+  Pluginobj* obj = this->object(handle);
+  if (obj == NULL)
+    return LDPS_BAD_HANDLE;
+
+  obj->unlock(this->task_);
+  return LDPS_OK;
+}
+
 // Add a new input file.
 
 ld_plugin_status
@@ -375,9 +424,9 @@ Plugin_manager::add_input_file(char *pathname)
 // Class Pluginobj.
 
 Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
-                     off_t offset)
+                     off_t offset, off_t filesize)
   : Object(name, input_file, false, offset),
-    nsyms_(0), syms_(NULL), symbols_(), comdat_map_()
+    nsyms_(0), syms_(NULL), symbols_(), filesize_(filesize), comdat_map_()
 {
 }
 
@@ -468,8 +517,9 @@ template<int size, bool big_endian>
 Sized_pluginobj<size, big_endian>::Sized_pluginobj(
     const std::string& name,
     Input_file* input_file,
-    off_t offset)
-  : Pluginobj(name, input_file, offset)
+    off_t offset,
+    off_t filesize)
+  : Pluginobj(name, input_file, offset, filesize)
 {
 }
 
@@ -822,6 +872,7 @@ Plugin_hook::run(Workqueue* workqueue)
 {
   gold_assert(this->options_.has_plugins());
   this->options_.plugins()->all_symbols_read(workqueue,
+                                             this,
                                              this->input_objects_,
                                              this->symtab_,
                                              this->layout_,
@@ -880,6 +931,29 @@ add_symbols(void* handle, int nsyms, const ld_plugin_symbol *syms)
   return LDPS_OK;
 }
 
+// Get the input file information with an open (possibly re-opened)
+// file descriptor.
+
+static enum ld_plugin_status
+get_input_file(const void *handle, struct ld_plugin_input_file *file)
+{
+  gold_assert(parameters->options().has_plugins());
+  unsigned int obj_index =
+      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
+  return parameters->options().plugins()->get_input_file(obj_index, file);
+}
+
+// Release the input file.
+
+static enum ld_plugin_status
+release_input_file(const void *handle)
+{
+  gold_assert(parameters->options().has_plugins());
+  unsigned int obj_index =
+      static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle));
+  return parameters->options().plugins()->release_input_file(obj_index);
+}
+
 // Get the symbol resolution info for a plugin-claimed input file.
 
 static enum ld_plugin_status
@@ -936,7 +1010,7 @@ message(int level, const char * format, ...)
 // Allocate a Pluginobj object of the appropriate size and endianness.
 
 static Pluginobj*
-make_sized_plugin_object(Input_file* input_file, off_t offset)
+make_sized_plugin_object(Input_file* input_file, off_t offset, off_t filesize)
 {
   Target* target;
   Pluginobj* obj = NULL;
@@ -951,7 +1025,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
       if (target->is_big_endian())
 #ifdef HAVE_TARGET_32_BIG
         obj = new Sized_pluginobj<32, true>(input_file->filename(),
-                                            input_file, offset);
+                                            input_file, offset, filesize);
 #else
         gold_error(_("%s: not configured to support "
                     "32-bit big-endian object"),
@@ -960,7 +1034,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
       else
 #ifdef HAVE_TARGET_32_LITTLE
         obj = new Sized_pluginobj<32, false>(input_file->filename(),
-                                             input_file, offset);
+                                             input_file, offset, filesize);
 #else
         gold_error(_("%s: not configured to support "
                     "32-bit little-endian object"),
@@ -972,7 +1046,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
       if (target->is_big_endian())
 #ifdef HAVE_TARGET_64_BIG
         obj = new Sized_pluginobj<64, true>(input_file->filename(),
-                                            input_file, offset);
+                                            input_file, offset, filesize);
 #else
         gold_error(_("%s: not configured to support "
                     "64-bit big-endian object"),
@@ -981,7 +1055,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
       else
 #ifdef HAVE_TARGET_64_LITTLE
         obj = new Sized_pluginobj<64, false>(input_file->filename(),
-                                             input_file, offset);
+                                             input_file, offset, filesize);
 #else
         gold_error(_("%s: not configured to support "
                     "64-bit little-endian object"),
index 2ea0370878c3a3797adac6938460e33c00b47e5d..a8d3dc4db15f63e4eda59457a0402b24cccd5ea8 100644 (file)
@@ -1,6 +1,6 @@
 // plugin.h -- plugin manager for gold      -*- C++ -*-
 
-// Copyright 2008 Free Software Foundation, Inc.
+// Copyright 2008, 2009 Free Software Foundation, Inc.
 // Written by Cary Coutant <ccoutant@google.com>.
 
 // This file is part of gold.
@@ -122,8 +122,9 @@ class Plugin_manager
   Plugin_manager(const General_options& options)
     : plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
       plugin_input_file_(), in_replacement_phase_(false), cleanup_done_(false),
-      options_(options), workqueue_(NULL), input_objects_(NULL), symtab_(NULL),
-      layout_(NULL), dirpath_(NULL), mapfile_(NULL), this_blocker_(NULL)
+      options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
+      symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
+      this_blocker_(NULL)
   { this->current_ = plugins_.end(); }
 
   ~Plugin_manager();
@@ -151,9 +152,10 @@ class Plugin_manager
 
   // Call the all-symbols-read handlers.
   void
-  all_symbols_read(Workqueue* workqueue, Input_objects* input_objects,
-                   Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
-                   Mapfile* mapfile, Task_token** last_blocker);
+  all_symbols_read(Workqueue* workqueue, Task* task,
+                   Input_objects* input_objects, Symbol_table* symtab,
+                   Layout* layout, Dirsearch* dirpath, Mapfile* mapfile,
+                   Task_token** last_blocker);
 
   // Run deferred layout.
   void
@@ -214,6 +216,15 @@ class Plugin_manager
   add_deferred_layout_object(Relobj* obj)
   { this->deferred_layout_objects_.push_back(obj); }
 
+  // Get input file information with an open (possibly re-opened)
+  // file descriptor.
+  ld_plugin_status
+  get_input_file(unsigned int handle, struct ld_plugin_input_file *file);
+
+  // Release an input file.
+  ld_plugin_status
+  release_input_file(unsigned int handle);
+
   // Add a new input file.
   ld_plugin_status
   add_input_file(char *pathname);
@@ -257,6 +268,7 @@ class Plugin_manager
 
   const General_options& options_;
   Workqueue* workqueue_;
+  Task* task_;
   Input_objects* input_objects_;
   Symbol_table* symtab_;
   Layout* layout_;
@@ -275,7 +287,8 @@ class Pluginobj : public Object
 
   typedef std::vector<Symbol*> Symbols;
 
-  Pluginobj(const std::string& name, Input_file* input_file, off_t offset);
+  Pluginobj(const std::string& name, Input_file* input_file, off_t offset,
+            off_t filesize);
 
   // Fill in the symbol resolution status for the given plugin symbols.
   ld_plugin_status
@@ -299,6 +312,21 @@ class Pluginobj : public Object
   bool
   include_comdat_group(std::string comdat_key, Layout* layout);
 
+  // Return the filename.
+  const std::string&
+  filename() const
+  { return this->input_file()->filename(); }
+
+  // Return the file descriptor.
+  int
+  descriptor()
+  { return this->input_file()->file().descriptor(); }
+
+  // Return the size of the file or archive member.
+  off_t
+  filesize()
+  { return this->filesize_; }
+
  protected:
   // Return TRUE if this is an object claimed by a plugin.
   virtual Pluginobj*
@@ -320,6 +348,8 @@ class Pluginobj : public Object
   Symbols symbols_;
 
  private:
+  // Size of the file (or archive member).
+  off_t filesize_;
   // Map a comdat key symbol to a boolean indicating whether the comdat
   // group in this object with that key should be kept.
   typedef Unordered_map<std::string, bool> Comdat_map;
@@ -333,7 +363,7 @@ class Sized_pluginobj : public Pluginobj
 {
  public:
   Sized_pluginobj(const std::string& name, Input_file* input_file,
-                  off_t offset);
+                  off_t offset, off_t filesize);
 
   // Read the symbols.
   void
index ac646d95d1ca517326eb2c2a8a5ace89bf06bf41..412ffcd07708f54f74e4072a10e48c4c6ed7d704 100644 (file)
@@ -1,6 +1,6 @@
 // readsyms.cc -- read input file symbols for gold
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -196,8 +196,10 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
         {
           // The input file was claimed by a plugin, and its symbols
           // have been provided by the plugin.
-         input_file->file().claim_for_plugin();
-         input_file->file().unlock(this);
+
+          // We are done with the file at this point, so unlock it.
+          obj->unlock(this);
+
           workqueue->queue_next(new Add_plugin_symbols(this->symtab_,
                                                        this->layout_,
                                                        obj,
index 40daf1a628e83e2db19495a173b588db3c17712f..c318718cd98376c924dd45f59e5c3eeacea9b4d1 100644 (file)
@@ -981,6 +981,18 @@ plugin_test_3: two_file_test_main.o two_file_test_1.syms two_file_test_1b.syms t
 plugin_test_3.err: plugin_test_3
        @touch plugin_test_3.err
 
+check_PROGRAMS += plugin_test_4
+check_SCRIPTS += plugin_test_4.sh
+check_DATA += plugin_test_4.err
+MOSTLYCLEANFILES += plugin_test_4.err
+plugin_test_4: two_file_test_main.o plugin_test_4.a gcctestdir/ld plugin_test.so
+       $(CXXLINK) -Bgcctestdir/ -Wl,--no-demangle,--plugin,"./plugin_test.so",--plugin-opt,"_Z4f13iv" two_file_test_main.o -Wl,--whole-archive,plugin_test_4.a,--no-whole-archive 2>plugin_test_4.err
+plugin_test_4.err: plugin_test_4
+       @touch plugin_test_4.err
+
+plugin_test_4.a: two_file_test_1.syms two_file_test_1b.syms two_file_test_2.syms
+       $(TEST_AR) cr $@ $^
+
 plugin_test.so: plugin_test.o
        $(LINK) -Bgcctestdir/ -shared plugin_test.o
 plugin_test.o: plugin_test.c
index a8644c1415121789c3e7ded94ba8e9eea13e9a61..c1ad9c3ed8ee6fcd0acfe4bbeadeff979c3e549a 100644 (file)
@@ -293,19 +293,23 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_20 =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_1 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_2 \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_4
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_21 =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_1.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_2.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3.sh
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_4.sh
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_22 =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_1.err \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_2.err \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_4.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_23 =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_1.err \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_2.err \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3.err \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_4.err
 subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -407,7 +411,8 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS)
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ thin_archive_test_2$(EXEEXT)
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__EXEEXT_16 = plugin_test_1$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_2$(EXEEXT) \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3$(EXEEXT)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_3$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   plugin_test_4$(EXEEXT)
 basic_pic_test_SOURCES = basic_pic_test.c
 basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT)
 basic_pic_test_LDADD = $(LDADD)
@@ -582,6 +587,12 @@ plugin_test_3_LDADD = $(LDADD)
 plugin_test_3_DEPENDENCIES = libgoldtest.a ../libgold.a \
        ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+plugin_test_4_SOURCES = plugin_test_4.c
+plugin_test_4_OBJECTS = plugin_test_4.$(OBJEXT)
+plugin_test_4_LDADD = $(LDADD)
+plugin_test_4_DEPENDENCIES = libgoldtest.a ../libgold.a \
+       ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
+       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am__protected_1_SOURCES_DIST = protected_main_1.cc protected_main_2.cc \
        protected_main_3.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am_protected_1_OBJECTS =  \
@@ -866,7 +877,7 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \
        $(initpri1_SOURCES) $(justsyms_SOURCES) many_sections_r_test.c \
        $(many_sections_test_SOURCES) $(object_unittest_SOURCES) \
        plugin_test_1.c plugin_test_2.c plugin_test_3.c \
-       $(protected_1_SOURCES) $(protected_2_SOURCES) \
+       plugin_test_4.c $(protected_1_SOURCES) $(protected_2_SOURCES) \
        $(relro_script_test_SOURCES) $(relro_test_SOURCES) \
        $(script_test_1_SOURCES) $(script_test_2_SOURCES) \
        script_test_3.c $(thin_archive_test_1_SOURCES) \
@@ -918,7 +929,8 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \
        $(am__initpri1_SOURCES_DIST) $(am__justsyms_SOURCES_DIST) \
        many_sections_r_test.c $(am__many_sections_test_SOURCES_DIST) \
        $(object_unittest_SOURCES) plugin_test_1.c plugin_test_2.c \
-       plugin_test_3.c $(am__protected_1_SOURCES_DIST) \
+       plugin_test_3.c plugin_test_4.c \
+       $(am__protected_1_SOURCES_DIST) \
        $(am__protected_2_SOURCES_DIST) \
        $(am__relro_script_test_SOURCES_DIST) \
        $(am__relro_test_SOURCES_DIST) \
@@ -1637,6 +1649,15 @@ object_unittest$(EXEEXT): $(object_unittest_OBJECTS) $(object_unittest_DEPENDENC
 @PLUGINS_FALSE@plugin_test_3$(EXEEXT): $(plugin_test_3_OBJECTS) $(plugin_test_3_DEPENDENCIES) 
 @PLUGINS_FALSE@        @rm -f plugin_test_3$(EXEEXT)
 @PLUGINS_FALSE@        $(LINK) $(plugin_test_3_LDFLAGS) $(plugin_test_3_OBJECTS) $(plugin_test_3_LDADD) $(LIBS)
+@GCC_FALSE@plugin_test_4$(EXEEXT): $(plugin_test_4_OBJECTS) $(plugin_test_4_DEPENDENCIES) 
+@GCC_FALSE@    @rm -f plugin_test_4$(EXEEXT)
+@GCC_FALSE@    $(LINK) $(plugin_test_4_LDFLAGS) $(plugin_test_4_OBJECTS) $(plugin_test_4_LDADD) $(LIBS)
+@NATIVE_LINKER_FALSE@plugin_test_4$(EXEEXT): $(plugin_test_4_OBJECTS) $(plugin_test_4_DEPENDENCIES) 
+@NATIVE_LINKER_FALSE@  @rm -f plugin_test_4$(EXEEXT)
+@NATIVE_LINKER_FALSE@  $(LINK) $(plugin_test_4_LDFLAGS) $(plugin_test_4_OBJECTS) $(plugin_test_4_LDADD) $(LIBS)
+@PLUGINS_FALSE@plugin_test_4$(EXEEXT): $(plugin_test_4_OBJECTS) $(plugin_test_4_DEPENDENCIES) 
+@PLUGINS_FALSE@        @rm -f plugin_test_4$(EXEEXT)
+@PLUGINS_FALSE@        $(LINK) $(plugin_test_4_LDFLAGS) $(plugin_test_4_OBJECTS) $(plugin_test_4_LDADD) $(LIBS)
 protected_1$(EXEEXT): $(protected_1_OBJECTS) $(protected_1_DEPENDENCIES) 
        @rm -f protected_1$(EXEEXT)
        $(CXXLINK) $(protected_1_LDFLAGS) $(protected_1_OBJECTS) $(protected_1_LDADD) $(LIBS)
@@ -1823,6 +1844,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_test_4.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protected_3.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protected_main_1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protected_main_2.Po@am__quote@
@@ -2487,6 +2509,13 @@ uninstall-am: uninstall-info-am
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   $(CXXLINK) -Bgcctestdir/ -Wl,--export-dynamic -Wl,--no-demangle,--plugin,"./plugin_test.so",--plugin-opt,"_Z4f13iv" two_file_test_main.o two_file_test_1.syms two_file_test_1b.syms two_file_test_2.syms empty.syms 2>plugin_test_3.err
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_test_3.err: plugin_test_3
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   @touch plugin_test_3.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_test_4: two_file_test_main.o plugin_test_4.a gcctestdir/ld plugin_test.so
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   $(CXXLINK) -Bgcctestdir/ -Wl,--no-demangle,--plugin,"./plugin_test.so",--plugin-opt,"_Z4f13iv" two_file_test_main.o -Wl,--whole-archive,plugin_test_4.a,--no-whole-archive 2>plugin_test_4.err
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_test_4.err: plugin_test_4
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   @touch plugin_test_4.err
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_test_4.a: two_file_test_1.syms two_file_test_1b.syms two_file_test_2.syms
+@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   $(TEST_AR) cr $@ $^
 
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_test.so: plugin_test.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@   $(LINK) -Bgcctestdir/ -shared plugin_test.o
index c36fee4aa63fddd8fdf2c1b1d4b045719a8b068e..2218d0841b1073370c42b77fa565b9db77d1dcbc 100644 (file)
@@ -1,6 +1,6 @@
 /* test_plugin.c -- simple linker plugin test
 
-   Copyright 2008 Free Software Foundation, Inc.
+   Copyright 2008, 2009 Free Software Foundation, Inc.
    Written by Cary Coutant <ccoutant@google.com>.
 
    This file is part of gold.
@@ -34,6 +34,16 @@ struct claimed_file
   struct claimed_file* next;
 };
 
+struct sym_info
+{
+  int size;
+  char* type;
+  char* bind;
+  char* vis;
+  char* sect;
+  char* name;
+};
+
 static struct claimed_file* first_claimed_file = NULL;
 static struct claimed_file* last_claimed_file = NULL;
 
@@ -44,6 +54,8 @@ static ld_plugin_add_symbols add_symbols = NULL;
 static ld_plugin_get_symbols get_symbols = NULL;
 static ld_plugin_add_input_file add_input_file = NULL;
 static ld_plugin_message message = NULL;
+static ld_plugin_get_input_file get_input_file = NULL;
+static ld_plugin_release_input_file release_input_file = NULL;
 
 #define MAXOPTS 10
 
@@ -56,6 +68,8 @@ enum ld_plugin_status claim_file_hook(const struct ld_plugin_input_file *file,
 enum ld_plugin_status all_symbols_read_hook(void);
 enum ld_plugin_status cleanup_hook(void);
 
+static void parse_readelf_line(char*, struct sym_info*);
+
 enum ld_plugin_status
 onload(struct ld_plugin_tv *tv)
 {
@@ -102,6 +116,12 @@ onload(struct ld_plugin_tv *tv)
         case LDPT_MESSAGE:
           message = entry->tv_u.tv_message;
           break;
+        case LDPT_GET_INPUT_FILE:
+          get_input_file = entry->tv_u.tv_get_input_file;
+          break;
+        case LDPT_RELEASE_INPUT_FILE:
+          release_input_file = entry->tv_u.tv_release_input_file;
+          break;
         default:
           break;
         }
@@ -162,21 +182,17 @@ enum ld_plugin_status
 claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
 {
   int len;
+  off_t end_offset;
   char buf[160];
   struct claimed_file* claimed_file;
   struct ld_plugin_symbol* syms;
   int nsyms = 0;
   int maxsyms = 0;
   FILE* irfile;
-  char *p;
-  char *pbind;
-  char *pvis;
-  char *psect;
+  struct sym_info info;
   int weak;
   int def;
   int vis;
-  int size;
-  char* name;
   int is_comdat;
   int i;
 
@@ -187,6 +203,7 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
   /* Look for the beginning of output from readelf -s.  */
   irfile = fdopen(file->fd, "r");
   (void)fseek(irfile, file->offset, SEEK_SET);
+  end_offset = file->offset + file->filesize;
   len = fread(buf, 1, 13, irfile);
   if (len < 13 || strncmp(buf, "\nSymbol table", 13) != 0)
     return LDPS_OK;
@@ -207,68 +224,28 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
   if (syms == NULL)
     return LDPS_ERR;
   maxsyms = 8;
-  while (fgets(buf, sizeof(buf), irfile) != NULL)
+  while (ftell(irfile) < end_offset
+         && fgets(buf, sizeof(buf), irfile) != NULL)
     {
-      p = buf;
-      p += strspn(p, " ");
-
-      /* Index field.  */
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Value field.  */
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Size field.  */
-      size = atoi(p);
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Type field.  */
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Binding field.  */
-      pbind = p;
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Visibility field.  */
-      pvis = p;
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Section field.  */
-      psect = p;
-      p += strcspn(p, " ");
-      p += strspn(p, " ");
-
-      /* Name field.  */
-      /* FIXME:  Look for version.  */
-      len = strlen(p);
-      if (p[len-1] == '\n')
-        p[--len] = '\0';
-      name = malloc(len + 1);
-      strncpy(name, p, len + 1);
+      parse_readelf_line(buf, &info);
 
       /* Ignore local symbols.  */
-      if (strncmp(pbind, "LOCAL", 5) == 0)
+      if (strncmp(info.bind, "LOCAL", 5) == 0)
         continue;
 
-      weak = strncmp(pbind, "WEAK", 4) == 0;
-      if (strncmp(psect, "UND", 3) == 0)
+      weak = strncmp(info.bind, "WEAK", 4) == 0;
+      if (strncmp(info.sect, "UND", 3) == 0)
         def = weak ? LDPK_WEAKUNDEF : LDPK_UNDEF;
-      else if (strncmp(psect, "COM", 3) == 0)
+      else if (strncmp(info.sect, "COM", 3) == 0)
         def = LDPK_COMMON;
       else
         def = weak ? LDPK_WEAKDEF : LDPK_DEF;
 
-      if (strncmp(pvis, "INTERNAL", 8) == 0)
+      if (strncmp(info.vis, "INTERNAL", 8) == 0)
         vis = LDPV_INTERNAL;
-      else if (strncmp(pvis, "HIDDEN", 6) == 0)
+      else if (strncmp(info.vis, "HIDDEN", 6) == 0)
         vis = LDPV_HIDDEN;
-      else if (strncmp(pvis, "PROTECTED", 9) == 0)
+      else if (strncmp(info.vis, "PROTECTED", 9) == 0)
         vis = LDPV_PROTECTED;
       else
         vis = LDPV_DEFAULT;
@@ -278,7 +255,7 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
       is_comdat = 0;
       for (i = 0; i < nopts; ++i)
         {
-          if (name != NULL && strcmp(name, opts[i]) == 0)
+          if (info.name != NULL && strcmp(info.name, opts[i]) == 0)
             {
               is_comdat = 1;
               break;
@@ -294,12 +271,19 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
           maxsyms *= 2;
         }
 
-      syms[nsyms].name = name;
+      if (info.name == NULL)
+        syms[nsyms].name = NULL;
+      else
+        {
+          len = strlen(info.name);
+          syms[nsyms].name = malloc(len + 1);
+          strncpy(syms[nsyms].name, info.name, len + 1);
+        }
       syms[nsyms].version = NULL;
       syms[nsyms].def = def;
       syms[nsyms].visibility = vis;
-      syms[nsyms].size = size;
-      syms[nsyms].comdat_key = is_comdat ? name : NULL;
+      syms[nsyms].size = info.size;
+      syms[nsyms].comdat_key = is_comdat ? syms[nsyms].name : NULL;
       syms[nsyms].resolution = LDPR_UNKNOWN;
       ++nsyms;
     }
@@ -335,8 +319,14 @@ all_symbols_read_hook(void)
   int i;
   const char* res;
   struct claimed_file* claimed_file;
+  struct ld_plugin_input_file file;
+  FILE* irfile;
+  off_t end_offset;
+  struct sym_info info;
+  int len;
   char buf[160];
-  char *p;
+  char* p;
+  const char* filename;
 
   (*message)(LDPL_INFO, "all symbols read hook called");
 
@@ -352,6 +342,7 @@ all_symbols_read_hook(void)
     {
       (*get_symbols)(claimed_file->handle, claimed_file->nsyms,
                      claimed_file->syms);
+
       for (i = 0; i < claimed_file->nsyms; ++i)
         {
           switch (claimed_file->syms[i].resolution)
@@ -397,28 +388,83 @@ all_symbols_read_hook(void)
       fprintf(stderr, "tv_add_input_file interface missing\n");
       return LDPS_ERR;
     }
+  if (get_input_file == NULL)
+    {
+      fprintf(stderr, "tv_get_input_file interface missing\n");
+      return LDPS_ERR;
+    }
+  if (release_input_file == NULL)
+    {
+      fprintf(stderr, "tv_release_input_file interface missing\n");
+      return LDPS_ERR;
+    }
 
   for (claimed_file = first_claimed_file;
        claimed_file != NULL;
        claimed_file = claimed_file->next)
     {
+      (*get_input_file) (claimed_file->handle, &file);
+
+      /* Look for the beginning of output from readelf -s.  */
+      irfile = fdopen(file.fd, "r");
+      (void)fseek(irfile, file.offset, SEEK_SET);
+      end_offset = file.offset + file.filesize;
+      len = fread(buf, 1, 13, irfile);
+      if (len < 13 || strncmp(buf, "\nSymbol table", 13) != 0)
+        {
+          fprintf(stderr, "%s: can't re-read original input file\n",
+                  claimed_file->name);
+          return LDPS_ERR;
+        }
+
+      /* Skip the two header lines.  */
+      (void) fgets(buf, sizeof(buf), irfile);
+      (void) fgets(buf, sizeof(buf), irfile);
+
+      filename = NULL;
+      while (ftell(irfile) < end_offset
+             && fgets(buf, sizeof(buf), irfile) != NULL)
+        {
+          parse_readelf_line(buf, &info);
+
+          /* Look for file name.  */
+          if (strncmp(info.type, "FILE", 4) == 0)
+            {
+              len = strlen(info.name);
+              p = malloc(len + 1);
+              strncpy(p, info.name, len + 1);
+              filename = p;
+              break;
+            }
+        }
+
+      (*release_input_file) (claimed_file->handle);
+
+      if (filename == NULL)
+        filename = claimed_file->name;
+
       if (claimed_file->nsyms == 0)
         continue;
-      if (strlen(claimed_file->name) >= sizeof(buf))
+
+      if (strlen(filename) >= sizeof(buf))
         {
-          (*message)(LDPL_FATAL, "%s: filename too long", claimed_file->name);
+          (*message)(LDPL_FATAL, "%s: filename too long", filename);
           return LDPS_ERR;
         }
-      strcpy(buf, claimed_file->name);
+      strcpy(buf, filename);
       p = strrchr(buf, '.');
-      if (p == NULL || strcmp(p, ".syms") != 0)
+      if (p == NULL
+          || (strcmp(p, ".syms") != 0
+              && strcmp(p, ".c") != 0
+              && strcmp(p, ".cc") != 0))
         {
-          (*message)(LDPL_FATAL, "%s: filename must have '.syms' suffix",
-                     claimed_file->name);
+          (*message)(LDPL_FATAL, "%s: filename has unknown suffix",
+                     filename);
           return LDPS_ERR;
         }
       p[1] = 'o';
       p[2] = '\0';
+      (*message)(LDPL_INFO, "%s: adding new input file", buf);
       (*add_input_file)(buf);
     }
 
@@ -431,3 +477,53 @@ cleanup_hook(void)
   (*message)(LDPL_INFO, "cleanup hook called");
   return LDPS_OK;
 }
+
+static void
+parse_readelf_line(char* p, struct sym_info* info)
+{
+  int len;
+
+  p += strspn(p, " ");
+
+  /* Index field.  */
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Value field.  */
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Size field.  */
+  info->size = atoi(p);
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Type field.  */
+  info->type = p;
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Binding field.  */
+  info->bind = p;
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Visibility field.  */
+  info->vis = p;
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Section field.  */
+  info->sect = p;
+  p += strcspn(p, " ");
+  p += strspn(p, " ");
+
+  /* Name field.  */
+  /* FIXME:  Look for version.  */
+  len = strlen(p);
+  if (len == 0)
+    p = NULL;
+  else if (p[len-1] == '\n')
+    p[--len] = '\0';
+  info->name = p;
+}
index 5e161396ac5f6991706abf484424edbb1231900c..4d3ed417f80db29a512c598c4a9b09275ac85ec7 100755 (executable)
@@ -2,7 +2,7 @@
 
 # plugin_test_1.sh -- a test case for the plugin API.
 
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008, 2009 Free Software Foundation, Inc.
 # Written by Cary Coutant <ccoutant@google.com>.
 
 # This file is part of gold.
@@ -51,6 +51,9 @@ check plugin_test_1.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG"
 check plugin_test_1.err "two_file_test_1.syms: v2: RESOLVED_IR"
 check plugin_test_1.err "two_file_test_1.syms: t17data: RESOLVED_IR"
 check plugin_test_1.err "two_file_test_2.syms: _Z4f13iv: PREEMPTED_IR"
+check plugin_test_1.err "two_file_test_1.o: adding new input file"
+check plugin_test_1.err "two_file_test_1b.o: adding new input file"
+check plugin_test_1.err "two_file_test_2.o: adding new input file"
 check plugin_test_1.err "cleanup hook called"
 
 exit 0
index 41865acff281ec46fe86461fac1a85fd903827e9..a47d22aaa65cb1ca662f3f632d2c4cf5d1ce06ff 100755 (executable)
@@ -2,7 +2,7 @@
 
 # plugin_test_2.sh -- a test case for the plugin API.
 
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008, 2009 Free Software Foundation, Inc.
 # Written by Cary Coutant <ccoutant@google.com>.
 
 # This file is part of gold.
@@ -49,6 +49,8 @@ check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_REG"
 check plugin_test_2.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG"
 check plugin_test_2.err "two_file_test_1.syms: v2: RESOLVED_DYN"
 check plugin_test_2.err "two_file_test_1.syms: t17data: RESOLVED_DYN"
+check plugin_test_2.err "two_file_test_1.o: adding new input file"
+check plugin_test_2.err "two_file_test_1b.o: adding new input file"
 check plugin_test_2.err "cleanup hook called"
 
 exit 0
index 837595fb753cabff2994303e92f7195261209fb4..961df156a26301a0c47bd53d97c33b32b9d080c4 100755 (executable)
@@ -2,7 +2,7 @@
 
 # plugin_test_3.sh -- a test case for the plugin API.
 
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008, 2009 Free Software Foundation, Inc.
 # Written by Cary Coutant <ccoutant@google.com>.
 
 # This file is part of gold.
@@ -51,6 +51,9 @@ check plugin_test_3.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG"
 check plugin_test_3.err "two_file_test_1.syms: v2: RESOLVED_IR"
 check plugin_test_3.err "two_file_test_1.syms: t17data: RESOLVED_IR"
 check plugin_test_3.err "two_file_test_2.syms: _Z4f13iv: PREEMPTED_IR"
+check plugin_test_3.err "two_file_test_1.o: adding new input file"
+check plugin_test_3.err "two_file_test_1b.o: adding new input file"
+check plugin_test_3.err "two_file_test_2.o: adding new input file"
 check plugin_test_3.err "cleanup hook called"
 
 exit 0
diff --git a/gold/testsuite/plugin_test_4.sh b/gold/testsuite/plugin_test_4.sh
new file mode 100755 (executable)
index 0000000..89df46c
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# plugin_test_4.sh -- a test case for the plugin API.
+
+# Copyright 2009 Free Software Foundation, Inc.
+# Written by Cary Coutant <ccoutant@google.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file goes with plugin_test_4.c, a simple plug-in library that
+# exercises the basic interfaces and prints out version numbers and
+# options passed to the plugin.
+
+check()
+{
+    if ! grep -q "$2" "$1"
+    then
+       echo "Did not find expected output in $1:"
+       echo "   $2"
+       echo ""
+       echo "Actual output below:"
+       cat "$1"
+       exit 1
+    fi
+}
+
+check plugin_test_4.err "API version:"
+check plugin_test_4.err "gold version:"
+check plugin_test_4.err "option: _Z4f13iv"
+check plugin_test_4.err "two_file_test_main.o: claim file hook called"
+check plugin_test_4.err "plugin_test_4.a: claim file hook called"
+check plugin_test_4.err "plugin_test_4.a: claiming file"
+check plugin_test_4.err "plugin_test_4.a: _Z4f13iv: PREVAILING_DEF_IRONLY"
+check plugin_test_4.err "plugin_test_4.a: _Z2t2v: PREVAILING_DEF_REG"
+check plugin_test_4.err "plugin_test_4.a: v2: RESOLVED_IR"
+check plugin_test_4.err "plugin_test_4.a: t17data: RESOLVED_IR"
+check plugin_test_4.err "plugin_test_4.a: _Z4f13iv: PREEMPTED_IR"
+check plugin_test_4.err "two_file_test_1.o: adding new input file"
+check plugin_test_4.err "two_file_test_1b.o: adding new input file"
+check plugin_test_4.err "two_file_test_2.o: adding new input file"
+check plugin_test_4.err "cleanup hook called"
+
+exit 0