include/ChangeLog

gcc PR lto/47247
	* plugin-api.h (enum ld_plugin_symbol_resolution): Add
	LDPR_PREVAILING_DEF_IRONLY_EXP.
	(enum ld_plugin_tag): Add LDPT_GET_SYMBOLS_V2.

gold/ChangeLog

	gcc PR lto/47247
	* plugin.cc (get_symbols_v2): New function.
	(Plugin::load): Add LDPT_GET_SYMBOLS_V2.
	(is_referenced_from_outside): New function.
	(Pluginobj::get_symbol_resolution_info): Add version parameter, return
	LDPR_PREVAILING_DEF_IRONLY_EXP when using new version.
	(get_symbols): Pass version parameter.
	(get_symbols_v2): New function.
	* plugin.h (Pluginobj::get_symbol_resolution_info): Add version
	parameter.
	* testsuite/plugin_test.c (get_symbols_v2): New static variable.
	(onload): Add LDPT_GET_SYMBOLS_V2.
	(all_symbols_read_hook): Use get_symbols_v2; check for
	LDPR_PREVAILING_DEF_IRONLY_EXP.
	* testsuite/plugin_test_3.sh: Update expected results.
This commit is contained in:
Cary Coutant 2011-09-26 23:00:17 +00:00
parent e91d10767a
commit 235061c2f4
7 changed files with 112 additions and 18 deletions

View File

@ -1,3 +1,21 @@
2011-09-26 Cary Coutant <ccoutant@google.com>
gcc PR lto/47247
* plugin.cc (get_symbols_v2): New function.
(Plugin::load): Add LDPT_GET_SYMBOLS_V2.
(is_referenced_from_outside): New function.
(Pluginobj::get_symbol_resolution_info): Add version parameter, return
LDPR_PREVAILING_DEF_IRONLY_EXP when using new version.
(get_symbols): Pass version parameter.
(get_symbols_v2): New function.
* plugin.h (Pluginobj::get_symbol_resolution_info): Add version
parameter.
* testsuite/plugin_test.c (get_symbols_v2): New static variable.
(onload): Add LDPT_GET_SYMBOLS_V2.
(all_symbols_read_hook): Use get_symbols_v2; check for
LDPR_PREVAILING_DEF_IRONLY_EXP.
* testsuite/plugin_test_3.sh: Update expected results.
2011-09-23 Simon Baldwin <simonb@google.com>
* configure.ac: Add new --with-gold-ldadd and --with-gold-ldflags

View File

