From c6de8ed4563e23ce1d0ee2a10a6a1ff882fa90ee Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 12 Oct 2012 09:44:11 +0000 Subject: * powerpc.cc (Powerpc_relobj::add_gc_mark, process_gc_mark): New. (struct Opd_ent): Make "discard" a bit field. Add "gc_mark". (Target_powerpc::do_gc_mark_symbol): Delay marking function code section if scan_opd_relocs not yet called. (Target_powerpc::gc_process_relocs): Call process_gc_mark. --- gold/ChangeLog | 8 ++++++++ gold/powerpc.cc | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index cbedb79..5895962 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,13 @@ 2012-10-12 Alan Modra + * powerpc.cc (Powerpc_relobj::add_gc_mark, process_gc_mark): New. + (struct Opd_ent): Make "discard" a bit field. Add "gc_mark". + (Target_powerpc::do_gc_mark_symbol): Delay marking function code + section if scan_opd_relocs not yet called. + (Target_powerpc::gc_process_relocs): Call process_gc_mark. + +2012-10-12 Alan Modra + * powerpc.cc (Output_data_plt_powerpc::add_entry, add_ifunc_entry, add_local_ifunc_entry): Revert last change. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Likewise. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index fc9264e..e346ac5 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -154,6 +154,28 @@ public: this->access_from_map_[dst_off].insert(src_id); } + // Add a reference to the code section specified by the .opd entry + // at DST_OFF + void + add_gc_mark(typename elfcpp::Elf_types::Elf_Addr dst_off) + { + size_t ndx = this->opd_ent_ndx(dst_off); + if (ndx >= this->opd_ent_.size()) + this->opd_ent_.resize(ndx + 1); + this->opd_ent_[ndx].gc_mark = true; + } + + void + process_gc_mark(Symbol_table* symtab) + { + for (size_t i = 0; i < this->opd_ent_.size(); i++) + if (this->opd_ent_[i].gc_mark) + { + unsigned int shndx = this->opd_ent_[i].shndx; + symtab->gc()->worklist().push(Section_id(this, shndx)); + } + } + bool opd_valid() const { return this->opd_valid_; } @@ -200,7 +222,8 @@ private: struct Opd_ent { unsigned int shndx; - bool discard; + bool discard : 1; + bool gc_mark : 1; Offset off; }; @@ -3499,6 +3522,7 @@ Target_powerpc::gc_process_relocs( p->second.clear(); } ppc_object->access_from_map()->clear(); + ppc_object->process_gc_mark(symtab); // Don't look at .opd relocs as .opd will reference everything. return; } @@ -3571,8 +3595,13 @@ Target_powerpc::do_gc_mark_symbol( { Sized_symbol* gsym = symtab->get_sized_symbol(sym); Address dst_off = gsym->value(); - unsigned int dst_indx = ppc_object->get_opd_ent(dst_off); - symtab->gc()->worklist().push(Section_id(ppc_object, dst_indx)); + if (ppc_object->opd_valid()) + { + unsigned int dst_indx = ppc_object->get_opd_ent(dst_off); + symtab->gc()->worklist().push(Section_id(ppc_object, dst_indx)); + } + else + ppc_object->add_gc_mark(dst_off); } } } -- cgit v1.1