diff options
author | Rafael Ávila de Espíndola <respindola@mozilla.com> | 2010-03-22 14:18:24 +0000 |
---|---|---|
committer | Rafael Ávila de Espíndola <respindola@mozilla.com> | 2010-03-22 14:18:24 +0000 |
commit | b0193076dad64abdb42ed0057ad668eaf3c17c7a (patch) | |
tree | 52ff18d9073b353700e411c07b9cf8ad4f7c50f5 /gold/object.cc | |
parent | cff8d58ab4a99c8fdcc1572227f9957064b1aaa0 (diff) | |
download | gdb-b0193076dad64abdb42ed0057ad668eaf3c17c7a.zip gdb-b0193076dad64abdb42ed0057ad668eaf3c17c7a.tar.gz gdb-b0193076dad64abdb42ed0057ad668eaf3c17c7a.tar.bz2 |
2010-03-22 Rafael Espindola <espindola@google.com>
* archive.cc (Should_include): Move to archive.h.
(should_include_member): Make it a member of Archive.
(Lib_group): New.
(Add_lib_group_symbols): New.
* archive.h: Include options.h.
(Archive_member): Moved from Archive.
(Should_include): Moved from archive.cc.
(Lib_group): New.
(Add_lib_group_symbols): New.
* dynobj.cc (do_should_include_member): New.
* dynobj.h (do_should_include_member): New.
* gold.cc (queue_initial_tasks): Update call to queue.
* main.cc (main): Print lib group stats.
* object.cc (do_should_include_member): New.
* object.h: Include archive.h.
(Object::should_include_member): New.
(Object::do_should_include_member): New.
(Sized_relobj::do_should_include_member): New.
* options.cc (General_options::parse_start_lib): New.
(General_options::parse_end_lib): New.
(Input_arguments::add_file): Handle lib groups.
(Input_arguments::start_group): Check we are not in a lib.
(Input_arguments::start_lib): New.
(Input_arguments::end_lib): New.
* options.h (General_options): Add start_lib and end_lib.
(Input_argument::lib_): New.
(Input_argument::lib): New.
(Input_argument::is_lib): New.
(Input_file_lib): New.
(Input_arguments::in_lib_): New.
(Input_arguments::in_lib): New.
(Input_arguments::start_lib): New.
(Input_arguments::end_lib_): New.
* plugin.cc (Pluginobj::get_symbol_resolution_info): Mark symbols
in unused members as preempted.
(Sized_pluginobj::do_should_include_member): New.
* plugin.h (Sized_pluginobj::do_should_include_member): New.
* readsyms.cc (Read_symbols::locks): If we are just reading a member,
return the blocker.
(Read_symbols::do_whole_lib_group): New.
(Read_symbols::do_lib_group): New.
(Read_symbols::do_read_symbols): Handle lib groups.
(Read_symbols::get_name): Handle lib groups.
* readsyms.h (Read_symbols): Add an archive member pointer.
(Read_symbols::do_whole_lib_group): New.
(Read_symbols::do_lib_group): New.
(Read_symbols::member_): New.
* script.cc (read_input_script): Update call to queue_soon.
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/gold/object.cc b/gold/object.cc index 73bf370..b9d0028 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1486,6 +1486,55 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab, sd->symbol_names = NULL; } +// Find out if this object, that is a member of a lib group, should be included +// in the link. We check every symbol defined by this object. If the symbol +// table has a strong undefined reference to that symbol, we have to include +// the object. + +template<int size, bool big_endian> +Archive::Should_include +Sized_relobj<size, big_endian>::do_should_include_member(Symbol_table* symtab, + Read_symbols_data* sd, + std::string* why) +{ + char* tmpbuf = NULL; + size_t tmpbuflen = 0; + const char* sym_names = + reinterpret_cast<const char*>(sd->symbol_names->data()); + const unsigned char* syms = + sd->symbols->data() + sd->external_symbols_offset; + const int sym_size = elfcpp::Elf_sizes<size>::sym_size; + size_t symcount = ((sd->symbols_size - sd->external_symbols_offset) + / sym_size); + + const unsigned char* p = syms; + + for (size_t i = 0; i < symcount; ++i, p += sym_size) + { + elfcpp::Sym<size, big_endian> sym(p); + unsigned int st_shndx = sym.get_st_shndx(); + if (st_shndx == elfcpp::SHN_UNDEF) + continue; + + unsigned int st_name = sym.get_st_name(); + const char* name = sym_names + st_name; + Symbol* symbol; + Archive::Should_include t = Archive::should_include_member(symtab, name, + &symbol, why, + &tmpbuf, + &tmpbuflen); + if (t == Archive::SHOULD_INCLUDE_YES) + { + if (tmpbuf != NULL) + free(tmpbuf); + return t; + } + } + if (tmpbuf != NULL) + free(tmpbuf); + return Archive::SHOULD_INCLUDE_UNKNOWN; +} + // First pass over the local symbols. Here we add their names to // *POOL and *DYNPOOL, and we store the symbol value in // THIS->LOCAL_VALUES_. This function is always called from a |