aboutsummaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc40
1 files changed, 37 insertions, 3 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index daf9daf..292a262 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -489,7 +489,7 @@ Symbol_table::Symbol_table(unsigned int count,
: saw_undefined_(0), offset_(0), table_(count), namepool_(),
forwarders_(), commons_(), tls_commons_(), small_commons_(),
large_commons_(), forced_locals_(), warnings_(),
- version_script_(version_script), gc_(NULL)
+ version_script_(version_script), gc_(NULL), icf_(NULL)
{
namepool_.reserve(count);
}
@@ -516,6 +516,13 @@ Symbol_table::Symbol_table_eq::operator()(const Symbol_table_key& k1,
return k1.first == k2.first && k1.second == k2.second;
}
+bool
+Symbol_table::is_section_folded(Object* obj, unsigned int shndx) const
+{
+ return (parameters->options().icf()
+ && this->icf_->is_section_folded(obj, shndx));
+}
+
// For symbols that have been listed with -u option, add them to the
// work list to avoid gc'ing them.
@@ -2417,8 +2424,22 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
{
Relobj* relobj = static_cast<Relobj*>(symobj);
Output_section* os = relobj->output_section(shndx);
+ uint64_t secoff64 = relobj->output_section_offset(shndx);
- if (os == NULL)
+ if (this->is_section_folded(relobj, shndx))
+ {
+ gold_assert(os == NULL);
+ // Get the os of the section it is folded onto.
+ Section_id folded = this->icf_->get_folded_section(relobj,
+ shndx);
+ gold_assert(folded.first != NULL);
+ Relobj* folded_obj = reinterpret_cast<Relobj*>(folded.first);
+ os = folded_obj->output_section(folded.second);
+ gold_assert(os != NULL);
+ secoff64 = folded_obj->output_section_offset(folded.second);
+ }
+
+ if (os == NULL)
{
sym->set_symtab_index(-1U);
bool static_or_reloc = (parameters->doing_static_link() ||
@@ -2428,10 +2449,10 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
return false;
}
- uint64_t secoff64 = relobj->output_section_offset(shndx);
if (secoff64 == -1ULL)
{
// The section needs special handling (e.g., a merge section).
+
value = os->output_address(relobj, shndx, sym->value());
}
else
@@ -2642,6 +2663,19 @@ Symbol_table::sized_write_globals(const Stringpool* sympool,
{
Relobj* relobj = static_cast<Relobj*>(symobj);
Output_section* os = relobj->output_section(in_shndx);
+ if (this->is_section_folded(relobj, in_shndx))
+ {
+ // This global symbol must be written out even though
+ // it is folded.
+ // Get the os of the section it is folded onto.
+ Section_id folded =
+ this->icf_->get_folded_section(relobj, in_shndx);
+ gold_assert(folded.first !=NULL);
+ Relobj* folded_obj =
+ reinterpret_cast<Relobj*>(folded.first);
+ os = folded_obj->output_section(folded.second);
+ gold_assert(os != NULL);
+ }
gold_assert(os != NULL);
shndx = os->out_shndx();