diff options
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 6 | ||||
-rw-r--r-- | gold/powerpc.cc | 37 |
2 files changed, 29 insertions, 14 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 8b44555..ae44916 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,11 @@ 2012-11-30 Alan Modra <amodra@gmail.com> + * powerpc.cc (Target_powerpc::make_plt_section): Add symtab + param. Call got_section() to make .got. Update all callers + and their callers and so on. + +2012-11-30 Alan Modra <amodra@gmail.com> + * powerpc.cc (Powerpc_relobj::do_scan_relocs): Make STB_LOCAL _GLOBAL_OFFSET_TABLE_ rather than STB_WEAK. (Output_data_got_powerpc::make_header): Update _GLOBAL_OFFSET_TABLE_ diff --git a/gold/powerpc.cc b/gold/powerpc.cc index e4aef13..0c5288f 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -711,20 +711,20 @@ class Target_powerpc : public Sized_target<size, big_endian> // Create the PLT section. void - make_plt_section(Layout*); + make_plt_section(Symbol_table*, Layout*); void - make_iplt_section(Layout*); + make_iplt_section(Symbol_table*, Layout*); // Create a PLT entry for a global symbol. void - make_plt_entry(Layout*, Symbol*, + make_plt_entry(Symbol_table*, Layout*, Symbol*, const elfcpp::Rela<size, big_endian>&, const Sized_relobj_file<size, big_endian>* object); // Create a PLT entry for a local IFUNC symbol. void - make_local_ifunc_plt_entry(Layout*, + make_local_ifunc_plt_entry(Symbol_table*, Layout*, const elfcpp::Rela<size, big_endian>&, Sized_relobj_file<size, big_endian>*); @@ -1885,10 +1885,14 @@ Output_data_plt_powerpc<size, big_endian>::do_write(Output_file* of) template<int size, bool big_endian> void -Target_powerpc<size, big_endian>::make_plt_section(Layout* layout) +Target_powerpc<size, big_endian>::make_plt_section(Symbol_table* symtab, + Layout* layout) { if (this->plt_ == NULL) { + if (this->got_ == NULL) + this->got_section(symtab, layout); + if (this->glink_ == NULL) make_glink_section(layout); @@ -1922,11 +1926,12 @@ Target_powerpc<size, big_endian>::make_plt_section(Layout* layout) template<int size, bool big_endian> void -Target_powerpc<size, big_endian>::make_iplt_section(Layout* layout) +Target_powerpc<size, big_endian>::make_iplt_section(Symbol_table* symtab, + Layout* layout) { if (this->iplt_ == NULL) { - this->make_plt_section(layout); + this->make_plt_section(symtab, layout); Reloc_section* iplt_rel = new Reloc_section(false); this->rela_dyn_->output_section()->add_output_section_data(iplt_rel); @@ -2872,6 +2877,7 @@ Target_powerpc<size, big_endian>::make_glink_section(Layout* layout) template<int size, bool big_endian> void Target_powerpc<size, big_endian>::make_plt_entry( + Symbol_table* symtab, Layout* layout, Symbol* gsym, const elfcpp::Rela<size, big_endian>& reloc, @@ -2881,13 +2887,13 @@ Target_powerpc<size, big_endian>::make_plt_entry( && gsym->can_use_relative_reloc(false)) { if (this->iplt_ == NULL) - this->make_iplt_section(layout); + this->make_iplt_section(symtab, layout); this->iplt_->add_ifunc_entry(gsym); } else { if (this->plt_ == NULL) - this->make_plt_section(layout); + this->make_plt_section(symtab, layout); this->plt_->add_entry(gsym); } this->glink_->add_entry(object, gsym, reloc); @@ -2898,12 +2904,13 @@ Target_powerpc<size, big_endian>::make_plt_entry( template<int size, bool big_endian> void Target_powerpc<size, big_endian>::make_local_ifunc_plt_entry( + Symbol_table* symtab, Layout* layout, const elfcpp::Rela<size, big_endian>& reloc, Sized_relobj_file<size, big_endian>* relobj) { if (this->iplt_ == NULL) - this->make_iplt_section(layout); + this->make_iplt_section(symtab, layout); unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info()); this->iplt_->add_local_ifunc_entry(relobj, r_sym); this->glink_->add_entry(relobj, r_sym, reloc); @@ -3256,7 +3263,9 @@ Target_powerpc<size, big_endian>::Scan::local( // A local STT_GNU_IFUNC symbol may require a PLT entry. bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC; if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type)) - target->make_local_ifunc_plt_entry(layout, reloc, object); + { + target->make_local_ifunc_plt_entry(symtab, layout, reloc, object); + } switch (r_type) { @@ -3566,7 +3575,7 @@ Target_powerpc<size, big_endian>::Scan::global( // A STT_GNU_IFUNC symbol may require a PLT entry. if (gsym->type() == elfcpp::STT_GNU_IFUNC && this->reloc_needs_plt_for_ifunc(object, r_type)) - target->make_plt_entry(layout, gsym, reloc, object); + target->make_plt_entry(symtab, layout, gsym, reloc, object); switch (r_type) { @@ -3636,7 +3645,7 @@ Target_powerpc<size, big_endian>::Scan::global( // Make a PLT entry if necessary. if (gsym->needs_plt_entry()) { - target->make_plt_entry(layout, gsym, reloc, 0); + target->make_plt_entry(symtab, layout, gsym, reloc, 0); // Since this is not a PC-relative relocation, we may be // taking the address of a function. In that case we need to // set the entry in the dynamic symbol table to the address of @@ -3692,7 +3701,7 @@ Target_powerpc<size, big_endian>::Scan::global( && (gsym->is_undefined() || gsym->is_from_dynobj() || gsym->is_preemptible()))) - target->make_plt_entry(layout, gsym, reloc, object); + target->make_plt_entry(symtab, layout, gsym, reloc, object); // Fall thru case elfcpp::R_PPC64_REL64: |