@ -77,6 +77,9 @@ 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
get_symbols_v2(const void *handle, int nsyms, struct ld_plugin_symbol *syms);
static enum ld_plugin_status
add_input_file(const char *pathname);
@ -156,7 +159,7 @@ Plugin::load()
sscanf(ver, "%d.%d", &major, &minor);
// Allocate and populate a transfer vector.
const int tv_fixed_size = 23;
const int tv_fixed_size = 24;
int tv_size = this->args_.size() + tv_fixed_size;
ld_plugin_tv* tv = new ld_plugin_tv[tv_size];
@ -227,6 +230,10 @@ Plugin::load()
tv[i].tv_tag = LDPT_GET_SYMBOLS;
tv[i].tv_u.tv_get_symbols = get_symbols;
++i;
tv[i].tv_tag = LDPT_GET_SYMBOLS_V2;
tv[i].tv_u.tv_get_symbols = get_symbols_v2;
++i;
tv[i].tv_tag = LDPT_ADD_INPUT_FILE;
tv[i].tv_u.tv_add_input_file = add_input_file;
@ -810,11 +817,11 @@ Pluginobj::Pluginobj(const std::string& name, Input_file* input_file,
{
}
// Return TRUE if a defined symbol might be reachable from outside the
// Return TRUE if a defined symbol is referenced from outside the
// universe of claimed objects.
static inline bool
is_visible_from_outside(Symbol* lsym)
is_referenced_from_outside(Symbol* lsym)
{
if (lsym->in_real_elf())
return true;
@ -822,6 +829,15 @@ is_visible_from_outside(Symbol* lsym)
return true;
if (parameters->options().is_undefined(lsym->name()))
return true;
return false;
}
// Return TRUE if a defined symbol might be reachable from outside the
// load module.
static inline bool
is_visible_from_outside(Symbol* lsym)
{
if (parameters->options().export_dynamic() || parameters->options().shared())
return lsym->is_externally_visible();
return false;
@ -830,8 +846,18 @@ is_visible_from_outside(Symbol* lsym)
// Get symbol resolution info.
ld_plugin_status
Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
Pluginobj::get_symbol_resolution_info(int nsyms,
ld_plugin_symbol* syms,
int version) const
{
// For version 1 of this interface, we cannot use
// LDPR_PREVAILING_DEF_IRONLY_EXP, so we return LDPR_PREVAILING_DEF
// instead.
const ld_plugin_symbol_resolution ldpr_prevailing_def_ironly_exp
= (version > 1
? LDPR_PREVAILING_DEF_IRONLY_EXP
: LDPR_PREVAILING_DEF);
if (nsyms > this->nsyms_)
return LDPS_NO_SYMS;
@ -862,9 +888,14 @@ Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
if (lsym->source() != Symbol::FROM_OBJECT)
res = LDPR_RESOLVED_EXEC;
else if (lsym->object()->pluginobj() == this)
res = (is_visible_from_outside(lsym)
? LDPR_PREVAILING_DEF
: LDPR_PREVAILING_DEF_IRONLY);
{
if (is_referenced_from_outside(lsym))
res = LDPR_PREVAILING_DEF;
else if (is_visible_from_outside(lsym))
res = ldpr_prevailing_def_ironly_exp;
else
res = LDPR_PREVAILING_DEF_IRONLY;
}
else if (lsym->object()->pluginobj() != NULL)
res = LDPR_RESOLVED_IR;
else if (lsym->object()->is_dynamic())
@ -878,9 +909,14 @@ Pluginobj::get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const
if (lsym->source() != Symbol::FROM_OBJECT)
res = LDPR_PREEMPTED_REG;
else if (lsym->object() == static_cast<const Object*>(this))
res = (is_visible_from_outside(lsym)
? LDPR_PREVAILING_DEF
: LDPR_PREVAILING_DEF_IRONLY);
{
if (is_referenced_from_outside(lsym))
res = LDPR_PREVAILING_DEF;
else if (is_visible_from_outside(lsym))
res = ldpr_prevailing_def_ironly_exp;
else
res = LDPR_PREVAILING_DEF_IRONLY;
}
else
res = (lsym->object()->pluginobj() != NULL
? LDPR_PREEMPTED_IR
@ -1411,7 +1447,24 @@ get_symbols(const void* handle, int nsyms, ld_plugin_symbol* syms)
Pluginobj* plugin_obj = obj->pluginobj();
if (plugin_obj == NULL)
return LDPS_ERR;
return plugin_obj->get_symbol_resolution_info(nsyms, syms);
return plugin_obj->get_symbol_resolution_info(nsyms, syms, 1);
}
// Version 2 of the above. The only difference is that this version
// is allowed to return the resolution code LDPR_PREVAILING_DEF_IRONLY_EXP.
static enum ld_plugin_status
get_symbols_v2(const void* handle, int nsyms, ld_plugin_symbol* syms)
{
gold_assert(parameters->options().has_plugins());
Object* obj = parameters->options().plugins()->object(
static_cast<unsigned int>(reinterpret_cast<intptr_t>(handle)));
if (obj == NULL)
return LDPS_ERR;
Pluginobj* plugin_obj = obj->pluginobj();
if (plugin_obj == NULL)
return LDPS_ERR;
return plugin_obj->get_symbol_resolution_info(nsyms, syms, 2);
}
// Add a new (real) input file generated by a plugin.

View File

@ -393,7 +393,9 @@ class Pluginobj : public Object
// Fill in the symbol resolution status for the given plugin symbols.
ld_plugin_status
get_symbol_resolution_info(int nsyms, ld_plugin_symbol* syms) const;
get_symbol_resolution_info(int nsyms,
ld_plugin_symbol* syms,
int version) const;
// Store the incoming symbols from the plugin for later processing.
void

View File

@ -56,6 +56,7 @@ static ld_plugin_register_all_symbols_read register_all_symbols_read_hook = NULL
static ld_plugin_register_cleanup register_cleanup_hook = NULL;
static ld_plugin_add_symbols add_symbols = NULL;
static ld_plugin_get_symbols get_symbols = NULL;
static ld_plugin_get_symbols get_symbols_v2 = 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;
@ -120,6 +121,9 @@ onload(struct ld_plugin_tv *tv)
case LDPT_GET_SYMBOLS:
get_symbols = entry->tv_u.tv_get_symbols;
break;
case LDPT_GET_SYMBOLS_V2:
get_symbols_v2 = entry->tv_u.tv_get_symbols;
break;
case LDPT_ADD_INPUT_FILE:
add_input_file = entry->tv_u.tv_add_input_file;
break;
@ -394,9 +398,9 @@ all_symbols_read_hook(void)
(*message)(LDPL_INFO, "all symbols read hook called");
if (get_symbols == NULL)
if (get_symbols_v2 == NULL)
{
fprintf(stderr, "tv_get_symbols interface missing\n");
fprintf(stderr, "tv_get_symbols (v2) interface missing\n");
return LDPS_ERR;
}
@ -404,7 +408,7 @@ all_symbols_read_hook(void)
claimed_file != NULL;
claimed_file = claimed_file->next)
{
(*get_symbols)(claimed_file->handle, claimed_file->nsyms,
(*get_symbols_v2)(claimed_file->handle, claimed_file->nsyms,
claimed_file->syms);
for (i = 0; i < claimed_file->nsyms; ++i)
@ -423,6 +427,9 @@ all_symbols_read_hook(void)
case LDPR_PREVAILING_DEF_IRONLY:
res = "PREVAILING_DEF_IRONLY";
break;
case LDPR_PREVAILING_DEF_IRONLY_EXP:
res = "PREVAILING_DEF_IRONLY_EXP";
break;
case LDPR_PREEMPTED_REG:
res = "PREEMPTED_REG";
break;

View File

@ -46,7 +46,7 @@ check plugin_test_3.err "two_file_test_main.o: claim file hook called"
check plugin_test_3.err "two_file_test_1.syms: claim file hook called"
check plugin_test_3.err "two_file_test_1b.syms: claim file hook called"
check plugin_test_3.err "two_file_test_2.syms: claim file hook called"
check plugin_test_3.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_REG"
check plugin_test_3.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_IRONLY_EXP"
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"

View File

@ -1,3 +1,10 @@
2011-09-26 Cary Coutant <ccoutant@google.com>
gcc PR lto/47247
* plugin-api.h (enum ld_plugin_symbol_resolution): Add
LDPR_PREVAILING_DEF_IRONLY_EXP.
(enum ld_plugin_tag): Add LDPT_GET_SYMBOLS_V2.
2011-09-23 Cary Coutant <ccoutant@google.com>
PR 40831

View File

@ -155,7 +155,13 @@ enum ld_plugin_symbol_resolution
LDPR_RESOLVED_EXEC,
/* This symbol was resolved by a definition in a shared object. */
LDPR_RESOLVED_DYN
LDPR_RESOLVED_DYN,
/* This is the prevailing definition of the symbol, with no
references from regular objects. It is only referenced from IR
code, but the symbol is exported and may be referenced from
a dynamic object (not seen at link time). */
LDPR_PREVAILING_DEF_IRONLY_EXP
};
/* The plugin library's "claim file" handler. */
@ -347,7 +353,8 @@ enum ld_plugin_tag
LDPT_GET_INPUT_SECTION_NAME,
LDPT_GET_INPUT_SECTION_CONTENTS,
LDPT_UPDATE_SECTION_ORDER,
LDPT_ALLOW_SECTION_ORDERING
LDPT_ALLOW_SECTION_ORDERING,
LDPT_GET_SYMBOLS_V2
};
/* The plugin transfer vector. */