From Craig Silverstein: rework DWARF reader code a bit.
[deliverable/binutils-gdb.git] / gold / reloc.h
CommitLineData
61ba1cf9
ILT
1// reloc.h -- relocate input files for gold -*- C++ -*-
2
6cb15b7f
ILT
3// Copyright 2006, 2007 Free Software Foundation, Inc.
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
92e059d8
ILT
26#include <byteswap.h>
27
4c50553d 28#include "elfcpp.h"
61ba1cf9
ILT
29#include "workqueue.h"
30
31namespace gold
32{
33
a3ad94ed 34class General_options;
f6ce93d6 35class Relobj;
92e059d8 36class Read_relocs_data;
a3ad94ed 37class Symbol;
ead1e424 38class Layout;
92e059d8 39
5a6f7e2d
ILT
40template<int size>
41class Sized_symbol;
42
b8e6aad9
ILT
43template<int size, bool big_endian>
44class Sized_relobj;
45
46template<int size>
47class Symbol_value;
48
5a6f7e2d
ILT
49template<int sh_type, bool dynamic, int size, bool big_endian>
50class Output_data_reloc;
51
92e059d8
ILT
52// A class to read the relocations for an object file, and then queue
53// up a task to see if they require any GOT/PLT/COPY relocations in
54// the symbol table.
55
56class Read_relocs : public Task
57{
58 public:
59 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
60 // unblocked when the Scan_relocs task completes.
61 Read_relocs(const General_options& options, Symbol_table* symtab,
f6ce93d6 62 Layout* layout, Relobj* object, Task_token* symtab_lock,
92e059d8 63 Task_token* blocker)
ead1e424 64 : options_(options), symtab_(symtab), layout_(layout), object_(object),
92e059d8
ILT
65 symtab_lock_(symtab_lock), blocker_(blocker)
66 { }
67
68 // The standard Task methods.
69
70 Is_runnable_type
71 is_runnable(Workqueue*);
72
73 Task_locker*
74 locks(Workqueue*);
75
76 void
77 run(Workqueue*);
78
79 private:
80 const General_options& options_;
81 Symbol_table* symtab_;
ead1e424 82 Layout* layout_;
f6ce93d6 83 Relobj* object_;
92e059d8
ILT
84 Task_token* symtab_lock_;
85 Task_token* blocker_;
86};
87
88// Scan the relocations for an object to see if they require any
89// GOT/PLT/COPY relocations.
90
91class Scan_relocs : public Task
92{
93 public:
94 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
95 // unblocked when the task completes.
96 Scan_relocs(const General_options& options, Symbol_table* symtab,
f6ce93d6 97 Layout* layout, Relobj* object, Read_relocs_data* rd,
ead1e424
ILT
98 Task_token* symtab_lock, Task_token* blocker)
99 : options_(options), symtab_(symtab), layout_(layout), object_(object),
100 rd_(rd), symtab_lock_(symtab_lock), blocker_(blocker)
92e059d8
ILT
101 { }
102
103 // The standard Task methods.
104
105 Is_runnable_type
106 is_runnable(Workqueue*);
107
108 Task_locker*
109 locks(Workqueue*);
110
111 void
112 run(Workqueue*);
113
114 private:
115 class Scan_relocs_locker;
116
117 const General_options& options_;
118 Symbol_table* symtab_;
ead1e424 119 Layout* layout_;
f6ce93d6 120 Relobj* object_;
92e059d8
ILT
121 Read_relocs_data* rd_;
122 Task_token* symtab_lock_;
123 Task_token* blocker_;
124};
125
126// A class to perform all the relocations for an object file.
127
61ba1cf9
ILT
128class Relocate_task : public Task
129{
130 public:
131 Relocate_task(const General_options& options, const Symbol_table* symtab,
f6ce93d6 132 const Layout* layout, Relobj* object, Output_file* of,
730cdc88
ILT
133 Task_token* input_sections_blocker,
134 Task_token* output_sections_blocker, Task_token* final_blocker)
92e059d8 135 : options_(options), symtab_(symtab), layout_(layout), object_(object),
730cdc88
ILT
136 of_(of), input_sections_blocker_(input_sections_blocker),
137 output_sections_blocker_(output_sections_blocker),
138 final_blocker_(final_blocker)
61ba1cf9
ILT
139 { }
140
141 // The standard Task methods.
142
143 Is_runnable_type
144 is_runnable(Workqueue*);
145
146 Task_locker*
147 locks(Workqueue*);
148
149 void
150 run(Workqueue*);
151
152 private:
153 class Relocate_locker;
154
155 const General_options& options_;
156 const Symbol_table* symtab_;
92e059d8 157 const Layout* layout_;
f6ce93d6 158 Relobj* object_;
61ba1cf9 159 Output_file* of_;
730cdc88
ILT
160 Task_token* input_sections_blocker_;
161 Task_token* output_sections_blocker_;
61ba1cf9
ILT
162 Task_token* final_blocker_;
163};
164
92e059d8
ILT
165// Standard relocation routines which are used on many targets. Here
166// SIZE and BIG_ENDIAN refer to the target, not the relocation type.
167
168template<int size, bool big_endian>
169class Relocate_functions
170{
171private:
172 // Do a simple relocation with the addend in the section contents.
173 // VALSIZE is the size of the value.
174 template<int valsize>
175 static inline void
f6ce93d6
ILT
176 rel(unsigned char* view,
177 typename elfcpp::Swap<valsize, big_endian>::Valtype value)
92e059d8 178 {
f6ce93d6 179 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
92e059d8 180 Valtype* wv = reinterpret_cast<Valtype*>(view);
f6ce93d6
ILT
181 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
182 elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value);
92e059d8
ILT
183 }
184
b8e6aad9
ILT
185 // Do a simple relocation using a Symbol_value with the addend in
186 // the section contents. VALSIZE is the size of the value to
187 // relocate.
188 template<int valsize>
189 static inline void
190 rel(unsigned char* view,
191 const Sized_relobj<size, big_endian>* object,
192 const Symbol_value<size>* psymval)
193 {
194 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
195 Valtype* wv = reinterpret_cast<Valtype*>(view);
196 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
197 x = psymval->value(object, x);
198 elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
199 }
200
d830e0e0
ILT
201 // Do a simple relocation with the addend in the relocation.
202 // VALSIZE is the size of the value.
203 template<int valsize>
204 static inline void
205 rela(unsigned char* view,
206 typename elfcpp::Swap<valsize, big_endian>::Valtype value,
207 typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
208 {
209 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
210 Valtype* wv = reinterpret_cast<Valtype*>(view);
211 elfcpp::Swap<valsize, big_endian>::writeval(wv, value + addend);
212 }
213
214 // Do a simple relocation using a symbol value with the addend in
215 // the relocation. VALSIZE is the size of the value.
216 template<int valsize>
217 static inline void
218 rela(unsigned char* view,
219 const Sized_relobj<size, big_endian>* object,
220 const Symbol_value<size>* psymval,
221 typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
222 {
223 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
224 Valtype* wv = reinterpret_cast<Valtype*>(view);
225 Valtype x = psymval->value(object, addend);
226 elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
227 }
228
92e059d8
ILT
229 // Do a simple PC relative relocation with the addend in the section
230 // contents. VALSIZE is the size of the value.
231 template<int valsize>
232 static inline void
f6ce93d6
ILT
233 pcrel(unsigned char* view,
234 typename elfcpp::Swap<valsize, big_endian>::Valtype value,
92e059d8
ILT
235 typename elfcpp::Elf_types<size>::Elf_Addr address)
236 {
f6ce93d6 237 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
92e059d8 238 Valtype* wv = reinterpret_cast<Valtype*>(view);
f6ce93d6
ILT
239 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
240 elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address);
92e059d8
ILT
241 }
242
b8e6aad9
ILT
243 // Do a simple PC relative relocation with a Symbol_value with the
244 // addend in the section contents. VALSIZE is the size of the
245 // value.
246 template<int valsize>
247 static inline void
248 pcrel(unsigned char* view,
249 const Sized_relobj<size, big_endian>* object,
250 const Symbol_value<size>* psymval,
251 typename elfcpp::Elf_types<size>::Elf_Addr address)
252 {
253 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
254 Valtype* wv = reinterpret_cast<Valtype*>(view);
255 Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
256 x = psymval->value(object, x);
257 elfcpp::Swap<valsize, big_endian>::writeval(wv, x - address);
258 }
259
d830e0e0
ILT
260 // Do a simple PC relative relocation with the addend in the
261 // relocation. VALSIZE is the size of the value.
262 template<int valsize>
263 static inline void
264 pcrela(unsigned char* view,
265 typename elfcpp::Swap<valsize, big_endian>::Valtype value,
266 typename elfcpp::Swap<valsize, big_endian>::Valtype addend,
267 typename elfcpp::Elf_types<size>::Elf_Addr address)
268 {
269 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
270 Valtype* wv = reinterpret_cast<Valtype*>(view);
271 elfcpp::Swap<valsize, big_endian>::writeval(wv, value + addend - address);
272 }
273
274 // Do a simple PC relative relocation with a Symbol_value with the
275 // addend in the relocation. VALSIZE is the size of the value.
276 template<int valsize>
277 static inline void
278 pcrela(unsigned char* view,
279 const Sized_relobj<size, big_endian>* object,
280 const Symbol_value<size>* psymval,
281 typename elfcpp::Swap<valsize, big_endian>::Valtype addend,
282 typename elfcpp::Elf_types<size>::Elf_Addr address)
283 {
284 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
285 Valtype* wv = reinterpret_cast<Valtype*>(view);
286 Valtype x = psymval->value(object, addend);
287 elfcpp::Swap<valsize, big_endian>::writeval(wv, x - address);
288 }
289
92e059d8
ILT
290 typedef Relocate_functions<size, big_endian> This;
291
292public:
b8e6aad9
ILT
293 // Do a simple 8-bit REL relocation with the addend in the section
294 // contents.
92e059d8
ILT
295 static inline void
296 rel8(unsigned char* view, unsigned char value)
b8e6aad9
ILT
297 { This::template rel<8>(view, value); }
298
299 static inline void
300 rel8(unsigned char* view,
301 const Sized_relobj<size, big_endian>* object,
302 const Symbol_value<size>* psymval)
303 { This::template rel<8>(view, object, psymval); }
92e059d8 304
d830e0e0
ILT
305 // Do an 8-bit RELA relocation with the addend in the relocation.
306 static inline void
5b3463d9 307 rela8(unsigned char* view, unsigned char value, unsigned char addend)
d830e0e0
ILT
308 { This::template rela<8>(view, value, addend); }
309
310 static inline void
5b3463d9 311 rela8(unsigned char* view,
d830e0e0
ILT
312 const Sized_relobj<size, big_endian>* object,
313 const Symbol_value<size>* psymval,
314 unsigned char addend)
315 { This::template rela<8>(view, object, psymval, addend); }
316
92e059d8 317 // Do a simple 8-bit PC relative relocation with the addend in the
b8e6aad9 318 // section contents.
92e059d8
ILT
319 static inline void
320 pcrel8(unsigned char* view, unsigned char value,
321 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
322 { This::template pcrel<8>(view, value, address); }
323
324 static inline void
325 pcrel8(unsigned char* view,
326 const Sized_relobj<size, big_endian>* object,
327 const Symbol_value<size>* psymval,
328 typename elfcpp::Elf_types<size>::Elf_Addr address)
329 { This::template pcrel<8>(view, object, psymval, address); }
92e059d8 330
d830e0e0
ILT
331 // Do a simple 8-bit PC relative RELA relocation with the addend in
332 // the reloc.
333 static inline void
334 pcrela8(unsigned char* view, unsigned char value, unsigned char addend,
335 typename elfcpp::Elf_types<size>::Elf_Addr address)
336 { This::template pcrela<8>(view, value, addend, address); }
337
338 static inline void
339 pcrela8(unsigned char* view,
340 const Sized_relobj<size, big_endian>* object,
341 const Symbol_value<size>* psymval,
342 unsigned char addend,
343 typename elfcpp::Elf_types<size>::Elf_Addr address)
344 { This::template pcrela<8>(view, object, psymval, addend, address); }
345
b8e6aad9
ILT
346 // Do a simple 16-bit REL relocation with the addend in the section
347 // contents.
92e059d8
ILT
348 static inline void
349 rel16(unsigned char* view, elfcpp::Elf_Half value)
b8e6aad9
ILT
350 { This::template rel<16>(view, value); }
351
352 static inline void
353 rel16(unsigned char* view,
354 const Sized_relobj<size, big_endian>* object,
355 const Symbol_value<size>* psymval)
356 { This::template rel<16>(view, object, psymval); }
92e059d8 357
d830e0e0
ILT
358 // Do an 16-bit RELA relocation with the addend in the relocation.
359 static inline void
360 rela16(unsigned char* view, elfcpp::Elf_Half value, elfcpp::Elf_Half addend)
361 { This::template rela<16>(view, value, addend); }
362
363 static inline void
364 rela16(unsigned char* view,
365 const Sized_relobj<size, big_endian>* object,
366 const Symbol_value<size>* psymval,
367 elfcpp::Elf_Half addend)
368 { This::template rela<16>(view, object, psymval, addend); }
369
d830e0e0 370 // Do a simple 16-bit PC relative REL relocation with the addend in
b8e6aad9 371 // the section contents.
92e059d8 372 static inline void
d830e0e0 373 pcrel16(unsigned char* view, elfcpp::Elf_Half value,
92e059d8 374 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
375 { This::template pcrel<16>(view, value, address); }
376
377 static inline void
378 pcrel16(unsigned char* view,
379 const Sized_relobj<size, big_endian>* object,
380 const Symbol_value<size>* psymval,
381 typename elfcpp::Elf_types<size>::Elf_Addr address)
382 { This::template pcrel<16>(view, object, psymval, address); }
92e059d8 383
d830e0e0
ILT
384 // Do a simple 16-bit PC relative RELA relocation with the addend in
385 // the reloc.
386 static inline void
387 pcrela16(unsigned char* view, elfcpp::Elf_Half value,
388 elfcpp::Elf_Half addend,
389 typename elfcpp::Elf_types<size>::Elf_Addr address)
390 { This::template pcrela<16>(view, value, addend, address); }
391
392 static inline void
393 pcrela16(unsigned char* view,
394 const Sized_relobj<size, big_endian>* object,
395 const Symbol_value<size>* psymval,
396 elfcpp::Elf_Half addend,
397 typename elfcpp::Elf_types<size>::Elf_Addr address)
398 { This::template pcrela<16>(view, object, psymval, addend, address); }
399
92e059d8
ILT
400 // Do a simple 32-bit REL relocation with the addend in the section
401 // contents.
402 static inline void
403 rel32(unsigned char* view, elfcpp::Elf_Word value)
b8e6aad9
ILT
404 { This::template rel<32>(view, value); }
405
406 static inline void
407 rel32(unsigned char* view,
408 const Sized_relobj<size, big_endian>* object,
409 const Symbol_value<size>* psymval)
410 { This::template rel<32>(view, object, psymval); }
92e059d8 411
d830e0e0
ILT
412 // Do an 32-bit RELA relocation with the addend in the relocation.
413 static inline void
414 rela32(unsigned char* view, elfcpp::Elf_Word value, elfcpp::Elf_Word addend)
415 { This::template rela<32>(view, value, addend); }
416
417 static inline void
418 rela32(unsigned char* view,
419 const Sized_relobj<size, big_endian>* object,
420 const Symbol_value<size>* psymval,
421 elfcpp::Elf_Word addend)
422 { This::template rela<32>(view, object, psymval, addend); }
423
92e059d8
ILT
424 // Do a simple 32-bit PC relative REL relocation with the addend in
425 // the section contents.
426 static inline void
427 pcrel32(unsigned char* view, elfcpp::Elf_Word value,
428 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
429 { This::template pcrel<32>(view, value, address); }
430
431 static inline void
432 pcrel32(unsigned char* view,
433 const Sized_relobj<size, big_endian>* object,
434 const Symbol_value<size>* psymval,
435 typename elfcpp::Elf_types<size>::Elf_Addr address)
436 { This::template pcrel<32>(view, object, psymval, address); }
92e059d8 437
d830e0e0
ILT
438 // Do a simple 32-bit PC relative RELA relocation with the addend in
439 // the relocation.
440 static inline void
441 pcrela32(unsigned char* view, elfcpp::Elf_Word value,
442 elfcpp::Elf_Word addend,
443 typename elfcpp::Elf_types<size>::Elf_Addr address)
444 { This::template pcrela<32>(view, value, addend, address); }
445
446 static inline void
447 pcrela32(unsigned char* view,
448 const Sized_relobj<size, big_endian>* object,
449 const Symbol_value<size>* psymval,
450 elfcpp::Elf_Word addend,
451 typename elfcpp::Elf_types<size>::Elf_Addr address)
452 { This::template pcrela<32>(view, object, psymval, addend, address); }
453
92e059d8
ILT
454 // Do a simple 64-bit REL relocation with the addend in the section
455 // contents.
456 static inline void
f6ce93d6 457 rel64(unsigned char* view, elfcpp::Elf_Xword value)
b8e6aad9
ILT
458 { This::template rel<64>(view, value); }
459
460 static inline void
461 rel64(unsigned char* view,
462 const Sized_relobj<size, big_endian>* object,
463 const Symbol_value<size>* psymval)
464 { This::template rel<64>(view, object, psymval); }
92e059d8 465
d830e0e0
ILT
466 // Do a 64-bit RELA relocation with the addend in the relocation.
467 static inline void
468 rela64(unsigned char* view, elfcpp::Elf_Xword value,
469 elfcpp::Elf_Xword addend)
470 { This::template rela<64>(view, value, addend); }
471
472 static inline void
473 rela64(unsigned char* view,
474 const Sized_relobj<size, big_endian>* object,
475 const Symbol_value<size>* psymval,
476 elfcpp::Elf_Xword addend)
477 { This::template rela<64>(view, object, psymval, addend); }
478
92e059d8
ILT
479 // Do a simple 64-bit PC relative REL relocation with the addend in
480 // the section contents.
481 static inline void
f6ce93d6 482 pcrel64(unsigned char* view, elfcpp::Elf_Xword value,
92e059d8 483 typename elfcpp::Elf_types<size>::Elf_Addr address)
b8e6aad9
ILT
484 { This::template pcrel<64>(view, value, address); }
485
486 static inline void
487 pcrel64(unsigned char* view,
488 const Sized_relobj<size, big_endian>* object,
489 const Symbol_value<size>* psymval,
490 typename elfcpp::Elf_types<size>::Elf_Addr address)
491 { This::template pcrel<64>(view, object, psymval, address); }
d830e0e0
ILT
492
493 // Do a simple 64-bit PC relative RELA relocation with the addend in
494 // the relocation.
495 static inline void
496 pcrela64(unsigned char* view, elfcpp::Elf_Xword value,
497 elfcpp::Elf_Xword addend,
498 typename elfcpp::Elf_types<size>::Elf_Addr address)
499 { This::template pcrela<64>(view, value, addend, address); }
500
501 static inline void
502 pcrela64(unsigned char* view,
503 const Sized_relobj<size, big_endian>* object,
504 const Symbol_value<size>* psymval,
505 elfcpp::Elf_Xword addend,
506 typename elfcpp::Elf_types<size>::Elf_Addr address)
507 { This::template pcrela<64>(view, object, psymval, addend, address); }
5a6f7e2d
ILT
508};
509
510// We try to avoid COPY relocations when possible. A COPY relocation
511// may be required when an executable refers to a variable defined in
512// a shared library. COPY relocations are problematic because they
513// tie the executable to the exact size of the variable in the shared
514// library. We can avoid them if all the references to the variable
515// are in a writeable section. In that case we can simply use dynamic
516// relocations. However, when scanning relocs, we don't know when we
517// see the relocation whether we will be forced to use a COPY
518// relocation or not. So we have to save the relocation during the
519// reloc scanning, and then emit it as a dynamic relocation if
520// necessary. This class implements that. It is used by the target
521// specific code.
522
523template<int size, bool big_endian>
524class Copy_relocs
525{
526 public:
527 Copy_relocs()
528 : entries_()
529 { }
a3ad94ed
ILT
530
531 // Return whether we need a COPY reloc for a reloc against GSYM,
532 // which is being applied to section SHNDX in OBJECT.
533 static bool
534 need_copy_reloc(const General_options*, Relobj* object, unsigned int shndx,
5a6f7e2d
ILT
535 Sized_symbol<size>* gsym);
536
537 // Save a Rel against SYM for possible emission later. SHNDX is the
538 // index of the section to which the reloc is being applied.
539 void
540 save(Symbol* sym, Relobj*, unsigned int shndx,
541 const elfcpp::Rel<size, big_endian>&);
542
543 // Save a Rela against SYM for possible emission later.
544 void
545 save(Symbol* sym, Relobj*, unsigned int shndx,
546 const elfcpp::Rela<size, big_endian>&);
547
548 // Return whether there are any relocs to emit. This also discards
549 // entries which need not be emitted.
550 bool
551 any_to_emit();
552
553 // Emit relocs for each symbol which did not get a COPY reloc (i.e.,
554 // is still defined in the dynamic object).
555 template<int sh_type>
556 void
557 emit(Output_data_reloc<sh_type, true, size, big_endian>*);
558
559 private:
560 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
561 typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
562
563 // This POD class holds the entries we are saving.
564 class Copy_reloc_entry
565 {
566 public:
567 Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
568 Relobj* relobj, unsigned int shndx,
569 Address address, Addend addend)
570 : sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
571 shndx_(shndx), address_(address), addend_(addend)
572 { }
573
574 // Return whether we should emit this reloc. If we should not
575 // emit, we clear it.
576 bool
577 should_emit();
578
579 // Emit this reloc.
580
581 void
582 emit(Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>*);
583
584 void
585 emit(Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>*);
586
587 private:
588 Symbol* sym_;
589 unsigned int reloc_type_;
590 Relobj* relobj_;
591 unsigned int shndx_;
592 Address address_;
593 Addend addend_;
594 };
595
596 // A list of relocs to be saved.
597 typedef std::vector<Copy_reloc_entry> Copy_reloc_entries;
598
599 // The list of relocs we are saving.
600 Copy_reloc_entries entries_;
92e059d8
ILT
601};
602
730cdc88
ILT
603// Track relocations while reading a section. This lets you ask for
604// the relocation at a certain offset, and see how relocs occur
605// between points of interest.
606
607template<int size, bool big_endian>
608class Track_relocs
609{
610 public:
611 Track_relocs()
612 : object_(NULL), prelocs_(NULL), len_(0), pos_(0), reloc_size_(0)
613 { }
614
615 // Initialize the Track_relocs object. OBJECT is the object holding
616 // the reloc section, RELOC_SHNDX is the section index of the reloc
617 // section, and RELOC_TYPE is the type of the reloc section
618 // (elfcpp::SHT_REL or elfcpp::SHT_RELA). This returns false if
619 // something went wrong.
620 bool
621 initialize(Sized_relobj<size, big_endian>* object, unsigned int reloc_shndx,
622 unsigned int reloc_type);
623
624 // Return the offset in the data section to which the next reloc
625 // applies. THis returns -1 if there is no next reloc.
626 off_t
627 next_offset() const;
628
629 // Return the symbol index of the next reloc. This returns -1U if
630 // there is no next reloc.
631 unsigned int
632 next_symndx() const;
633
634 // Advance to OFFSET within the data section, and return the number
635 // of relocs which would be skipped.
636 int
637 advance(off_t offset);
638
639 private:
640 // The object file.
641 Sized_relobj<size, big_endian>* object_;
642 // The contents of the reloc section.
643 const unsigned char* prelocs_;
644 // The length of the reloc section.
645 off_t len_;
646 // Our current position in the reloc section.
647 off_t pos_;
648 // The size of the relocs in the section.
649 int reloc_size_;
650};
651
61ba1cf9
ILT
652} // End namespace gold.
653
654#endif // !defined(GOLD_RELOC_H)
This page took 0.084413 seconds and 4 git commands to generate.