diff options
author | Cary Coutant <ccoutant@google.com> | 2009-01-15 01:29:25 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2009-01-15 01:29:25 +0000 |
commit | 0f7c0701ba26bd4c94e968f6be5c954819c97f81 (patch) | |
tree | 3ffcaaf955c71edad7e9d7b1965894a3e5e3d722 | |
parent | fa7f3e72292434483fbce576f8613a1af727df6c (diff) | |
download | fsf-binutils-gdb-0f7c0701ba26bd4c94e968f6be5c954819c97f81.zip fsf-binutils-gdb-0f7c0701ba26bd4c94e968f6be5c954819c97f81.tar.gz fsf-binutils-gdb-0f7c0701ba26bd4c94e968f6be5c954819c97f81.tar.bz2 |
* 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.
-rw-r--r-- | gold/ChangeLog | 56 | ||||
-rw-r--r-- | gold/archive.cc | 3 | ||||
-rw-r--r-- | gold/descriptors.cc | 24 | ||||
-rw-r--r-- | gold/descriptors.h | 14 | ||||
-rw-r--r-- | gold/fileread.cc | 15 | ||||
-rw-r--r-- | gold/fileread.h | 11 | ||||
-rw-r--r-- | gold/plugin.cc | 102 | ||||
-rw-r--r-- | gold/plugin.h | 46 | ||||
-rw-r--r-- | gold/readsyms.cc | 8 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 12 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 43 | ||||
-rw-r--r-- | gold/testsuite/plugin_test.c | 232 | ||||
-rwxr-xr-x | gold/testsuite/plugin_test_1.sh | 5 | ||||
-rwxr-xr-x | gold/testsuite/plugin_test_2.sh | 4 | ||||
-rwxr-xr-x | gold/testsuite/plugin_test_3.sh | 5 | ||||
-rwxr-xr-x | gold/testsuite/plugin_test_4.sh | 58 |
16 files changed, 476 insertions, 162 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 9e2d1e0..cf06e1f 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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. diff --git a/gold/archive.cc b/gold/archive.cc index 7e2d143..b1ba6d9 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -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; } } diff --git a/gold/descriptors.cc b/gold/descriptors.cc index 73c03bf..18498ef 100644 --- a/gold/descriptors.cc +++ b/gold/descriptors.cc @@ -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 diff --git a/gold/descriptors.h b/gold/descriptors.h index 359008c..1933314 100644 --- a/gold/descriptors.h +++ b/gold/descriptors.h @@ -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) diff --git a/gold/fileread.cc b/gold/fileread.cc index 72abd6b..36eee6c 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -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 diff --git a/gold/fileread.h b/gold/fileread.h index 1b776f1..3afba86 100644 --- a/gold/fileread.h +++ b/gold/fileread.h @@ -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_; } diff --git a/gold/plugin.cc b/gold/plugin.cc index e2a9e60..7d5b1b7 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -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* 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"), diff --git a/gold/plugin.h b/gold/plugin.h index 2ea0370..a8d3dc4 100644 --- a/gold/plugin.h +++ b/gold/plugin.h @@ -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 diff --git a/gold/readsyms.cc b/gold/readsyms.cc index ac646d9..412ffcd 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -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, diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 40daf1a..c318718 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -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 diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index a8644c1..c1ad9c3 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -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 diff --git a/gold/testsuite/plugin_test.c b/gold/testsuite/plugin_test.c index c36fee4..2218d08 100644 --- a/gold/testsuite/plugin_test.c +++ b/gold/testsuite/plugin_test.c @@ -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; +} diff --git a/gold/testsuite/plugin_test_1.sh b/gold/testsuite/plugin_test_1.sh index 5e16139..4d3ed41 100755 --- a/gold/testsuite/plugin_test_1.sh +++ b/gold/testsuite/plugin_test_1.sh @@ -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 diff --git a/gold/testsuite/plugin_test_2.sh b/gold/testsuite/plugin_test_2.sh index 41865ac..a47d22a 100755 --- a/gold/testsuite/plugin_test_2.sh +++ b/gold/testsuite/plugin_test_2.sh @@ -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 diff --git a/gold/testsuite/plugin_test_3.sh b/gold/testsuite/plugin_test_3.sh index 837595f..961df15 100755 --- a/gold/testsuite/plugin_test_3.sh +++ b/gold/testsuite/plugin_test_3.sh @@ -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 index 0000000..89df46c --- /dev/null +++ b/gold/testsuite/plugin_test_4.sh @@ -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 |