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