1*a9fa9459Szrj // copy-relocs.h -- handle COPY relocations for gold -*- C++ -*- 2*a9fa9459Szrj 3*a9fa9459Szrj // Copyright (C) 2006-2016 Free Software Foundation, Inc. 4*a9fa9459Szrj // Written by Ian Lance Taylor <iant@google.com>. 5*a9fa9459Szrj 6*a9fa9459Szrj // This file is part of gold. 7*a9fa9459Szrj 8*a9fa9459Szrj // This program is free software; you can redistribute it and/or modify 9*a9fa9459Szrj // it under the terms of the GNU General Public License as published by 10*a9fa9459Szrj // the Free Software Foundation; either version 3 of the License, or 11*a9fa9459Szrj // (at your option) any later version. 12*a9fa9459Szrj 13*a9fa9459Szrj // This program is distributed in the hope that it will be useful, 14*a9fa9459Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 15*a9fa9459Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*a9fa9459Szrj // GNU General Public License for more details. 17*a9fa9459Szrj 18*a9fa9459Szrj // You should have received a copy of the GNU General Public License 19*a9fa9459Szrj // along with this program; if not, write to the Free Software 20*a9fa9459Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21*a9fa9459Szrj // MA 02110-1301, USA. 22*a9fa9459Szrj 23*a9fa9459Szrj #ifndef GOLD_COPY_RELOCS_H 24*a9fa9459Szrj #define GOLD_COPY_RELOCS_H 25*a9fa9459Szrj 26*a9fa9459Szrj #include "elfcpp.h" 27*a9fa9459Szrj #include "reloc-types.h" 28*a9fa9459Szrj #include "output.h" 29*a9fa9459Szrj 30*a9fa9459Szrj namespace gold 31*a9fa9459Szrj { 32*a9fa9459Szrj 33*a9fa9459Szrj // This class is used to manage COPY relocations. We try to avoid 34*a9fa9459Szrj // them when possible. A COPY relocation may be required when an 35*a9fa9459Szrj // executable refers to a variable defined in a shared library. COPY 36*a9fa9459Szrj // relocations are problematic because they tie the executable to the 37*a9fa9459Szrj // exact size of the variable in the shared library. We can avoid 38*a9fa9459Szrj // them if all the references to the variable are in a writeable 39*a9fa9459Szrj // section. In that case we can simply use dynamic relocations. 40*a9fa9459Szrj // However, when scanning relocs, we don't know when we see the 41*a9fa9459Szrj // relocation whether we will be forced to use a COPY relocation or 42*a9fa9459Szrj // not. So we have to save the relocation during the reloc scanning, 43*a9fa9459Szrj // and then emit it as a dynamic relocation if necessary. This class 44*a9fa9459Szrj // implements that. It is used by the target specific code. 45*a9fa9459Szrj 46*a9fa9459Szrj // The template parameter SH_TYPE is the type of the reloc section to 47*a9fa9459Szrj // be used for COPY relocs: elfcpp::SHT_REL or elfcpp::SHT_RELA. 48*a9fa9459Szrj 49*a9fa9459Szrj template<int sh_type, int size, bool big_endian> 50*a9fa9459Szrj class Copy_relocs 51*a9fa9459Szrj { 52*a9fa9459Szrj private: 53*a9fa9459Szrj typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reloc; 54*a9fa9459Szrj 55*a9fa9459Szrj public: Copy_relocs(unsigned int copy_reloc_type)56*a9fa9459Szrj Copy_relocs(unsigned int copy_reloc_type) 57*a9fa9459Szrj : entries_(), copy_reloc_type_(copy_reloc_type), dynbss_(NULL) 58*a9fa9459Szrj { } 59*a9fa9459Szrj 60*a9fa9459Szrj // This is called while scanning relocs if we see a relocation 61*a9fa9459Szrj // against a symbol which may force us to generate a COPY reloc. 62*a9fa9459Szrj // SYM is the symbol. OBJECT is the object whose relocs we are 63*a9fa9459Szrj // scanning. The relocation is being applied to section SHNDX in 64*a9fa9459Szrj // OBJECT. OUTPUT_SECTION is the output section where section SHNDX 65*a9fa9459Szrj // will wind up. REL is the reloc itself. The Output_data_reloc 66*a9fa9459Szrj // section is where the dynamic relocs are put. 67*a9fa9459Szrj void 68*a9fa9459Szrj copy_reloc(Symbol_table*, 69*a9fa9459Szrj Layout*, 70*a9fa9459Szrj Sized_symbol<size>* sym, 71*a9fa9459Szrj Sized_relobj_file<size, big_endian>* object, 72*a9fa9459Szrj unsigned int shndx, 73*a9fa9459Szrj Output_section* output_section, 74*a9fa9459Szrj unsigned int r_type, 75*a9fa9459Szrj typename elfcpp::Elf_types<size>::Elf_Addr r_offset, 76*a9fa9459Szrj typename elfcpp::Elf_types<size>::Elf_Swxword r_addend, 77*a9fa9459Szrj Output_data_reloc<sh_type, true, size, big_endian>*); 78*a9fa9459Szrj 79*a9fa9459Szrj // Return whether there are any saved relocations. 80*a9fa9459Szrj bool any_saved_relocs()81*a9fa9459Szrj any_saved_relocs() const 82*a9fa9459Szrj { return !this->entries_.empty(); } 83*a9fa9459Szrj 84*a9fa9459Szrj // Emit any saved relocations which turn out to be needed. This is 85*a9fa9459Szrj // called after all the relocs have been scanned. 86*a9fa9459Szrj void 87*a9fa9459Szrj emit(Output_data_reloc<sh_type, true, size, big_endian>*); 88*a9fa9459Szrj 89*a9fa9459Szrj // Emit a COPY reloc. 90*a9fa9459Szrj void 91*a9fa9459Szrj emit_copy_reloc(Symbol_table*, Sized_symbol<size>*, 92*a9fa9459Szrj Output_data*, off_t, 93*a9fa9459Szrj Output_data_reloc<sh_type, true, size, big_endian>*); 94*a9fa9459Szrj 95*a9fa9459Szrj protected: 96*a9fa9459Szrj typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; 97*a9fa9459Szrj typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend; 98*a9fa9459Szrj 99*a9fa9459Szrj // This POD class holds the relocations we are saving. We will emit 100*a9fa9459Szrj // these relocations if it turns out that the symbol does not 101*a9fa9459Szrj // require a COPY relocation. 102*a9fa9459Szrj struct Copy_reloc_entry 103*a9fa9459Szrj { Copy_reloc_entryCopy_reloc_entry104*a9fa9459Szrj Copy_reloc_entry(Symbol* sym, unsigned int reloc_type, 105*a9fa9459Szrj Sized_relobj_file<size, big_endian>* relobj, 106*a9fa9459Szrj unsigned int shndx, 107*a9fa9459Szrj Output_section* output_section, 108*a9fa9459Szrj Address address, Addend addend) 109*a9fa9459Szrj : sym_(sym), reloc_type_(reloc_type), relobj_(relobj), 110*a9fa9459Szrj shndx_(shndx), output_section_(output_section), 111*a9fa9459Szrj address_(address), addend_(addend) 112*a9fa9459Szrj { } 113*a9fa9459Szrj 114*a9fa9459Szrj Symbol* sym_; 115*a9fa9459Szrj unsigned int reloc_type_; 116*a9fa9459Szrj Sized_relobj_file<size, big_endian>* relobj_; 117*a9fa9459Szrj unsigned int shndx_; 118*a9fa9459Szrj Output_section* output_section_; 119*a9fa9459Szrj Address address_; 120*a9fa9459Szrj Addend addend_; 121*a9fa9459Szrj }; 122*a9fa9459Szrj 123*a9fa9459Szrj // Make a new COPY reloc and emit it. 124*a9fa9459Szrj void 125*a9fa9459Szrj make_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*, 126*a9fa9459Szrj Sized_relobj_file<size, big_endian>* object, 127*a9fa9459Szrj Output_data_reloc<sh_type, true, size, big_endian>*); 128*a9fa9459Szrj 129*a9fa9459Szrj // A list of relocs to be saved. 130*a9fa9459Szrj typedef std::vector<Copy_reloc_entry> Copy_reloc_entries; 131*a9fa9459Szrj 132*a9fa9459Szrj // The list of relocs we are saving. 133*a9fa9459Szrj Copy_reloc_entries entries_; 134*a9fa9459Szrj 135*a9fa9459Szrj private: 136*a9fa9459Szrj // Return whether we need a COPY reloc. 137*a9fa9459Szrj bool 138*a9fa9459Szrj need_copy_reloc(Sized_symbol<size>* gsym, 139*a9fa9459Szrj Sized_relobj_file<size, big_endian>* object, 140*a9fa9459Szrj unsigned int shndx) const; 141*a9fa9459Szrj 142*a9fa9459Szrj // Save a reloc against SYM for possible emission later. 143*a9fa9459Szrj void 144*a9fa9459Szrj save(Symbol*, 145*a9fa9459Szrj Sized_relobj_file<size, big_endian>*, 146*a9fa9459Szrj unsigned int shndx, 147*a9fa9459Szrj Output_section*, 148*a9fa9459Szrj unsigned int r_type, 149*a9fa9459Szrj typename elfcpp::Elf_types<size>::Elf_Addr r_offset, 150*a9fa9459Szrj typename elfcpp::Elf_types<size>::Elf_Swxword r_addend); 151*a9fa9459Szrj 152*a9fa9459Szrj // The target specific relocation type of the COPY relocation. 153*a9fa9459Szrj const unsigned int copy_reloc_type_; 154*a9fa9459Szrj // The dynamic BSS data which goes into the .bss section. This is 155*a9fa9459Szrj // where variables which require COPY relocations are placed. 156*a9fa9459Szrj Output_data_space* dynbss_; 157*a9fa9459Szrj }; 158*a9fa9459Szrj 159*a9fa9459Szrj } // End namespace gold. 160*a9fa9459Szrj 161*a9fa9459Szrj #endif // !defined(GOLD_COPY_RELOCS_H) 162