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