diff options
author | Sriraman Tallam <tmsriram@google.com> | 2018-02-15 17:35:16 -0800 |
---|---|---|
committer | Sriraman Tallam <tmsriram@google.com> | 2018-02-15 17:35:16 -0800 |
commit | 3281b315c89caf1d539a316e41cc095e46482f75 (patch) | |
tree | c324284c8a21bf2bac30f2bb5678cbb430e63867 /gold/plugin.cc | |
parent | 43859909e2982252d136e19258431f3aa8afb890 (diff) | |
download | fsf-binutils-gdb-3281b315c89caf1d539a316e41cc095e46482f75.zip fsf-binutils-gdb-3281b315c89caf1d539a316e41cc095e46482f75.tar.gz fsf-binutils-gdb-3281b315c89caf1d539a316e41cc095e46482f75.tar.bz2 |
Fix symbol resolution with linker plugins for defsym symbols.
2018-02-07 Sriraman Tallam <tmsriram@google.com>
* expression.cc (Symbol_expression::set_expr_sym_in_real_elf):
New method.
(Unary_expression::set_expr_sym_in_real_elf): New method.
(Binary_expression::set_expr_sym_in_real_elf): New method.
(Trinary_expression::set_expr_sym_in_real_elf): New method.
* plugin.cc (get_symbol_resolution_info): Fix symbol resolution if
defined or used in defsyms.
* plugin.h (Plugin_manager::is_defsym_def): New method.
(Plugin_manager::Plugin_manager): Initialize defsym_defines_set_.
(Plugin_manager::defsym_defines_set_): New member.
(Plugin_manager::Defsym_defines_set): New typedef.
* script.cc (Script_options::set_defsym_uses_in_real_elf): New method.
(Script_options::find_defsym_defs): New method.
* script.h (Expression::set_expr_sym_in_real_elf): New method.
(Symbol_assignment::is_defsym): New method.
(Symbol_assignment::value): New method.
(Script_options::find_defsym_defs): New method.
(Script_options::set_defsym_uses_in_real_elf): New method.
* testsuite/Makefile.am (plugin_test_defsym): New test.
* testsuite/Makefile.in: Regenerate.
* testsuite/plugin_test.c: Check for new symbol resolution.
* testsuite/plugin_test_defsym.sh: New script.
* testsuite/plugin_test_defsym.c: New test source.
Diffstat (limited to 'gold/plugin.cc')
-rw-r--r-- | gold/plugin.cc | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/gold/plugin.cc b/gold/plugin.cc index 02fef25..566f1b7 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -580,6 +580,11 @@ Plugin_manager::all_symbols_read(Workqueue* workqueue, Task* task, this->mapfile_ = mapfile; this->this_blocker_ = NULL; + // Set symbols used in defsym expressions as seen in real ELF. + Layout *layout = parameters->options().plugins()->layout(); + layout->script_options()->set_defsym_uses_in_real_elf(symtab); + layout->script_options()->find_defsym_defs(this->defsym_defines_set_); + for (this->current_ = this->plugins_.begin(); this->current_ != this->plugins_.end(); ++this->current_) @@ -989,6 +994,7 @@ Pluginobj::get_symbol_resolution_info(Symbol_table* symtab, return version > 2 ? LDPS_NO_SYMS : LDPS_OK; } + Plugin_manager* plugins = parameters->options().plugins(); for (int i = 0; i < nsyms; i++) { ld_plugin_symbol* isym = &syms[i]; @@ -997,9 +1003,16 @@ Pluginobj::get_symbol_resolution_info(Symbol_table* symtab, lsym = symtab->resolve_forwards(lsym); ld_plugin_symbol_resolution res = LDPR_UNKNOWN; - if (lsym->is_undefined()) - // The symbol remains undefined. - res = LDPR_UNDEF; + if (plugins->is_defsym_def(lsym->name())) + { + // The symbol is redefined via defsym. + res = LDPR_PREEMPTED_REG; + } + else if (lsym->is_undefined()) + { + // The symbol remains undefined. + res = LDPR_UNDEF; + } else if (isym->def == LDPK_UNDEF || isym->def == LDPK_WEAKUNDEF || isym->def == LDPK_COMMON) |