mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 01:28:46 +00:00
* resolve.cc (Symbol_table::resolve): Remember whether undef was
weak when resolving to a dynamic def. (Symbol_table::should_override): Add adjust_dyndef flag; set it for weak undef/dynamic def cases. Adjust callers. * symtab.cc (Symbol::init_fields): Initialize undef_binding_set_ and undef_binding_weak_. (Symbol_table::sized_write_globals): Adjust symbol binding. (Symbol_table::sized_write_symbol): Add binding parameter. * symtab.h (Symbol::set_undef_binding): New method. (Symbol::is_undef_binding_weak): New method. (Symbol::undef_binding_set_, Symbol::undef_binding_weak_): New members. (Symbol_table::should_override): Add new parameter. (Symbol_table::sized_write_symbol): Add new parameter. * testsuite/weak_undef_file1.cc: Add new test case. * testsuite/weak_undef_file2.cc: Fix header comment. * testsuite/weak_undef_test.cc: Add new test case.
This commit is contained in:
@@ -335,18 +335,33 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
||||
sym.get_st_type());
|
||||
|
||||
bool adjust_common_sizes;
|
||||
bool adjust_dyndef;
|
||||
typename Sized_symbol<size>::Size_type tosize = to->symsize();
|
||||
if (Symbol_table::should_override(to, frombits, OBJECT, object,
|
||||
&adjust_common_sizes))
|
||||
&adjust_common_sizes,
|
||||
&adjust_dyndef))
|
||||
{
|
||||
elfcpp::STB tobinding = to->binding();
|
||||
this->override(to, sym, st_shndx, is_ordinary, object, version);
|
||||
if (adjust_common_sizes && tosize > to->symsize())
|
||||
to->set_symsize(tosize);
|
||||
if (adjust_dyndef)
|
||||
{
|
||||
// We are overriding an UNDEF or WEAK UNDEF with a DYN DEF.
|
||||
// Remember which kind of UNDEF it was for future reference.
|
||||
to->set_undef_binding(tobinding);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (adjust_common_sizes && sym.get_st_size() > tosize)
|
||||
to->set_symsize(sym.get_st_size());
|
||||
if (adjust_dyndef)
|
||||
{
|
||||
// We are keeping a DYN DEF after seeing an UNDEF or WEAK UNDEF.
|
||||
// Remember which kind of UNDEF it was.
|
||||
to->set_undef_binding(sym.get_st_bind());
|
||||
}
|
||||
// The ELF ABI says that even for a reference to a symbol we
|
||||
// merge the visibility.
|
||||
to->override_visibility(sym.get_st_visibility());
|
||||
@@ -381,9 +396,11 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
||||
bool
|
||||
Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
Defined defined, Object* object,
|
||||
bool* adjust_common_sizes)
|
||||
bool* adjust_common_sizes,
|
||||
bool* adjust_dyndef)
|
||||
{
|
||||
*adjust_common_sizes = false;
|
||||
*adjust_dyndef = false;
|
||||
|
||||
unsigned int tobits;
|
||||
if (to->source() == Symbol::IS_UNDEFINED)
|
||||
@@ -531,12 +548,17 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
return false;
|
||||
|
||||
case UNDEF * 16 + DYN_DEF:
|
||||
case WEAK_UNDEF * 16 + DYN_DEF:
|
||||
case DYN_UNDEF * 16 + DYN_DEF:
|
||||
case DYN_WEAK_UNDEF * 16 + DYN_DEF:
|
||||
// Use a dynamic definition if we have a reference.
|
||||
return true;
|
||||
|
||||
case WEAK_UNDEF * 16 + DYN_DEF:
|
||||
// When overriding a weak undef by a dynamic definition,
|
||||
// we need to remember that the original undef was weak.
|
||||
*adjust_dyndef = true;
|
||||
return true;
|
||||
|
||||
case COMMON * 16 + DYN_DEF:
|
||||
case WEAK_COMMON * 16 + DYN_DEF:
|
||||
case DYN_COMMON * 16 + DYN_DEF:
|
||||
@@ -554,12 +576,17 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
return false;
|
||||
|
||||
case UNDEF * 16 + DYN_WEAK_DEF:
|
||||
case WEAK_UNDEF * 16 + DYN_WEAK_DEF:
|
||||
case DYN_UNDEF * 16 + DYN_WEAK_DEF:
|
||||
case DYN_WEAK_UNDEF * 16 + DYN_WEAK_DEF:
|
||||
// Use a weak dynamic definition if we have a reference.
|
||||
return true;
|
||||
|
||||
case WEAK_UNDEF * 16 + DYN_WEAK_DEF:
|
||||
// When overriding a weak undef by a dynamic definition,
|
||||
// we need to remember that the original undef was weak.
|
||||
*adjust_dyndef = true;
|
||||
return true;
|
||||
|
||||
case COMMON * 16 + DYN_WEAK_DEF:
|
||||
case WEAK_COMMON * 16 + DYN_WEAK_DEF:
|
||||
case DYN_COMMON * 16 + DYN_WEAK_DEF:
|
||||
@@ -570,12 +597,16 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
|
||||
case DEF * 16 + UNDEF:
|
||||
case WEAK_DEF * 16 + UNDEF:
|
||||
case DYN_DEF * 16 + UNDEF:
|
||||
case DYN_WEAK_DEF * 16 + UNDEF:
|
||||
case UNDEF * 16 + UNDEF:
|
||||
// A new undefined reference tells us nothing.
|
||||
return false;
|
||||
|
||||
case DYN_DEF * 16 + UNDEF:
|
||||
case DYN_WEAK_DEF * 16 + UNDEF:
|
||||
// For a dynamic def, we need to remember which kind of undef we see.
|
||||
*adjust_dyndef = true;
|
||||
return false;
|
||||
|
||||
case WEAK_UNDEF * 16 + UNDEF:
|
||||
case DYN_UNDEF * 16 + UNDEF:
|
||||
case DYN_WEAK_UNDEF * 16 + UNDEF:
|
||||
@@ -591,8 +622,6 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
|
||||
case DEF * 16 + WEAK_UNDEF:
|
||||
case WEAK_DEF * 16 + WEAK_UNDEF:
|
||||
case DYN_DEF * 16 + WEAK_UNDEF:
|
||||
case DYN_WEAK_DEF * 16 + WEAK_UNDEF:
|
||||
case UNDEF * 16 + WEAK_UNDEF:
|
||||
case WEAK_UNDEF * 16 + WEAK_UNDEF:
|
||||
case DYN_UNDEF * 16 + WEAK_UNDEF:
|
||||
@@ -604,6 +633,12 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
// A new weak undefined reference tells us nothing.
|
||||
return false;
|
||||
|
||||
case DYN_DEF * 16 + WEAK_UNDEF:
|
||||
case DYN_WEAK_DEF * 16 + WEAK_UNDEF:
|
||||
// For a dynamic def, we need to remember which kind of undef we see.
|
||||
*adjust_dyndef = true;
|
||||
return false;
|
||||
|
||||
case DEF * 16 + DYN_UNDEF:
|
||||
case WEAK_DEF * 16 + DYN_UNDEF:
|
||||
case DYN_DEF * 16 + DYN_UNDEF:
|
||||
@@ -811,10 +846,12 @@ bool
|
||||
Symbol_table::should_override_with_special(const Symbol* to, Defined defined)
|
||||
{
|
||||
bool adjust_common_sizes;
|
||||
bool adjust_dyn_def;
|
||||
unsigned int frombits = global_flag | regular_flag | def_flag;
|
||||
bool ret = Symbol_table::should_override(to, frombits, defined, NULL,
|
||||
&adjust_common_sizes);
|
||||
gold_assert(!adjust_common_sizes);
|
||||
&adjust_common_sizes,
|
||||
&adjust_dyn_def);
|
||||
gold_assert(!adjust_common_sizes && !adjust_dyn_def);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user