[gold][patch] Fix plugin API so gold doesn't try to access a closed file
Cary Coutant
ccoutant@google.com
Thu Jan 15 01:20:00 GMT 2009
The linker plugin API to support LTO currently turns over management
of file descriptors that are claimed by the plugin to the plugin. This
is a problem when the IR files happen to be members of archives, and
it also means that if the plugin decides to keep the files open, we
may run out of available file descriptors before completing the link.
The attached patch reworks the API so that the linker retains the
management of file descriptors. It hands a file descriptor to a plugin
in the claim-file interface, and guarantees that the descriptor will
remain valid until the claim-file callback returns to the linker. If
the plugin needs to access the file again during the all-symbols-read
callback, it can use a new get-input-file API to obtain an open file
descriptor, and a new release-input-file API to release it.
A new testcase covers IR files in archive libraries and all plugin
testcases now exercise the two new APIs.
Since the only changes outside of the plugin code are trivial (the
changes to descriptors.* and fileread.* are nearly complete reversions
of the original plugin checkin), I'm going to go ahead and commit this
patch.
-cary
include/:
* plugin-api.h (LDPS_BAD_HANDLE): New constant.
(ld_plugin_get_input_file): New typedef.
(ld_plugin_release_input_file): New typedef.
(LDPT_GET_INPUT_FILE, LDPT_RELEASE_INPUT_FILE): New constants.
(struct ld_plugin_tv): Add two new fields.
gold/:
* 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.
-------------- next part --------------
Index: include/plugin-api.h
===================================================================
RCS file: /cvs/src/src/include/plugin-api.h,v
retrieving revision 1.4
diff -u -p -r1.4 plugin-api.h
--- include/plugin-api.h 1 Dec 2008 19:50:49 -0000 1.4
+++ include/plugin-api.h 14 Jan 2009 01:36:11 -0000
@@ -40,6 +40,7 @@ enum ld_plugin_status
{
LDPS_OK = 0,
LDPS_NO_SYMS, /* Attempt to get symbols that haven't been added. */
+ LDPS_BAD_HANDLE, /* No claimed object associated with given handle. */
LDPS_ERR
/* Additional Error codes TBD. */
};
@@ -165,6 +166,20 @@ enum ld_plugin_status
(*ld_plugin_add_symbols) (void *handle, int nsyms,
const struct ld_plugin_symbol *syms);
+/* The linker's interface for getting the input file information with
+ an open (possibly re-opened) file descriptor. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_get_input_file) (const void *handle,
+ struct ld_plugin_input_file *file);
+
+/* The linker's interface for releasing the input file. */
+
+typedef
+enum ld_plugin_status
+(*ld_plugin_release_input_file) (const void *handle);
+
/* The linker's interface for retrieving symbol resolution information. */
typedef
@@ -207,7 +222,9 @@ enum ld_plugin_tag
LDPT_ADD_SYMBOLS,
LDPT_GET_SYMBOLS,
LDPT_ADD_INPUT_FILE,
- LDPT_MESSAGE
+ LDPT_MESSAGE,
+ LDPT_GET_INPUT_FILE,
+ LDPT_RELEASE_INPUT_FILE
};
/* The plugin transfer vector. */
@@ -226,6 +243,8 @@ struct ld_plugin_tv
ld_plugin_get_symbols tv_get_symbols;
ld_plugin_add_input_file tv_add_input_file;
ld_plugin_message tv_message;
+ ld_plugin_get_input_file tv_get_input_file;
+ ld_plugin_release_input_file tv_release_input_file;
} tv_u;
};
Index: gold/archive.cc
===================================================================
RCS file: /cvs/src/src/gold/archive.cc,v
retrieving revision 1.37
diff -u -p -r1.37 archive.cc
--- gold/archive.cc 29 Sep 2008 21:23:02 -0000 1.37
+++ gold/archive.cc 14 Jan 2009 01:36:12 -0000
@@ -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
{
// 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: gold/descriptors.cc
===================================================================
RCS file: /cvs/src/src/gold/descriptors.cc,v
retrieving revision 1.2
diff -u -p -r1.2 descriptors.cc
--- gold/descriptors.cc 19 Sep 2008 22:54:57 -0000 1.2
+++ gold/descriptors.cc 14 Jan 2009 01:36:12 -0000
@@ -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
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, boo
}
}
-// 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: gold/descriptors.h
===================================================================
RCS file: /cvs/src/src/gold/descriptors.h,v
retrieving revision 1.2
diff -u -p -r1.2 descriptors.h
--- gold/descriptors.h 19 Sep 2008 22:54:57 -0000 1.2
+++ gold/descriptors.h 14 Jan 2009 01:36:12 -0000
@@ -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: gold/fileread.cc
===================================================================
RCS file: /cvs/src/src/gold/fileread.cc,v
retrieving revision 1.46
diff -u -p -r1.46 fileread.cc
--- gold/fileread.cc 19 Sep 2008 22:54:57 -0000 1.46
+++ gold/fileread.cc 14 Jan 2009 01:36:12 -0000
@@ -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: gold/fileread.h
===================================================================
RCS file: /cvs/src/src/gold/fileread.h,v
retrieving revision 1.31
diff -u -p -r1.31 fileread.h
--- gold/fileread.h 19 Sep 2008 22:54:57 -0000 1.31
+++ gold/fileread.h 14 Jan 2009 01:36:12 -0000
@@ -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: gold/plugin.cc
===================================================================
RCS file: /cvs/src/src/gold/plugin.cc,v
retrieving revision 1.8
diff -u -p -r1.8 plugin.cc
--- gold/plugin.cc 24 Dec 2008 06:17:18 -0000 1.8
+++ gold/plugin.cc 14 Jan 2009 01:36:12 -0000
@@ -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.
@@ -62,6 +62,12 @@ 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);
static enum ld_plugin_status
@@ -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];
@@ -163,6 +169,14 @@ Plugin::load()
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* i
// 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(Workque
{
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(unsig
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 *pat
// 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, con
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* inp
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* inp
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* inp
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* inp
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: gold/plugin.h
===================================================================
RCS file: /cvs/src/src/gold/plugin.h,v
retrieving revision 1.4
diff -u -p -r1.4 plugin.h
--- gold/plugin.h 24 Dec 2008 06:17:18 -0000 1.4
+++ gold/plugin.h 14 Jan 2009 01:36:12 -0000
@@ -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: gold/readsyms.cc
===================================================================
RCS file: /cvs/src/src/gold/readsyms.cc,v
retrieving revision 1.31
diff -u -p -r1.31 readsyms.cc
--- gold/readsyms.cc 19 Sep 2008 22:54:57 -0000 1.31
+++ gold/readsyms.cc 14 Jan 2009 01:36:12 -0000
@@ -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*
{
// 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: gold/testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.82
diff -u -p -r1.82 Makefile.am
--- gold/testsuite/Makefile.am 23 Dec 2008 23:46:55 -0000 1.82
+++ gold/testsuite/Makefile.am 14 Jan 2009 01:36:12 -0000
@@ -981,6 +981,18 @@ plugin_test_3: two_file_test_main.o two_
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: gold/testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.87
diff -u -p -r1.87 Makefile.in
--- gold/testsuite/Makefile.in 23 Dec 2008 23:46:55 -0000 1.87
+++ gold/testsuite/Makefile.in 14 Jan 2009 01:36:12 -0000
@@ -293,19 +293,23 @@ check_PROGRAMS = object_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
@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
$(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)
$(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_unitt
@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: gold/testsuite/plugin_test.c
===================================================================
RCS file: /cvs/src/src/gold/testsuite/plugin_test.c,v
retrieving revision 1.2
diff -u -p -r1.2 plugin_test.c
--- gold/testsuite/plugin_test.c 16 Dec 2008 19:19:16 -0000 1.2
+++ gold/testsuite/plugin_test.c 14 Jan 2009 01:36:12 -0000
@@ -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
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(co
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_
/* 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_
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_
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_
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: gold/testsuite/plugin_test_1.sh
===================================================================
RCS file: /cvs/src/src/gold/testsuite/plugin_test_1.sh,v
retrieving revision 1.1
diff -u -p -r1.1 plugin_test_1.sh
--- gold/testsuite/plugin_test_1.sh 19 Sep 2008 22:54:57 -0000 1.1
+++ gold/testsuite/plugin_test_1.sh 14 Jan 2009 01:36:12 -0000
@@ -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
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: gold/testsuite/plugin_test_2.sh
===================================================================
RCS file: /cvs/src/src/gold/testsuite/plugin_test_2.sh,v
retrieving revision 1.1
diff -u -p -r1.1 plugin_test_2.sh
--- gold/testsuite/plugin_test_2.sh 19 Sep 2008 22:54:57 -0000 1.1
+++ gold/testsuite/plugin_test_2.sh 14 Jan 2009 01:36:12 -0000
@@ -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
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: gold/testsuite/plugin_test_3.sh
===================================================================
RCS file: /cvs/src/src/gold/testsuite/plugin_test_3.sh,v
retrieving revision 1.1
diff -u -p -r1.1 plugin_test_3.sh
--- gold/testsuite/plugin_test_3.sh 23 Dec 2008 23:46:55 -0000 1.1
+++ gold/testsuite/plugin_test_3.sh 14 Jan 2009 01:36:12 -0000
@@ -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
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
Index: gold/testsuite/plugin_test_4.sh
===================================================================
RCS file: gold/testsuite/plugin_test_4.sh
diff -N gold/testsuite/plugin_test_4.sh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/plugin_test_4.sh 14 Jan 2009 01:36:12 -0000
@@ -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
More information about the Binutils
mailing list