2009-06-23 Sami Wagiaalla <swagiaal@redhat.com>
[deliverable/binutils-gdb.git] / gold / reloc.h
CommitLineData
61ba1cf9
ILT
1// reloc.h -- relocate input files for gold -*- C++ -*-
2
6d03d481 3// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
6cb15b7f
ILT
4// Written by Ian Lance Taylor <iant@google.com>.
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
61ba1cf9
ILT
23#ifndef GOLD_RELOC_H
24#define GOLD_RELOC_H
25
17a1d0a9 26#include <vector>
92e059d8
ILT
27#include <byteswap.h>
28
4c50553d 29#include "elfcpp.h"
61ba1cf9
ILT
30#include "workqueue.h"
31
32namespace gold
33{
34
a3ad94ed 35class General_options;
b696e6d4 36class Object;
f6ce93d6 37class Relobj;
92e059d8 38class Read_relocs_data;
a3ad94ed 39class Symbol;
ead1e424 40class Layout;
6a74a719 41class Output_data;
4f4c5f80 42class Output_section;
92e059d8 43
5a6f7e2d
ILT
44template<int size>
45class Sized_symbol;
46
b8e6aad9
ILT
47template<int size, bool big_endian>
48class Sized_relobj;
49
50template<int size>
51class Symbol_value;
52
5a6f7e2d
ILT
53template<int sh_type, bool dynamic, int size, bool big_endian>
54class Output_data_reloc;
55
92e059d8
ILT
56// A class to read the relocations for an object file, and then queue
57// up a task to see if they require any GOT/PLT/COPY relocations in
58// the symbol table.
59
60class Read_relocs : public Task
61{
62 public:
63 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
64 // unblocked when the Scan_relocs task completes.
65 Read_relocs(const General_options& options, Symbol_table* symtab,
f6ce93d6 66 Layout* layout, Relobj* object, Task_token* symtab_lock,
92e059d8 67 Task_token* blocker)
ead1e424 68 : options_(options), symtab_(symtab), layout_(layout), object_(object),
92e059d8
ILT
69 symtab_lock_(symtab_lock), blocker_(blocker)
70 { }
71
72 // The standard Task methods.
73
17a1d0a9
ILT
74 Task_token*
75 is_runnable();
92e059d8 76
17a1d0a9
ILT
77 void
78 locks(Task_locker*);
92e059d8
ILT
79
80 void
81 run(Workqueue*);
82
c7912668
ILT
83 std::string
84 get_name() const;
85
92e059d8
ILT
86 private:
87 const General_options& options_;
88 Symbol_table* symtab_;
ead1e424 89 Layout* layout_;
f6ce93d6 90 Relobj* object_;
92e059d8
ILT
91 Task_token* symtab_lock_;
92 Task_token* blocker_;
93};
94
6d03d481
ST
95// Process the relocs to figure out which sections are garbage.
96// Very similar to scan relocs.
97
98class Gc_process_relocs : public Task
99{
100 public:
101 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
102 // unblocked when the task completes.
103 Gc_process_relocs(const General_options& options, Symbol_table* symtab,
104 Layout* layout, Relobj* object, Read_relocs_data* rd,
105 Task_token* symtab_lock, Task_token* blocker)
106 : options_(options), symtab_(symtab), layout_(layout), object_(object),
107 rd_(rd), symtab_lock_(symtab_lock), blocker_(blocker)
108 { }
109
110 // The standard Task methods.
111
112 Task_token*
113 is_runnable();
114
115 void
116 locks(Task_locker*);
117
118 void
119 run(Workqueue*);
120
121 std::string
122 get_name() const;
123
124 private:
125 const General_options& options_;
126 Symbol_table* symtab_;
127 Layout* layout_;
128 Relobj* object_;
129 Read_relocs_data* rd_;
130 Task_token* symtab_lock_;
131 Task_token* blocker_;
132};
133
92e059d8
ILT
134// Scan the relocations for an object to see if they require any
135// GOT/PLT/COPY relocations.
136
137class Scan_relocs : public Task
138{
139 public:
140 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
141 // unblocked when the task completes.
142 Scan_relocs(const General_options& options, Symbol_table* symtab,
f6ce93d6 143 Layout* layout, Relobj* object, Read_relocs_data* rd,
ead1e424
ILT
144 Task_token* symtab_lock, Task_token* blocker)
145 : options_(options), symtab_(symtab), layout_(layout), object_(object),
146 rd_(rd), symtab_lock_(symtab_lock), blocker_(blocker)
92e059d8
ILT
147 { }
148
149 // The standard Task methods.
150
17a1d0a9
ILT
151 Task_token*
152 is_runnable();
92e059d8 153
17a1d0a9
ILT
154 void
155 locks(Task_locker*);
92e059d8
ILT
156
157 void
158 run(Workqueue*);
159
c7912668
ILT
160 std::string
161 get_name() const;
162
92e059d8 163 private:
92e059d8
ILT
164 const General_options& options_;
165 Symbol_table* symtab_;
ead1e424 166 Layout* layout_;
f6ce93d6 167 Relobj* object_;
92e059d8
ILT
168 Read_relocs_data* rd_;
169 Task_token* symtab_lock_;
170 Task_token* blocker_;
171};
172
173// A class to perform all the relocations for an object file.
174
61ba1cf9
ILT
175class Relocate_task : public Task
176{
177 public:
178 Relocate_task(const General_options& options, const Symbol_table* symtab,
f6ce93d6 179 const Layout* layout, Relobj* object, Output_file* of,
730cdc88
ILT
180 Task_token* input_sections_blocker,
181 Task_token* output_sections_blocker, Task_token* final_blocker)
92e059d8 182 : options_(options), symtab_(symtab), layout_(layout), object_(object),
730cdc88
ILT
183 of_(of), input_sections_blocker_(input_sections_blocker),
184 output_sections_blocker_(output_sections_blocker),
185 final_blocker_(final_blocker)
61ba1cf9
ILT
186 { }
187
188 // The standard Task methods.
189
17a1d0a9
ILT
190 Task_token*
191 is_runnable();
61ba1cf9 192
17a1d0a9
ILT
193 void
194 locks(Task_locker*);
61ba1cf9
ILT
195
196 void
197 run(Workqueue*);
198
c7912668
ILT
199 std::string
200 get_name() const;
201
61ba1cf9 202 private:
61ba1cf9
ILT
203 const General_options& options_;
204 const Symbol_table* symtab_;
92e059d8 205 const Layout* layout_;
f6ce93d6 206 Relobj* object_;
61ba1cf9 207 Output_file* of_;
730cdc88
ILT
208 Task_token* input_sections_blocker_;
209 Task_token* output_sections_blocker_;
61ba1cf9
ILT
210 Task_token* final_blocker_;
211};
212
6a74a719
ILT
213// During a relocatable link, this class records how relocations
214// should be handled for a single input reloc section. An instance of
215// this class is created while scanning relocs, and it is used while
216// processing relocs.
217
218class Relocatable_relocs
219{
220 public:
221 // We use a vector of unsigned char to indicate how the input relocs
222 // should be handled. Each element is one of the following values.
223 // We create this vector when we initially scan the relocations.
224 enum Reloc_strategy
225 {
226 // Copy the input reloc. Don't modify it other than updating the
227 // r_offset field and the r_sym part of the r_info field.
228 RELOC_COPY,
229 // Copy the input reloc which is against an STT_SECTION symbol.
230 // Update the r_offset and r_sym part of the r_info field. Adjust
231 // the addend by subtracting the value of the old local symbol and
232 // adding the value of the new local symbol. The addend is in the
233 // SHT_RELA reloc and the contents of the data section do not need
234 // to be changed.
235 RELOC_ADJUST_FOR_SECTION_RELA,
7019cd25
ILT
236 // Like RELOC_ADJUST_FOR_SECTION_RELA but the addend should not be
237 // adjusted.
238 RELOC_ADJUST_FOR_SECTION_0,
6a74a719
ILT
239 // Like RELOC_ADJUST_FOR_SECTION_RELA but the contents of the
240 // section need to be changed. The number indicates the number of
241 // bytes in the addend in the section contents.
242 RELOC_ADJUST_FOR_SECTION_1,
243 RELOC_ADJUST_FOR_SECTION_2,
244 RELOC_ADJUST_FOR_SECTION_4,
245 RELOC_ADJUST_FOR_SECTION_8,
246 // Discard the input reloc--process it completely when relocating
247 // the data section contents.
248 RELOC_DISCARD,
249 // An input reloc which is not discarded, but which requires
250 // target specific processing in order to update it.
251 RELOC_SPECIAL
252 };
253
254 Relocatable_relocs()
255 : reloc_strategies_(), output_reloc_count_(0), posd_(NULL)
256 { }
257
258 // Record the number of relocs.
259 void
260 set_reloc_count(size_t reloc_count)
261 { this->reloc_strategies_.reserve(reloc_count); }
262
263 // Record what to do for the next reloc.
264 void
265 set_next_reloc_strategy(Reloc_strategy strategy)
266 {
267 this->reloc_strategies_.push_back(static_cast<unsigned char>(strategy));
268 if (strategy != RELOC_DISCARD)
269 ++this->output_reloc_count_;
270 }
271
272 // Record the Output_data associated with this reloc section.
273 void
274 set_output_data(Output_data* posd)
275 {
276 gold_assert(this->posd_ == NULL);
277 this->posd_ = posd;
278 }
279
280 // Return the Output_data associated with this reloc section.
281 Output_data*
282 output_data() const
283 { return this->posd_; }
284
285 // Return what to do for reloc I.
286 Reloc_strategy
287 strategy(unsigned int i) const
288 {
289 gold_assert(i < this->reloc_strategies_.size());
290 return static_cast<Reloc_strategy>(this->reloc_strategies_[i]);
291 }
292
293 // Return the number of relocations to create in the output file.
294 size_t
295 output_reloc_count() const
296 { return this->output_reloc_count_; }
297
298 private:
299 typedef std::vector<unsigned char> Reloc_strategies;
300
301 // The strategies for the input reloc. There is one entry in this
302 // vector for each relocation in the input section.
303 Reloc_strategies reloc_strategies_;
304 // The number of relocations to be created in the output file.
305 size_t output_reloc_count_;
306 // The output data structure associated with this relocation.
307 Output_data* posd_;
308};
309
92e059d8
ILT
310// Standard relocation routines which are used on many targets. Here
311// SIZE and BIG_ENDIAN refer to the target, not the relocation type.
312
313template<int size, bool big_endian>
314class Relocate_functions
315{
316private:
317 // Do a simple relocation with the addend in the section contents.
318 // VALSIZE is the size of the value.
319 template<int valsize>
320 static inline void
f6ce93d6
ILT
321 rel(unsigned char* view,
322 typename elfcpp::Swap<valsize, big_endian>::Valtype value)
92e059d8 323 {
f6ce93d6 324 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
92e059d8 325 Valtype* wv = reinterpret_cast<Valtype*>(view);
f6ce93d6
ILT
326 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
327 elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value);
92e059d8
ILT
328 }
329
b8e6aad9
ILT
330 // Do a simple relocation using a Symbol_value with the addend in
331 // the section contents. VALSIZE is the size of the value to
332 // relocate.
333 template<int valsize>
334 static inline void
335 rel(unsigned char* view,
336 const Sized_relobj<size, big_endian>* object,
337 const Symbol_value<size>* psymval)
338 {
339 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
340 Valtype* wv = reinterpret_cast<Valtype*>(view);
341 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
342 x = psymval->value(object, x);
343 elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
344 }
345
d830e0e0
ILT
346 // Do a simple relocation with the addend in the relocation.
347 // VALSIZE is the size of the value.
348 template<int valsize>
349 static inline void
350 rela(unsigned char* view,
351 typename elfcpp::Swap<valsize, big_endian>::Valtype value,
352 typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
353 {
354 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
355 Valtype* wv = reinterpret_cast<Valtype*>(view);
356 elfcpp::Swap<valsize, big_endian>::writeval(wv, value + addend);
357 }
358
359 // Do a simple relocation using a symbol value with the addend in
360 // the relocation. VALSIZE is the size of the value.
361 template<int valsize>
362 static inline void
363 rela(unsigned char* view,
364 const Sized_relobj<size, big_endian>* object,
365 const Symbol_value<size>* psymval,
366 typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
367 {
368 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
369 Valtype* wv = reinterpret_cast<Valtype*>(view);
370 Valtype x = psymval->value(object, addend);
371 elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
372 }
373
92e059d8
ILT
374 // Do a simple PC relative relocation with the addend in the section
375 // contents. VALSIZE is the size of the value.
376 template<int valsize>
377 static inline void
f6ce93d6
ILT
378 pcrel(unsigned char* view,
379 typename elfcpp::Swap<valsize, big_endian>::Valtype value,
92e059d8
ILT
380 typename elfcpp::Elf_types<size>::Elf_Addr address)
381 {
f6ce93d6 382 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
92e059d8 383 Valtype* wv = reinterpret_cast<Valtype*>(view);
f6ce93d6
ILT
384 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
385 elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address);
92e059d8
ILT
386 }
387
b8e6aad9
ILT
388 // Do a simple PC relative relocation with a Symbol_value with the
389 // addend in the section contents. VALSIZE is the size of the
390 // value.
391 template<int valsize>
392 static inline void
393 pcrel(unsigned char* view,
394 const Sized_relobj<size, big_endian>* object,
395 const Symbol_value<size>* psymval,
396 typename elfcpp::Elf_types<size>::Elf_Addr address)
397 {
398 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
399 Valtype* wv = reinterpret_cast<Valtype*>(view);
400 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
401 x = psymval->value(object, x);
402 elfcpp::Swap<valsize, big_endian>::writeval(wv, x - address);
403 }
404
d830e0e0
ILT
405 // Do a simple PC relative relocation with the addend in the
406 // relocation. VALSIZE is the size of the value.
407 template<int valsize>
408 static inline void
409 pcrela(unsigned char* view,
410 typename elfcpp::Swap<valsize, big_endian>::Valtype value,
411 typename elfcpp::Swap<valsize, big_endian>::Valtype addend,
412 typename elfcpp::Elf_types<size>::Elf_Addr address)
413 {
414 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
415 Valtype* wv = reinterpret_cast<Valtype*>(view);
416 elfcpp::Swap<valsize, big_endian>::writeval(wv, value + addend - address);
417 }
418
419 // Do a simple PC relative relocation with a Symbol_value with the
420 // addend in the relocation. VALSIZE is the size of the value.
421 template<int valsize>
422 static inline void
423 pcrela(unsigned char* view,
424 const Sized_relobj<size, big_endian>* object,
425 const Symbol_value<size>* psymval,
426 typename elfcpp::Swap<valsize, big_endian>::Valtype addend,
427 typename elfcpp::Elf_types<size>::Elf_Addr address)
428 {
429 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
430 Valtype* wv = reinterpret_cast<Valtype*>(view);
431 Valtype x = psymval->value(object, addend);
432 elfcpp::Swap<valsize, big_endian>::writeval(wv, x - address);
433 }
434
92e059d8
ILT
435 typedef Relocate_functions<size, big_endian> This;
436
437public:
b8e6aad9
ILT
438 // Do a simple 8-bit REL relocation with the addend in the section
439 // contents.
92e059d8
ILT
440 static inline void
441 rel8(unsigned char* view, unsigned char value)
b8e6aad9
ILT
442 { This::template rel<8>(view, value); }
443
444 static inline void
445 rel8(unsigned char* view,
446 const Sized_relobj<size, big_endian>* object,
447 const Symbol_value<size>* psymval)
448 { This::template rel<8>(view, object, psymval); }
92e059d8 449
d830e0e0
ILT
450 // Do an 8-bit RELA relocation with the addend in the relocation.
451 static inline void
5b3463d9 452 rela8(unsigned char* view, unsigned char value, unsigned char addend)
d830e0e0
ILT
453 { This::template rela<8>(view, value, addend); }
454
455 static inline void
5b3463d9 456 rela8(unsigned char* view,
d830e0e0
ILT
457 const Sized_relobj<size, big_endian>* object,
458 const Symbol_value<size>* psymval,
459 unsigned char addend)
460 { This::template rela<8>(view, object, psymval, addend); }
461
92e059d8 462 // Do a simple 8-bit PC relative relocation with the addend in the
b8e6aad9 463 // section contents.
92e059d8
ILT
464 static inline void
465 pcrel8(unsigned char* view, unsigned char value,
466 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
467 { This::template pcrel<8>(view, value, address); }
468
469 static inline void
470 pcrel8(unsigned char* view,
471 const Sized_relobj<size, big_endian>* object,
472 const Symbol_value<size>* psymval,
473 typename elfcpp::Elf_types<size>::Elf_Addr address)
474 { This::template pcrel<8>(view, object, psymval, address); }
92e059d8 475
d830e0e0
ILT
476 // Do a simple 8-bit PC relative RELA relocation with the addend in
477 // the reloc.
478 static inline void
479 pcrela8(unsigned char* view, unsigned char value, unsigned char addend,
480 typename elfcpp::Elf_types<size>::Elf_Addr address)
481 { This::template pcrela<8>(view, value, addend, address); }
482
483 static inline void
484 pcrela8(unsigned char* view,
485 const Sized_relobj<size, big_endian>* object,
486 const Symbol_value<size>* psymval,
487 unsigned char addend,
488 typename elfcpp::Elf_types<size>::Elf_Addr address)
489 { This::template pcrela<8>(view, object, psymval, addend, address); }
490
b8e6aad9
ILT
491 // Do a simple 16-bit REL relocation with the addend in the section
492 // contents.
92e059d8
ILT
493 static inline void
494 rel16(unsigned char* view, elfcpp::Elf_Half value)
b8e6aad9
ILT
495 { This::template rel<16>(view, value); }
496
497 static inline void
498 rel16(unsigned char* view,
499 const Sized_relobj<size, big_endian>* object,
500 const Symbol_value<size>* psymval)
501 { This::template rel<16>(view, object, psymval); }
92e059d8 502
d830e0e0
ILT
503 // Do an 16-bit RELA relocation with the addend in the relocation.
504 static inline void
505 rela16(unsigned char* view, elfcpp::Elf_Half value, elfcpp::Elf_Half addend)
506 { This::template rela<16>(view, value, addend); }
507
508 static inline void
509 rela16(unsigned char* view,
510 const Sized_relobj<size, big_endian>* object,
511 const Symbol_value<size>* psymval,
512 elfcpp::Elf_Half addend)
513 { This::template rela<16>(view, object, psymval, addend); }
514
d830e0e0 515 // Do a simple 16-bit PC relative REL relocation with the addend in
b8e6aad9 516 // the section contents.
92e059d8 517 static inline void
d830e0e0 518 pcrel16(unsigned char* view, elfcpp::Elf_Half value,
92e059d8 519 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
520 { This::template pcrel<16>(view, value, address); }
521
522 static inline void
523 pcrel16(unsigned char* view,
524 const Sized_relobj<size, big_endian>* object,
525 const Symbol_value<size>* psymval,
526 typename elfcpp::Elf_types<size>::Elf_Addr address)
527 { This::template pcrel<16>(view, object, psymval, address); }
92e059d8 528
d830e0e0
ILT
529 // Do a simple 16-bit PC relative RELA relocation with the addend in
530 // the reloc.
531 static inline void
532 pcrela16(unsigned char* view, elfcpp::Elf_Half value,
533 elfcpp::Elf_Half addend,
534 typename elfcpp::Elf_types<size>::Elf_Addr address)
535 { This::template pcrela<16>(view, value, addend, address); }
536
537 static inline void
538 pcrela16(unsigned char* view,
539 const Sized_relobj<size, big_endian>* object,
540 const Symbol_value<size>* psymval,
541 elfcpp::Elf_Half addend,
542 typename elfcpp::Elf_types<size>::Elf_Addr address)
543 { This::template pcrela<16>(view, object, psymval, addend, address); }
544
92e059d8
ILT
545 // Do a simple 32-bit REL relocation with the addend in the section
546 // contents.
547 static inline void
548 rel32(unsigned char* view, elfcpp::Elf_Word value)
b8e6aad9
ILT
549 { This::template rel<32>(view, value); }
550
551 static inline void
552 rel32(unsigned char* view,
553 const Sized_relobj<size, big_endian>* object,
554 const Symbol_value<size>* psymval)
555 { This::template rel<32>(view, object, psymval); }
92e059d8 556
d830e0e0
ILT
557 // Do an 32-bit RELA relocation with the addend in the relocation.
558 static inline void
559 rela32(unsigned char* view, elfcpp::Elf_Word value, elfcpp::Elf_Word addend)
560 { This::template rela<32>(view, value, addend); }
561
562 static inline void
563 rela32(unsigned char* view,
564 const Sized_relobj<size, big_endian>* object,
565 const Symbol_value<size>* psymval,
566 elfcpp::Elf_Word addend)
567 { This::template rela<32>(view, object, psymval, addend); }
568
92e059d8
ILT
569 // Do a simple 32-bit PC relative REL relocation with the addend in
570 // the section contents.
571 static inline void
572 pcrel32(unsigned char* view, elfcpp::Elf_Word value,
573 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
574 { This::template pcrel<32>(view, value, address); }
575
576 static inline void
577 pcrel32(unsigned char* view,
578 const Sized_relobj<size, big_endian>* object,
579 const Symbol_value<size>* psymval,
580 typename elfcpp::Elf_types<size>::Elf_Addr address)
581 { This::template pcrel<32>(view, object, psymval, address); }
92e059d8 582
d830e0e0
ILT
583 // Do a simple 32-bit PC relative RELA relocation with the addend in
584 // the relocation.
585 static inline void
586 pcrela32(unsigned char* view, elfcpp::Elf_Word value,
587 elfcpp::Elf_Word addend,
588 typename elfcpp::Elf_types<size>::Elf_Addr address)
589 { This::template pcrela<32>(view, value, addend, address); }
590
591 static inline void
592 pcrela32(unsigned char* view,
593 const Sized_relobj<size, big_endian>* object,
594 const Symbol_value<size>* psymval,
595 elfcpp::Elf_Word addend,
596 typename elfcpp::Elf_types<size>::Elf_Addr address)
597 { This::template pcrela<32>(view, object, psymval, addend, address); }
598
92e059d8
ILT
599 // Do a simple 64-bit REL relocation with the addend in the section
600 // contents.
601 static inline void
f6ce93d6 602 rel64(unsigned char* view, elfcpp::Elf_Xword value)
b8e6aad9
ILT
603 { This::template rel<64>(view, value); }
604
605 static inline void
606 rel64(unsigned char* view,
607 const Sized_relobj<size, big_endian>* object,
608 const Symbol_value<size>* psymval)
609 { This::template rel<64>(view, object, psymval); }
92e059d8 610
d830e0e0
ILT
611 // Do a 64-bit RELA relocation with the addend in the relocation.
612 static inline void
613 rela64(unsigned char* view, elfcpp::Elf_Xword value,
614 elfcpp::Elf_Xword addend)
615 { This::template rela<64>(view, value, addend); }
616
617 static inline void
618 rela64(unsigned char* view,
619 const Sized_relobj<size, big_endian>* object,
620 const Symbol_value<size>* psymval,
621 elfcpp::Elf_Xword addend)
622 { This::template rela<64>(view, object, psymval, addend); }
623
92e059d8
ILT
624 // Do a simple 64-bit PC relative REL relocation with the addend in
625 // the section contents.
626 static inline void
f6ce93d6 627 pcrel64(unsigned char* view, elfcpp::Elf_Xword value,
92e059d8 628 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
629 { This::template pcrel<64>(view, value, address); }
630
631 static inline void
632 pcrel64(unsigned char* view,
633 const Sized_relobj<size, big_endian>* object,
634 const Symbol_value<size>* psymval,
635 typename elfcpp::Elf_types<size>::Elf_Addr address)
636 { This::template pcrel<64>(view, object, psymval, address); }
d830e0e0
ILT
637
638 // Do a simple 64-bit PC relative RELA relocation with the addend in
639 // the relocation.
640 static inline void
641 pcrela64(unsigned char* view, elfcpp::Elf_Xword value,
642 elfcpp::Elf_Xword addend,
643 typename elfcpp::Elf_types<size>::Elf_Addr address)
644 { This::template pcrela<64>(view, value, addend, address); }
645
646 static inline void
647 pcrela64(unsigned char* view,
648 const Sized_relobj<size, big_endian>* object,
649 const Symbol_value<size>* psymval,
650 elfcpp::Elf_Xword addend,
651 typename elfcpp::Elf_types<size>::Elf_Addr address)
652 { This::template pcrela<64>(view, object, psymval, addend, address); }
5a6f7e2d
ILT
653};
654
730cdc88
ILT
655// Track relocations while reading a section. This lets you ask for
656// the relocation at a certain offset, and see how relocs occur
657// between points of interest.
658
659template<int size, bool big_endian>
660class Track_relocs
661{
662 public:
663 Track_relocs()
b696e6d4 664 : prelocs_(NULL), len_(0), pos_(0), reloc_size_(0)
730cdc88
ILT
665 { }
666
667 // Initialize the Track_relocs object. OBJECT is the object holding
668 // the reloc section, RELOC_SHNDX is the section index of the reloc
669 // section, and RELOC_TYPE is the type of the reloc section
670 // (elfcpp::SHT_REL or elfcpp::SHT_RELA). This returns false if
671 // something went wrong.
672 bool
b696e6d4 673 initialize(Object* object, unsigned int reloc_shndx,
730cdc88
ILT
674 unsigned int reloc_type);
675
676 // Return the offset in the data section to which the next reloc
677 // applies. THis returns -1 if there is no next reloc.
678 off_t
679 next_offset() const;
680
681 // Return the symbol index of the next reloc. This returns -1U if
682 // there is no next reloc.
683 unsigned int
684 next_symndx() const;
685
686 // Advance to OFFSET within the data section, and return the number
687 // of relocs which would be skipped.
688 int
689 advance(off_t offset);
690
691 private:
b696e6d4 692 // The contents of the input object's reloc section.
730cdc88
ILT
693 const unsigned char* prelocs_;
694 // The length of the reloc section.
8383303e 695 section_size_type len_;
730cdc88 696 // Our current position in the reloc section.
8383303e 697 section_size_type pos_;
730cdc88
ILT
698 // The size of the relocs in the section.
699 int reloc_size_;
700};
701
61ba1cf9
ILT
702} // End namespace gold.
703
704#endif // !defined(GOLD_RELOC_H)
This page took 0.149014 seconds and 4 git commands to generate.