aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog6
-rw-r--r--gold/powerpc.cc37
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: