xref: /dflybsd-src/contrib/binutils-2.27/gold/copy-relocs.h (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
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