aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2012-11-05 03:29:58 +0000
committerAlan Modra <amodra@bigpond.net.au>2012-11-05 03:29:58 +0000
commit973d3b5c86b53e0940e540966b982409b26b4365 (patch)
tree78a0bb84b8b2b166283deb6682e3c64f8ec726f9
parent7067772c2c7b9ac6885fc9b759980425b7dc33f9 (diff)
downloadbinutils-973d3b5c86b53e0940e540966b982409b26b4365.tar.gz
* powerpc.cc (Powerpc_relobj): Delete "Offset" typedef.
(struct Opd_ent): Use "Address" rather than "Offset". (Output_data_got_powerpc::got_base_offset): Return Valtype. (Target_powerpc::got_section): Make public. (Target_powerpc::scan_relocs): Move code setting symbols.. (Powerpc_relobj::do_scan_relocs): ..to here, new function. Create _SDA_BASE_ only when referenced.
-rw-r--r--gold/ChangeLog10
-rw-r--r--gold/powerpc.cc108
2 files changed, 75 insertions, 43 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 91f97eb44..6c5a80e5a 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,13 @@
+2012-11-05 Alan Modra <amodra@gmail.com>
+
+ * powerpc.cc (Powerpc_relobj): Delete "Offset" typedef.
+ (struct Opd_ent): Use "Address" rather than "Offset".
+ (Output_data_got_powerpc::got_base_offset): Return Valtype.
+ (Target_powerpc::got_section): Make public.
+ (Target_powerpc::scan_relocs): Move code setting symbols..
+ (Powerpc_relobj::do_scan_relocs): ..to here, new function.
+ Create _SDA_BASE_ only when referenced.
+
2012-11-02 Roland McGrath <mcgrathr@google.com>
* i386.cc (Target_i386::relocate_relocs): Remove extraneous typename
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 3b36b417e..fd7931227 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -58,7 +58,6 @@ class Powerpc_relobj : public Sized_relobj_file<size, big_endian>
{
public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
- typedef typename elfcpp::Elf_types<size>::Elf_Off Offset;
typedef Unordered_set<Section_id, Section_id_hash> Section_refs;
typedef Unordered_map<Address, Section_refs> Access_from;
@@ -190,9 +189,17 @@ public:
const unsigned char* prelocs,
const unsigned char* plocal_syms);
+ // Perform the Sized_relobj_file method, then set up opd info from
+ // .opd relocs.
void
do_read_relocs(Read_relocs_data*);
+ // Set up some symbols, then perform Sized_relobj_file method.
+ // Occurs after garbage collection, which is why opd info can't be
+ // set up here.
+ void
+ do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*);
+
bool
do_find_special_sections(Read_symbols_data* sd);
@@ -224,7 +231,7 @@ private:
unsigned int shndx;
bool discard : 1;
bool gc_mark : 1;
- Offset off;
+ Address off;
};
// Return index into opd_ent_ array for .opd entry at OFF.
@@ -449,6 +456,10 @@ class Target_powerpc : public Sized_target<size, big_endian>
return this->got_;
}
+ // Get the GOT section, creating it if necessary.
+ Output_data_got_powerpc<size, big_endian>*
+ got_section(Symbol_table*, Layout*);
+
Object*
do_make_elf_object(const std::string&, Input_file*, off_t,
const elfcpp::Ehdr<size, big_endian>&);
@@ -694,10 +705,6 @@ class Target_powerpc : public Sized_target<size, big_endian>
return tls::TLSOPT_TO_LE;
}
- // Get the GOT section, creating it if necessary.
- Output_data_got_powerpc<size, big_endian>*
- got_section(Symbol_table*, Layout*);
-
// Create glink.
void
make_glink_section(Layout*);
@@ -1374,6 +1381,57 @@ Powerpc_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
}
}
+// Set up some symbols, then perform Sized_relobj_file method.
+
+template<int size, bool big_endian>
+void
+Powerpc_relobj<size, big_endian>::do_scan_relocs(Symbol_table* symtab,
+ Layout* layout,
+ Read_relocs_data* rd)
+{
+ if (size == 32)
+ {
+ // Define a weak hidden _GLOBAL_OFFSET_TABLE_ to ensure it isn't
+ // seen as undefined when scanning relocs (and thus requires
+ // non-relative dynamic relocs). The proper value will be
+ // updated later.
+ Symbol *gotsym = symtab->lookup("_GLOBAL_OFFSET_TABLE_", NULL);
+ if (gotsym != NULL && gotsym->is_undefined())
+ {
+ Target_powerpc<size, big_endian>* target =
+ static_cast<Target_powerpc<size, big_endian>*>(
+ parameters->sized_target<size, big_endian>());
+ Output_data_got_powerpc<size, big_endian>* got
+ = target->got_section(symtab, layout);
+ symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
+ Symbol_table::PREDEFINED,
+ got, 0, 0,
+ elfcpp::STT_OBJECT,
+ elfcpp::STB_WEAK,
+ elfcpp::STV_HIDDEN, 0,
+ false, false);
+ }
+
+ // Define _SDA_BASE_ at the start of the .sdata section + 32768.
+ Symbol *sdasym = symtab->lookup("_SDA_BASE_", NULL);
+ if (sdasym != NULL && sdasym->is_undefined())
+ {
+ Output_data_space* sdata = new Output_data_space(4, "** sdata");
+ Output_section* os
+ = layout->add_output_section_data(".sdata", 0,
+ elfcpp::SHF_ALLOC
+ | elfcpp::SHF_WRITE,
+ sdata, ORDER_SMALL_DATA, false);
+ symtab->define_in_output_data("_SDA_BASE_", NULL,
+ Symbol_table::PREDEFINED,
+ os, 32768, 0, elfcpp::STT_OBJECT,
+ elfcpp::STB_LOCAL, elfcpp::STV_HIDDEN,
+ 0, false, false);
+ }
+ }
+ Sized_relobj_file<size, big_endian>::do_scan_relocs(symtab, layout, rd);
+}
+
// Set up PowerPC target specific relobj.
template<int size, bool big_endian>
@@ -1459,7 +1517,7 @@ public:
// Offset of base used to access the GOT/TOC.
// The got/toc pointer reg will be set to this value.
- typename elfcpp::Elf_types<size>::Elf_Off
+ Valtype
got_base_offset(const Powerpc_relobj<size, big_endian>* object) const
{
if (size == 32)
@@ -4038,42 +4096,6 @@ Target_powerpc<size, big_endian>::scan_relocs(
return;
}
- if (size == 32)
- {
- // Define a weak hidden _GLOBAL_OFFSET_TABLE_ to ensure it isn't
- // seen as undefined when scanning relocs (and thus requires
- // non-relative dynamic relocs). The proper value will be
- // updated later.
- Symbol *gotsym = symtab->lookup("_GLOBAL_OFFSET_TABLE_", NULL);
- if (gotsym != NULL && gotsym->is_undefined())
- symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
- Symbol_table::PREDEFINED,
- this->got_section(symtab, layout), 0, 0,
- elfcpp::STT_OBJECT,
- elfcpp::STB_WEAK,
- elfcpp::STV_HIDDEN, 0,
- false, false);
-
- static Output_data_space* sdata;
-
- // Define _SDA_BASE_ at the start of the .sdata section.
- if (sdata == NULL)
- {
- // layout->find_output_section(".sdata") == NULL
- sdata = new Output_data_space(4, "** sdata");
- Output_section* os
- = layout->add_output_section_data(".sdata", 0,
- elfcpp::SHF_ALLOC
- | elfcpp::SHF_WRITE,
- sdata, ORDER_SMALL_DATA, false);
- symtab->define_in_output_data("_SDA_BASE_", NULL,
- Symbol_table::PREDEFINED,
- os, 32768, 0, elfcpp::STT_OBJECT,
- elfcpp::STB_LOCAL, elfcpp::STV_HIDDEN,
- 0, false, false);
- }
- }
-
gold::scan_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>(
symtab,
layout,