* 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.
This commit is contained in:
parent
fa7f3e7229
commit
0f7c0701ba
16 changed files with 479 additions and 165 deletions
|
@ -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>
|
2009-01-07 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* version.cc (version_string): Bump to 1.8.
|
* version.cc (version_string): Bump to 1.8.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// archive.cc -- archive support for gold
|
// 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>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// 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
|
// The input file was claimed by a plugin, and its symbols
|
||||||
// have been provided by the plugin.
|
// have been provided by the plugin.
|
||||||
input_file->file().claim_for_plugin();
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// descriptors.cc -- manage file descriptors for gold
|
// 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>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// 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->inuse = true;
|
||||||
pod->is_write = (flags & O_ACCMODE) != O_RDONLY;
|
pod->is_write = (flags & O_ACCMODE) != O_RDONLY;
|
||||||
|
|
||||||
if (!pod->is_claimed)
|
++this->current_;
|
||||||
++this->current_;
|
|
||||||
pod->is_claimed = false;
|
|
||||||
if (this->current_ >= this->limit_)
|
if (this->current_ >= this->limit_)
|
||||||
this->close_some_descriptor();
|
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 some descriptor. The lock is held when this is called. We
|
||||||
// close the descriptor on the top of the free stack. Note that this
|
// 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
|
// is the opposite of an LRU algorithm--we close the most recently
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// descriptors.h -- manage file descriptors for gold -*- C++ -*-
|
// 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>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// This file is part of gold.
|
||||||
|
@ -56,12 +56,6 @@ class Descriptors
|
||||||
void
|
void
|
||||||
release(int descriptor, bool permanent);
|
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:
|
private:
|
||||||
// Information kept for a descriptor.
|
// Information kept for a descriptor.
|
||||||
struct Open_descriptor
|
struct Open_descriptor
|
||||||
|
@ -75,8 +69,6 @@ class Descriptors
|
||||||
bool inuse;
|
bool inuse;
|
||||||
// Whether this is a write descriptor.
|
// Whether this is a write descriptor.
|
||||||
bool is_write;
|
bool is_write;
|
||||||
// Whether the descriptor has been claimed for a plugin.
|
|
||||||
bool is_claimed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -108,10 +100,6 @@ inline void
|
||||||
release_descriptor(int descriptor, bool permanent)
|
release_descriptor(int descriptor, bool permanent)
|
||||||
{ descriptors.release(descriptor, permanent); }
|
{ descriptors.release(descriptor, permanent); }
|
||||||
|
|
||||||
inline void
|
|
||||||
claim_descriptor_for_plugin(int descriptor)
|
|
||||||
{ descriptors.claim_for_plugin(descriptor); }
|
|
||||||
|
|
||||||
} // End namespace gold.
|
} // End namespace gold.
|
||||||
|
|
||||||
#endif // !defined(GOLD_DESCRIPTORS_H)
|
#endif // !defined(GOLD_DESCRIPTORS_H)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// fileread.cc -- read files for gold
|
// 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>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// This file is part of gold.
|
||||||
|
@ -191,19 +191,6 @@ File_read::release()
|
||||||
this->released_ = true;
|
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.
|
// Lock the file.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// fileread.h -- read files for gold -*- C++ -*-
|
// 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>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// This file is part of gold.
|
||||||
|
@ -109,11 +109,6 @@ class File_read
|
||||||
void
|
void
|
||||||
release();
|
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.
|
// Return the size of the file.
|
||||||
off_t
|
off_t
|
||||||
filesize() const
|
filesize() const
|
||||||
|
@ -190,9 +185,9 @@ class File_read
|
||||||
|
|
||||||
// Return the open file descriptor (for plugins).
|
// Return the open file descriptor (for plugins).
|
||||||
int
|
int
|
||||||
descriptor() const
|
descriptor()
|
||||||
{
|
{
|
||||||
gold_assert(this->descriptor_ >= 0);
|
this->reopen_descriptor();
|
||||||
return this->descriptor_;
|
return this->descriptor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
102
gold/plugin.cc
102
gold/plugin.cc
|
@ -1,6 +1,6 @@
|
||||||
// plugin.c -- plugin manager for gold -*- C++ -*-
|
// 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>.
|
// Written by Cary Coutant <ccoutant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// This file is part of gold.
|
||||||
|
@ -61,6 +61,12 @@ register_cleanup(ld_plugin_cleanup_handler handler);
|
||||||
static enum ld_plugin_status
|
static enum ld_plugin_status
|
||||||
add_symbols(void *handle, int nsyms, const struct ld_plugin_symbol *syms);
|
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
|
static enum ld_plugin_status
|
||||||
get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
|
get_symbols(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
|
||||||
|
|
||||||
|
@ -75,7 +81,7 @@ message(int level, const char *format, ...);
|
||||||
#endif // ENABLE_PLUGINS
|
#endif // ENABLE_PLUGINS
|
||||||
|
|
||||||
static Pluginobj* make_sized_plugin_object(Input_file* input_file,
|
static Pluginobj* make_sized_plugin_object(Input_file* input_file,
|
||||||
off_t offset);
|
off_t offset, off_t filesize);
|
||||||
|
|
||||||
// Plugin methods.
|
// Plugin methods.
|
||||||
|
|
||||||
|
@ -112,7 +118,7 @@ Plugin::load()
|
||||||
sscanf(ver, "%d.%d", &major, &minor);
|
sscanf(ver, "%d.%d", &major, &minor);
|
||||||
|
|
||||||
// Allocate and populate a transfer vector.
|
// 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;
|
int tv_size = this->args_.size() + tv_fixed_size;
|
||||||
ld_plugin_tv *tv = new ld_plugin_tv[tv_size];
|
ld_plugin_tv *tv = new ld_plugin_tv[tv_size];
|
||||||
|
|
||||||
|
@ -162,6 +168,14 @@ Plugin::load()
|
||||||
tv[i].tv_tag = LDPT_ADD_SYMBOLS;
|
tv[i].tv_tag = LDPT_ADD_SYMBOLS;
|
||||||
tv[i].tv_u.tv_add_symbols = add_symbols;
|
tv[i].tv_u.tv_add_symbols = add_symbols;
|
||||||
|
|
||||||
|
++i;
|
||||||
|
tv[i].tv_tag = LDPT_GET_INPUT_FILE;
|
||||||
|
tv[i].tv_u.tv_get_input_file = get_input_file;
|
||||||
|
|
||||||
|
++i;
|
||||||
|
tv[i].tv_tag = LDPT_RELEASE_INPUT_FILE;
|
||||||
|
tv[i].tv_u.tv_release_input_file = release_input_file;
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
tv[i].tv_tag = LDPT_GET_SYMBOLS;
|
tv[i].tv_tag = LDPT_GET_SYMBOLS;
|
||||||
tv[i].tv_u.tv_get_symbols = 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.
|
// Call the all-symbols-read handlers.
|
||||||
|
|
||||||
void
|
void
|
||||||
Plugin_manager::all_symbols_read(Workqueue* workqueue,
|
Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task,
|
||||||
Input_objects* input_objects,
|
Input_objects* input_objects,
|
||||||
Symbol_table* symtab, Layout* layout,
|
Symbol_table* symtab, Layout* layout,
|
||||||
Dirsearch* dirpath, Mapfile* mapfile,
|
Dirsearch* dirpath, Mapfile* mapfile,
|
||||||
|
@ -291,6 +305,7 @@ Plugin_manager::all_symbols_read(Workqueue* workqueue,
|
||||||
{
|
{
|
||||||
this->in_replacement_phase_ = true;
|
this->in_replacement_phase_ = true;
|
||||||
this->workqueue_ = workqueue;
|
this->workqueue_ = workqueue;
|
||||||
|
this->task_ = task;
|
||||||
this->input_objects_ = input_objects;
|
this->input_objects_ = input_objects;
|
||||||
this->symtab_ = symtab;
|
this->symtab_ = symtab;
|
||||||
this->layout_ = layout;
|
this->layout_ = layout;
|
||||||
|
@ -344,11 +359,45 @@ Plugin_manager::make_plugin_object(unsigned int handle)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Pluginobj* obj = make_sized_plugin_object(this->input_file_,
|
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);
|
this->objects_.push_back(obj);
|
||||||
return 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.
|
// Add a new input file.
|
||||||
|
|
||||||
ld_plugin_status
|
ld_plugin_status
|
||||||
|
@ -375,9 +424,9 @@ Plugin_manager::add_input_file(char *pathname)
|
||||||
// Class Pluginobj.
|
// Class Pluginobj.
|
||||||
|
|
||||||
Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
|
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),
|
: 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(
|
Sized_pluginobj<size, big_endian>::Sized_pluginobj(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
Input_file* input_file,
|
Input_file* input_file,
|
||||||
off_t offset)
|
off_t offset,
|
||||||
: Pluginobj(name, input_file, 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());
|
gold_assert(this->options_.has_plugins());
|
||||||
this->options_.plugins()->all_symbols_read(workqueue,
|
this->options_.plugins()->all_symbols_read(workqueue,
|
||||||
|
this,
|
||||||
this->input_objects_,
|
this->input_objects_,
|
||||||
this->symtab_,
|
this->symtab_,
|
||||||
this->layout_,
|
this->layout_,
|
||||||
|
@ -880,6 +931,29 @@ add_symbols(void* handle, int nsyms, const ld_plugin_symbol *syms)
|
||||||
return LDPS_OK;
|
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.
|
// Get the symbol resolution info for a plugin-claimed input file.
|
||||||
|
|
||||||
static enum ld_plugin_status
|
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.
|
// Allocate a Pluginobj object of the appropriate size and endianness.
|
||||||
|
|
||||||
static Pluginobj*
|
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;
|
Target* target;
|
||||||
Pluginobj* obj = NULL;
|
Pluginobj* obj = NULL;
|
||||||
|
@ -951,7 +1025,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
||||||
if (target->is_big_endian())
|
if (target->is_big_endian())
|
||||||
#ifdef HAVE_TARGET_32_BIG
|
#ifdef HAVE_TARGET_32_BIG
|
||||||
obj = new Sized_pluginobj<32, true>(input_file->filename(),
|
obj = new Sized_pluginobj<32, true>(input_file->filename(),
|
||||||
input_file, offset);
|
input_file, offset, filesize);
|
||||||
#else
|
#else
|
||||||
gold_error(_("%s: not configured to support "
|
gold_error(_("%s: not configured to support "
|
||||||
"32-bit big-endian object"),
|
"32-bit big-endian object"),
|
||||||
|
@ -960,7 +1034,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
||||||
else
|
else
|
||||||
#ifdef HAVE_TARGET_32_LITTLE
|
#ifdef HAVE_TARGET_32_LITTLE
|
||||||
obj = new Sized_pluginobj<32, false>(input_file->filename(),
|
obj = new Sized_pluginobj<32, false>(input_file->filename(),
|
||||||
input_file, offset);
|
input_file, offset, filesize);
|
||||||
#else
|
#else
|
||||||
gold_error(_("%s: not configured to support "
|
gold_error(_("%s: not configured to support "
|
||||||
"32-bit little-endian object"),
|
"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())
|
if (target->is_big_endian())
|
||||||
#ifdef HAVE_TARGET_64_BIG
|
#ifdef HAVE_TARGET_64_BIG
|
||||||
obj = new Sized_pluginobj<64, true>(input_file->filename(),
|
obj = new Sized_pluginobj<64, true>(input_file->filename(),
|
||||||
input_file, offset);
|
input_file, offset, filesize);
|
||||||
#else
|
#else
|
||||||
gold_error(_("%s: not configured to support "
|
gold_error(_("%s: not configured to support "
|
||||||
"64-bit big-endian object"),
|
"64-bit big-endian object"),
|
||||||
|
@ -981,7 +1055,7 @@ make_sized_plugin_object(Input_file* input_file, off_t offset)
|
||||||
else
|
else
|
||||||
#ifdef HAVE_TARGET_64_LITTLE
|
#ifdef HAVE_TARGET_64_LITTLE
|
||||||
obj = new Sized_pluginobj<64, false>(input_file->filename(),
|
obj = new Sized_pluginobj<64, false>(input_file->filename(),
|
||||||
input_file, offset);
|
input_file, offset, filesize);
|
||||||
#else
|
#else
|
||||||
gold_error(_("%s: not configured to support "
|
gold_error(_("%s: not configured to support "
|
||||||
"64-bit little-endian object"),
|
"64-bit little-endian object"),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// plugin.h -- plugin manager for gold -*- C++ -*-
|
// 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>.
|
// Written by Cary Coutant <ccoutant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// This file is part of gold.
|
||||||
|
@ -122,8 +122,9 @@ class Plugin_manager
|
||||||
Plugin_manager(const General_options& options)
|
Plugin_manager(const General_options& options)
|
||||||
: plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
|
: plugins_(), objects_(), deferred_layout_objects_(), input_file_(NULL),
|
||||||
plugin_input_file_(), in_replacement_phase_(false), cleanup_done_(false),
|
plugin_input_file_(), in_replacement_phase_(false), cleanup_done_(false),
|
||||||
options_(options), workqueue_(NULL), input_objects_(NULL), symtab_(NULL),
|
options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL),
|
||||||
layout_(NULL), dirpath_(NULL), mapfile_(NULL), this_blocker_(NULL)
|
symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL),
|
||||||
|
this_blocker_(NULL)
|
||||||
{ this->current_ = plugins_.end(); }
|
{ this->current_ = plugins_.end(); }
|
||||||
|
|
||||||
~Plugin_manager();
|
~Plugin_manager();
|
||||||
|
@ -151,9 +152,10 @@ class Plugin_manager
|
||||||
|
|
||||||
// Call the all-symbols-read handlers.
|
// Call the all-symbols-read handlers.
|
||||||
void
|
void
|
||||||
all_symbols_read(Workqueue* workqueue, Input_objects* input_objects,
|
all_symbols_read(Workqueue* workqueue, Task* task,
|
||||||
Symbol_table* symtab, Layout* layout, Dirsearch* dirpath,
|
Input_objects* input_objects, Symbol_table* symtab,
|
||||||
Mapfile* mapfile, Task_token** last_blocker);
|
Layout* layout, Dirsearch* dirpath, Mapfile* mapfile,
|
||||||
|
Task_token** last_blocker);
|
||||||
|
|
||||||
// Run deferred layout.
|
// Run deferred layout.
|
||||||
void
|
void
|
||||||
|
@ -214,6 +216,15 @@ class Plugin_manager
|
||||||
add_deferred_layout_object(Relobj* obj)
|
add_deferred_layout_object(Relobj* obj)
|
||||||
{ this->deferred_layout_objects_.push_back(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.
|
// Add a new input file.
|
||||||
ld_plugin_status
|
ld_plugin_status
|
||||||
add_input_file(char *pathname);
|
add_input_file(char *pathname);
|
||||||
|
@ -257,6 +268,7 @@ class Plugin_manager
|
||||||
|
|
||||||
const General_options& options_;
|
const General_options& options_;
|
||||||
Workqueue* workqueue_;
|
Workqueue* workqueue_;
|
||||||
|
Task* task_;
|
||||||
Input_objects* input_objects_;
|
Input_objects* input_objects_;
|
||||||
Symbol_table* symtab_;
|
Symbol_table* symtab_;
|
||||||
Layout* layout_;
|
Layout* layout_;
|
||||||
|
@ -275,7 +287,8 @@ class Pluginobj : public Object
|
||||||
|
|
||||||
typedef std::vector<Symbol*> Symbols;
|
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.
|
// Fill in the symbol resolution status for the given plugin symbols.
|
||||||
ld_plugin_status
|
ld_plugin_status
|
||||||
|
@ -299,6 +312,21 @@ class Pluginobj : public Object
|
||||||
bool
|
bool
|
||||||
include_comdat_group(std::string comdat_key, Layout* layout);
|
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:
|
protected:
|
||||||
// Return TRUE if this is an object claimed by a plugin.
|
// Return TRUE if this is an object claimed by a plugin.
|
||||||
virtual Pluginobj*
|
virtual Pluginobj*
|
||||||
|
@ -320,6 +348,8 @@ class Pluginobj : public Object
|
||||||
Symbols symbols_;
|
Symbols symbols_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Size of the file (or archive member).
|
||||||
|
off_t filesize_;
|
||||||
// Map a comdat key symbol to a boolean indicating whether the comdat
|
// Map a comdat key symbol to a boolean indicating whether the comdat
|
||||||
// group in this object with that key should be kept.
|
// group in this object with that key should be kept.
|
||||||
typedef Unordered_map<std::string, bool> Comdat_map;
|
typedef Unordered_map<std::string, bool> Comdat_map;
|
||||||
|
@ -333,7 +363,7 @@ class Sized_pluginobj : public Pluginobj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sized_pluginobj(const std::string& name, Input_file* input_file,
|
Sized_pluginobj(const std::string& name, Input_file* input_file,
|
||||||
off_t offset);
|
off_t offset, off_t filesize);
|
||||||
|
|
||||||
// Read the symbols.
|
// Read the symbols.
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// readsyms.cc -- read input file symbols for gold
|
// 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>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
||||||
|
|
||||||
// This file is part of gold.
|
// 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
|
// The input file was claimed by a plugin, and its symbols
|
||||||
// have been provided by the plugin.
|
// 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_,
|
workqueue->queue_next(new Add_plugin_symbols(this->symtab_,
|
||||||
this->layout_,
|
this->layout_,
|
||||||
obj,
|
obj,
|
||||||
|
|
|
@ -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
|
plugin_test_3.err: plugin_test_3
|
||||||
@touch plugin_test_3.err
|
@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
|
plugin_test.so: plugin_test.o
|
||||||
$(LINK) -Bgcctestdir/ -shared plugin_test.o
|
$(LINK) -Bgcctestdir/ -shared plugin_test.o
|
||||||
plugin_test.o: plugin_test.c
|
plugin_test.o: plugin_test.c
|
||||||
|
|
|
@ -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@am__append_20 = \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_1 \
|
@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_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@am__append_21 = \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_1.sh \
|
@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_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@am__append_22 = \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_1.err \
|
@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_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@am__append_23 = \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_1.err \
|
@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_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
|
subdir = testsuite
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
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@ 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@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_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_SOURCES = basic_pic_test.c
|
||||||
basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT)
|
basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT)
|
||||||
basic_pic_test_LDADD = $(LDADD)
|
basic_pic_test_LDADD = $(LDADD)
|
||||||
|
@ -582,6 +587,12 @@ plugin_test_3_LDADD = $(LDADD)
|
||||||
plugin_test_3_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
plugin_test_3_DEPENDENCIES = libgoldtest.a ../libgold.a \
|
||||||
../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
|
||||||
$(am__DEPENDENCIES_1) $(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 \
|
am__protected_1_SOURCES_DIST = protected_main_1.cc protected_main_2.cc \
|
||||||
protected_main_3.cc
|
protected_main_3.cc
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_protected_1_OBJECTS = \
|
@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 \
|
$(initpri1_SOURCES) $(justsyms_SOURCES) many_sections_r_test.c \
|
||||||
$(many_sections_test_SOURCES) $(object_unittest_SOURCES) \
|
$(many_sections_test_SOURCES) $(object_unittest_SOURCES) \
|
||||||
plugin_test_1.c plugin_test_2.c plugin_test_3.c \
|
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) \
|
$(relro_script_test_SOURCES) $(relro_test_SOURCES) \
|
||||||
$(script_test_1_SOURCES) $(script_test_2_SOURCES) \
|
$(script_test_1_SOURCES) $(script_test_2_SOURCES) \
|
||||||
script_test_3.c $(thin_archive_test_1_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) \
|
$(am__initpri1_SOURCES_DIST) $(am__justsyms_SOURCES_DIST) \
|
||||||
many_sections_r_test.c $(am__many_sections_test_SOURCES_DIST) \
|
many_sections_r_test.c $(am__many_sections_test_SOURCES_DIST) \
|
||||||
$(object_unittest_SOURCES) plugin_test_1.c plugin_test_2.c \
|
$(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__protected_2_SOURCES_DIST) \
|
||||||
$(am__relro_script_test_SOURCES_DIST) \
|
$(am__relro_script_test_SOURCES_DIST) \
|
||||||
$(am__relro_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@plugin_test_3$(EXEEXT): $(plugin_test_3_OBJECTS) $(plugin_test_3_DEPENDENCIES)
|
||||||
@PLUGINS_FALSE@ @rm -f plugin_test_3$(EXEEXT)
|
@PLUGINS_FALSE@ @rm -f plugin_test_3$(EXEEXT)
|
||||||
@PLUGINS_FALSE@ $(LINK) $(plugin_test_3_LDFLAGS) $(plugin_test_3_OBJECTS) $(plugin_test_3_LDADD) $(LIBS)
|
@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)
|
protected_1$(EXEEXT): $(protected_1_OBJECTS) $(protected_1_DEPENDENCIES)
|
||||||
@rm -f protected_1$(EXEEXT)
|
@rm -f protected_1$(EXEEXT)
|
||||||
$(CXXLINK) $(protected_1_LDFLAGS) $(protected_1_OBJECTS) $(protected_1_LDADD) $(LIBS)
|
$(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_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_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_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_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_1.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protected_main_2.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@ $(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@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@ @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@plugin_test.so: plugin_test.o
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(LINK) -Bgcctestdir/ -shared plugin_test.o
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(LINK) -Bgcctestdir/ -shared plugin_test.o
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* test_plugin.c -- simple linker plugin test
|
/* 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>.
|
Written by Cary Coutant <ccoutant@google.com>.
|
||||||
|
|
||||||
This file is part of gold.
|
This file is part of gold.
|
||||||
|
@ -34,6 +34,16 @@ struct claimed_file
|
||||||
struct claimed_file* next;
|
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* first_claimed_file = NULL;
|
||||||
static struct claimed_file* last_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_get_symbols get_symbols = NULL;
|
||||||
static ld_plugin_add_input_file add_input_file = NULL;
|
static ld_plugin_add_input_file add_input_file = NULL;
|
||||||
static ld_plugin_message message = 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
|
#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 all_symbols_read_hook(void);
|
||||||
enum ld_plugin_status cleanup_hook(void);
|
enum ld_plugin_status cleanup_hook(void);
|
||||||
|
|
||||||
|
static void parse_readelf_line(char*, struct sym_info*);
|
||||||
|
|
||||||
enum ld_plugin_status
|
enum ld_plugin_status
|
||||||
onload(struct ld_plugin_tv *tv)
|
onload(struct ld_plugin_tv *tv)
|
||||||
{
|
{
|
||||||
|
@ -102,6 +116,12 @@ onload(struct ld_plugin_tv *tv)
|
||||||
case LDPT_MESSAGE:
|
case LDPT_MESSAGE:
|
||||||
message = entry->tv_u.tv_message;
|
message = entry->tv_u.tv_message;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -162,21 +182,17 @@ enum ld_plugin_status
|
||||||
claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
|
claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
off_t end_offset;
|
||||||
char buf[160];
|
char buf[160];
|
||||||
struct claimed_file* claimed_file;
|
struct claimed_file* claimed_file;
|
||||||
struct ld_plugin_symbol* syms;
|
struct ld_plugin_symbol* syms;
|
||||||
int nsyms = 0;
|
int nsyms = 0;
|
||||||
int maxsyms = 0;
|
int maxsyms = 0;
|
||||||
FILE* irfile;
|
FILE* irfile;
|
||||||
char *p;
|
struct sym_info info;
|
||||||
char *pbind;
|
|
||||||
char *pvis;
|
|
||||||
char *psect;
|
|
||||||
int weak;
|
int weak;
|
||||||
int def;
|
int def;
|
||||||
int vis;
|
int vis;
|
||||||
int size;
|
|
||||||
char* name;
|
|
||||||
int is_comdat;
|
int is_comdat;
|
||||||
int i;
|
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. */
|
/* Look for the beginning of output from readelf -s. */
|
||||||
irfile = fdopen(file->fd, "r");
|
irfile = fdopen(file->fd, "r");
|
||||||
(void)fseek(irfile, file->offset, SEEK_SET);
|
(void)fseek(irfile, file->offset, SEEK_SET);
|
||||||
|
end_offset = file->offset + file->filesize;
|
||||||
len = fread(buf, 1, 13, irfile);
|
len = fread(buf, 1, 13, irfile);
|
||||||
if (len < 13 || strncmp(buf, "\nSymbol table", 13) != 0)
|
if (len < 13 || strncmp(buf, "\nSymbol table", 13) != 0)
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
|
@ -207,68 +224,28 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
|
||||||
if (syms == NULL)
|
if (syms == NULL)
|
||||||
return LDPS_ERR;
|
return LDPS_ERR;
|
||||||
maxsyms = 8;
|
maxsyms = 8;
|
||||||
while (fgets(buf, sizeof(buf), irfile) != NULL)
|
while (ftell(irfile) < end_offset
|
||||||
|
&& fgets(buf, sizeof(buf), irfile) != NULL)
|
||||||
{
|
{
|
||||||
p = buf;
|
parse_readelf_line(buf, &info);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Ignore local symbols. */
|
/* Ignore local symbols. */
|
||||||
if (strncmp(pbind, "LOCAL", 5) == 0)
|
if (strncmp(info.bind, "LOCAL", 5) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
weak = strncmp(pbind, "WEAK", 4) == 0;
|
weak = strncmp(info.bind, "WEAK", 4) == 0;
|
||||||
if (strncmp(psect, "UND", 3) == 0)
|
if (strncmp(info.sect, "UND", 3) == 0)
|
||||||
def = weak ? LDPK_WEAKUNDEF : LDPK_UNDEF;
|
def = weak ? LDPK_WEAKUNDEF : LDPK_UNDEF;
|
||||||
else if (strncmp(psect, "COM", 3) == 0)
|
else if (strncmp(info.sect, "COM", 3) == 0)
|
||||||
def = LDPK_COMMON;
|
def = LDPK_COMMON;
|
||||||
else
|
else
|
||||||
def = weak ? LDPK_WEAKDEF : LDPK_DEF;
|
def = weak ? LDPK_WEAKDEF : LDPK_DEF;
|
||||||
|
|
||||||
if (strncmp(pvis, "INTERNAL", 8) == 0)
|
if (strncmp(info.vis, "INTERNAL", 8) == 0)
|
||||||
vis = LDPV_INTERNAL;
|
vis = LDPV_INTERNAL;
|
||||||
else if (strncmp(pvis, "HIDDEN", 6) == 0)
|
else if (strncmp(info.vis, "HIDDEN", 6) == 0)
|
||||||
vis = LDPV_HIDDEN;
|
vis = LDPV_HIDDEN;
|
||||||
else if (strncmp(pvis, "PROTECTED", 9) == 0)
|
else if (strncmp(info.vis, "PROTECTED", 9) == 0)
|
||||||
vis = LDPV_PROTECTED;
|
vis = LDPV_PROTECTED;
|
||||||
else
|
else
|
||||||
vis = LDPV_DEFAULT;
|
vis = LDPV_DEFAULT;
|
||||||
|
@ -278,7 +255,7 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
|
||||||
is_comdat = 0;
|
is_comdat = 0;
|
||||||
for (i = 0; i < nopts; ++i)
|
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;
|
is_comdat = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -294,12 +271,19 @@ claim_file_hook (const struct ld_plugin_input_file* file, int* claimed)
|
||||||
maxsyms *= 2;
|
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].version = NULL;
|
||||||
syms[nsyms].def = def;
|
syms[nsyms].def = def;
|
||||||
syms[nsyms].visibility = vis;
|
syms[nsyms].visibility = vis;
|
||||||
syms[nsyms].size = size;
|
syms[nsyms].size = info.size;
|
||||||
syms[nsyms].comdat_key = is_comdat ? name : NULL;
|
syms[nsyms].comdat_key = is_comdat ? syms[nsyms].name : NULL;
|
||||||
syms[nsyms].resolution = LDPR_UNKNOWN;
|
syms[nsyms].resolution = LDPR_UNKNOWN;
|
||||||
++nsyms;
|
++nsyms;
|
||||||
}
|
}
|
||||||
|
@ -335,8 +319,14 @@ all_symbols_read_hook(void)
|
||||||
int i;
|
int i;
|
||||||
const char* res;
|
const char* res;
|
||||||
struct claimed_file* claimed_file;
|
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 buf[160];
|
||||||
char *p;
|
char* p;
|
||||||
|
const char* filename;
|
||||||
|
|
||||||
(*message)(LDPL_INFO, "all symbols read hook called");
|
(*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,
|
(*get_symbols)(claimed_file->handle, claimed_file->nsyms,
|
||||||
claimed_file->syms);
|
claimed_file->syms);
|
||||||
|
|
||||||
for (i = 0; i < claimed_file->nsyms; ++i)
|
for (i = 0; i < claimed_file->nsyms; ++i)
|
||||||
{
|
{
|
||||||
switch (claimed_file->syms[i].resolution)
|
switch (claimed_file->syms[i].resolution)
|
||||||
|
@ -397,28 +388,83 @@ all_symbols_read_hook(void)
|
||||||
fprintf(stderr, "tv_add_input_file interface missing\n");
|
fprintf(stderr, "tv_add_input_file interface missing\n");
|
||||||
return LDPS_ERR;
|
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;
|
for (claimed_file = first_claimed_file;
|
||||||
claimed_file != NULL;
|
claimed_file != NULL;
|
||||||
claimed_file = claimed_file->next)
|
claimed_file = claimed_file->next)
|
||||||
{
|
{
|
||||||
if (claimed_file->nsyms == 0)
|
(*get_input_file) (claimed_file->handle, &file);
|
||||||
continue;
|
|
||||||
if (strlen(claimed_file->name) >= sizeof(buf))
|
/* 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)
|
||||||
{
|
{
|
||||||
(*message)(LDPL_FATAL, "%s: filename too long", claimed_file->name);
|
fprintf(stderr, "%s: can't re-read original input file\n",
|
||||||
|
claimed_file->name);
|
||||||
return LDPS_ERR;
|
return LDPS_ERR;
|
||||||
}
|
}
|
||||||
strcpy(buf, claimed_file->name);
|
|
||||||
p = strrchr(buf, '.');
|
/* Skip the two header lines. */
|
||||||
if (p == NULL || strcmp(p, ".syms") != 0)
|
(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)
|
||||||
{
|
{
|
||||||
(*message)(LDPL_FATAL, "%s: filename must have '.syms' suffix",
|
parse_readelf_line(buf, &info);
|
||||||
claimed_file->name);
|
|
||||||
|
/* 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(filename) >= sizeof(buf))
|
||||||
|
{
|
||||||
|
(*message)(LDPL_FATAL, "%s: filename too long", filename);
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
strcpy(buf, filename);
|
||||||
|
p = strrchr(buf, '.');
|
||||||
|
if (p == NULL
|
||||||
|
|| (strcmp(p, ".syms") != 0
|
||||||
|
&& strcmp(p, ".c") != 0
|
||||||
|
&& strcmp(p, ".cc") != 0))
|
||||||
|
{
|
||||||
|
(*message)(LDPL_FATAL, "%s: filename has unknown suffix",
|
||||||
|
filename);
|
||||||
return LDPS_ERR;
|
return LDPS_ERR;
|
||||||
}
|
}
|
||||||
p[1] = 'o';
|
p[1] = 'o';
|
||||||
p[2] = '\0';
|
p[2] = '\0';
|
||||||
|
(*message)(LDPL_INFO, "%s: adding new input file", buf);
|
||||||
(*add_input_file)(buf);
|
(*add_input_file)(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,3 +477,53 @@ cleanup_hook(void)
|
||||||
(*message)(LDPL_INFO, "cleanup hook called");
|
(*message)(LDPL_INFO, "cleanup hook called");
|
||||||
return LDPS_OK;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# plugin_test_1.sh -- a test case for the plugin API.
|
# 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>.
|
# Written by Cary Coutant <ccoutant@google.com>.
|
||||||
|
|
||||||
# This file is part of gold.
|
# 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: v2: RESOLVED_IR"
|
||||||
check plugin_test_1.err "two_file_test_1.syms: t17data: 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_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"
|
check plugin_test_1.err "cleanup hook called"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# plugin_test_2.sh -- a test case for the plugin API.
|
# 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>.
|
# Written by Cary Coutant <ccoutant@google.com>.
|
||||||
|
|
||||||
# This file is part of gold.
|
# 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: _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: 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.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"
|
check plugin_test_2.err "cleanup hook called"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# plugin_test_3.sh -- a test case for the plugin API.
|
# 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>.
|
# Written by Cary Coutant <ccoutant@google.com>.
|
||||||
|
|
||||||
# This file is part of gold.
|
# 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: v2: RESOLVED_IR"
|
||||||
check plugin_test_3.err "two_file_test_1.syms: t17data: 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_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"
|
check plugin_test_3.err "cleanup hook called"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
58
gold/testsuite/plugin_test_4.sh
Executable file
58
gold/testsuite/plugin_test_4.sh
Executable file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue