summaryrefslogtreecommitdiff
path: root/gold/plugin.cc
diff options
context:
space:
mode:
authorSriraman Tallam <tmsriram@google.com>2018-02-15 17:35:16 -0800
committerSriraman Tallam <tmsriram@google.com>2018-02-15 17:35:16 -0800
commit3281b315c89caf1d539a316e41cc095e46482f75 (patch)
treec324284c8a21bf2bac30f2bb5678cbb430e63867 /gold/plugin.cc
parent43859909e2982252d136e19258431f3aa8afb890 (diff)
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.cc19
1 files changed, 16 insertions, 3 deletions
diff --git a/gold/plugin.cc b/gold/plugin.cc
index 02fef25dda..566f1b7cae 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)