From 26a4e9cbc48e0bb4ae5e1af8f1a432211b4b3867 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 5 Nov 2012 03:29:58 +0000 Subject: * 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. --- gold/ChangeLog | 10 ++++++ gold/powerpc.cc | 108 ++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 75 insertions(+), 43 deletions(-) (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index 91f97eb4..6c5a80e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,13 @@ +2012-11-05 Alan Modra + + * 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 * i386.cc (Target_i386::relocate_relocs): Remove extraneous typename diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 3b36b41..fd79312 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -58,7 +58,6 @@ class Powerpc_relobj : public Sized_relobj_file { public: typedef typename elfcpp::Elf_types::Elf_Addr Address; - typedef typename elfcpp::Elf_types::Elf_Off Offset; typedef Unordered_set Section_refs; typedef Unordered_map 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 return this->got_; } + // Get the GOT section, creating it if necessary. + Output_data_got_powerpc* + got_section(Symbol_table*, Layout*); + Object* do_make_elf_object(const std::string&, Input_file*, off_t, const elfcpp::Ehdr&); @@ -694,10 +705,6 @@ class Target_powerpc : public Sized_target return tls::TLSOPT_TO_LE; } - // Get the GOT section, creating it if necessary. - Output_data_got_powerpc* - got_section(Symbol_table*, Layout*); - // Create glink. void make_glink_section(Layout*); @@ -1374,6 +1381,57 @@ Powerpc_relobj::do_read_relocs(Read_relocs_data* rd) } } +// Set up some symbols, then perform Sized_relobj_file method. + +template +void +Powerpc_relobj::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* target = + static_cast*>( + parameters->sized_target()); + Output_data_got_powerpc* 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::do_scan_relocs(symtab, layout, rd); +} + // Set up PowerPC target specific relobj. template @@ -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::Elf_Off + Valtype got_base_offset(const Powerpc_relobj* object) const { if (size == 32) @@ -4038,42 +4096,6 @@ Target_powerpc::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( symtab, layout, -- cgit v1.1