OSDN Git Service

* configure.ac: Adjust for loop syntax.
[pf3gnuchains/pf3gnuchains3x.git] / gold / reloc.h
1 // reloc.h -- relocate input files for gold   -*- C++ -*-
2
3 #ifndef GOLD_RELOC_H
4 #define GOLD_RELOC_H
5
6 #include <byteswap.h>
7
8 #include "workqueue.h"
9
10 namespace gold
11 {
12
13 class General_options;
14 class Relobj;
15 class Read_relocs_data;
16 class Stringpool;
17 class Symbol;
18 class Layout;
19
20 template<int size>
21 class Sized_symbol;
22
23 template<int sh_type, bool dynamic, int size, bool big_endian>
24 class Output_data_reloc;
25
26 // A class to read the relocations for an object file, and then queue
27 // up a task to see if they require any GOT/PLT/COPY relocations in
28 // the symbol table.
29
30 class Read_relocs : public Task
31 {
32  public:
33   // SYMTAB_LOCK is used to lock the symbol table.  BLOCKER should be
34   // unblocked when the Scan_relocs task completes.
35   Read_relocs(const General_options& options, Symbol_table* symtab,
36               Layout* layout, Relobj* object, Task_token* symtab_lock,
37               Task_token* blocker)
38     : options_(options), symtab_(symtab), layout_(layout), object_(object),
39       symtab_lock_(symtab_lock), blocker_(blocker)
40   { }
41
42   // The standard Task methods.
43
44   Is_runnable_type
45   is_runnable(Workqueue*);
46
47   Task_locker*
48   locks(Workqueue*);
49
50   void
51   run(Workqueue*);
52
53  private:
54   const General_options& options_;
55   Symbol_table* symtab_;
56   Layout* layout_;
57   Relobj* object_;
58   Task_token* symtab_lock_;
59   Task_token* blocker_;
60 };
61
62 // Scan the relocations for an object to see if they require any
63 // GOT/PLT/COPY relocations.
64
65 class Scan_relocs : public Task
66 {
67  public:
68   // SYMTAB_LOCK is used to lock the symbol table.  BLOCKER should be
69   // unblocked when the task completes.
70   Scan_relocs(const General_options& options, Symbol_table* symtab,
71               Layout* layout, Relobj* object, Read_relocs_data* rd,
72               Task_token* symtab_lock, Task_token* blocker)
73     : options_(options), symtab_(symtab), layout_(layout), object_(object),
74       rd_(rd), symtab_lock_(symtab_lock), blocker_(blocker)
75   { }
76
77   // The standard Task methods.
78
79   Is_runnable_type
80   is_runnable(Workqueue*);
81
82   Task_locker*
83   locks(Workqueue*);
84
85   void
86   run(Workqueue*);
87
88  private:
89   class Scan_relocs_locker;
90
91   const General_options& options_;
92   Symbol_table* symtab_;
93   Layout* layout_;
94   Relobj* object_;
95   Read_relocs_data* rd_;
96   Task_token* symtab_lock_;
97   Task_token* blocker_;
98 };
99
100 // A class to perform all the relocations for an object file.
101
102 class Relocate_task : public Task
103 {
104  public:
105   Relocate_task(const General_options& options, const Symbol_table* symtab,
106                 const Layout* layout, Relobj* object, Output_file* of,
107                 Task_token* final_blocker)
108     : options_(options), symtab_(symtab), layout_(layout), object_(object),
109       of_(of), final_blocker_(final_blocker)
110   { }
111
112   // The standard Task methods.
113
114   Is_runnable_type
115   is_runnable(Workqueue*);
116
117   Task_locker*
118   locks(Workqueue*);
119
120   void
121   run(Workqueue*);
122
123  private:
124   class Relocate_locker;
125
126   const General_options& options_;
127   const Symbol_table* symtab_;
128   const Layout* layout_;
129   Relobj* object_;
130   Output_file* of_;
131   Task_token* final_blocker_;
132 };
133
134 // Standard relocation routines which are used on many targets.  Here
135 // SIZE and BIG_ENDIAN refer to the target, not the relocation type.
136
137 template<int size, bool big_endian>
138 class Relocate_functions
139 {
140 private:
141   // Do a simple relocation with the addend in the section contents.
142   // VALSIZE is the size of the value.
143   template<int valsize>
144   static inline void
145   rel(unsigned char* view,
146       typename elfcpp::Swap<valsize, big_endian>::Valtype value)
147   {
148     typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
149     Valtype* wv = reinterpret_cast<Valtype*>(view);
150     Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
151     elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value);
152   }
153
154   // Do a simple PC relative relocation with the addend in the section
155   // contents.  VALSIZE is the size of the value.
156   template<int valsize>
157   static inline void
158   pcrel(unsigned char* view,
159         typename elfcpp::Swap<valsize, big_endian>::Valtype value,
160         typename elfcpp::Elf_types<size>::Elf_Addr address)
161   {
162     typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
163     Valtype* wv = reinterpret_cast<Valtype*>(view);
164     Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
165     elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address);
166   }
167
168   typedef Relocate_functions<size, big_endian> This;
169
170 public:
171   // Do a simple 8-bit REL relocation with the addend in the object
172   // file data.
173   static inline void
174   rel8(unsigned char* view, unsigned char value)
175   {
176     This::template rel<8>(view, value);
177   }
178
179   // Do a simple 8-bit PC relative relocation with the addend in the
180   // object file data.
181   static inline void
182   pcrel8(unsigned char* view, unsigned char value,
183          typename elfcpp::Elf_types<size>::Elf_Addr address)
184   {
185     This::template pcrel<8>(view, value, address);
186   }
187
188   // Do a simple 16-bit REL relocation with the addend in the object
189   // file data.
190   static inline void
191   rel16(unsigned char* view, elfcpp::Elf_Half value)
192   {
193     This::template rel<16>(view, value);
194   }
195
196   // Do a simple 32-bit PC relative REL relocation with the addend in
197   // the object file data.
198   static inline void
199   pcrel16(unsigned char* view, elfcpp::Elf_Word value,
200           typename elfcpp::Elf_types<size>::Elf_Addr address)
201   {
202     This::template pcrel<16>(view, value, address);
203   }
204
205   // Do a simple 32-bit REL relocation with the addend in the section
206   // contents.
207   static inline void
208   rel32(unsigned char* view, elfcpp::Elf_Word value)
209   {
210     This::template rel<32>(view, value);
211   }
212
213   // Do a simple 32-bit PC relative REL relocation with the addend in
214   // the section contents.
215   static inline void
216   pcrel32(unsigned char* view, elfcpp::Elf_Word value,
217           typename elfcpp::Elf_types<size>::Elf_Addr address)
218   {
219     This::template pcrel<32>(view, value, address);
220   }
221
222   // Do a simple 64-bit REL relocation with the addend in the section
223   // contents.
224   static inline void
225   rel64(unsigned char* view, elfcpp::Elf_Xword value)
226   {
227     This::template rel<64>(view, value);
228   }
229
230   // Do a simple 64-bit PC relative REL relocation with the addend in
231   // the section contents.
232   static inline void
233   pcrel64(unsigned char* view, elfcpp::Elf_Xword value,
234           typename elfcpp::Elf_types<size>::Elf_Addr address)
235   {
236     This::template pcrel<64>(view, value, address);
237   }
238 };
239
240 // We try to avoid COPY relocations when possible.  A COPY relocation
241 // may be required when an executable refers to a variable defined in
242 // a shared library.  COPY relocations are problematic because they
243 // tie the executable to the exact size of the variable in the shared
244 // library.  We can avoid them if all the references to the variable
245 // are in a writeable section.  In that case we can simply use dynamic
246 // relocations.  However, when scanning relocs, we don't know when we
247 // see the relocation whether we will be forced to use a COPY
248 // relocation or not.  So we have to save the relocation during the
249 // reloc scanning, and then emit it as a dynamic relocation if
250 // necessary.  This class implements that.  It is used by the target
251 // specific code.
252
253 template<int size, bool big_endian>
254 class Copy_relocs
255 {
256  public:
257   Copy_relocs()
258     : entries_()
259   { }
260
261   // Return whether we need a COPY reloc for a reloc against GSYM,
262   // which is being applied to section SHNDX in OBJECT.
263   static bool
264   need_copy_reloc(const General_options*, Relobj* object, unsigned int shndx,
265                   Sized_symbol<size>* gsym);
266
267   // Save a Rel against SYM for possible emission later.  SHNDX is the
268   // index of the section to which the reloc is being applied.
269   void
270   save(Symbol* sym, Relobj*, unsigned int shndx,
271        const elfcpp::Rel<size, big_endian>&);
272
273   // Save a Rela against SYM for possible emission later.
274   void
275   save(Symbol* sym, Relobj*, unsigned int shndx,
276        const elfcpp::Rela<size, big_endian>&);
277
278   // Return whether there are any relocs to emit.  This also discards
279   // entries which need not be emitted.
280   bool
281   any_to_emit();
282
283   // Emit relocs for each symbol which did not get a COPY reloc (i.e.,
284   // is still defined in the dynamic object).
285   template<int sh_type>
286   void
287   emit(Output_data_reloc<sh_type, true, size, big_endian>*);
288
289  private:
290   typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
291   typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
292
293   // This POD class holds the entries we are saving.
294   class Copy_reloc_entry
295   {
296    public:
297     Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
298                      Relobj* relobj, unsigned int shndx,
299                      Address address, Addend addend)
300       : sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
301         shndx_(shndx), address_(address), addend_(addend)
302     { }
303
304     // Return whether we should emit this reloc.  If we should not
305     // emit, we clear it.
306     bool
307     should_emit();
308
309     // Emit this reloc.
310
311     void
312     emit(Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>*);
313
314     void
315     emit(Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>*);
316
317    private:
318     Symbol* sym_;
319     unsigned int reloc_type_;
320     Relobj* relobj_;
321     unsigned int shndx_;
322     Address address_;
323     Addend addend_;
324   };
325
326   // A list of relocs to be saved.
327   typedef std::vector<Copy_reloc_entry> Copy_reloc_entries;
328
329   // The list of relocs we are saving.
330   Copy_reloc_entries entries_;
331 };
332
333 } // End namespace gold.
334
335 #endif // !defined(GOLD_RELOC_H)