1 // reloc.h -- relocate input files for gold -*- C++ -*-
14 class Read_relocs_data
;
17 // A class to read the relocations for an object file, and then queue
18 // up a task to see if they require any GOT/PLT/COPY relocations in
21 class Read_relocs
: public Task
24 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
25 // unblocked when the Scan_relocs task completes.
26 Read_relocs(const General_options
& options
, Symbol_table
* symtab
,
27 Object
* object
, Task_token
* symtab_lock
,
29 : options_(options
), symtab_(symtab
), object_(object
),
30 symtab_lock_(symtab_lock
), blocker_(blocker
)
33 // The standard Task methods.
36 is_runnable(Workqueue
*);
45 const General_options
& options_
;
46 Symbol_table
* symtab_
;
48 Task_token
* symtab_lock_
;
52 // Scan the relocations for an object to see if they require any
53 // GOT/PLT/COPY relocations.
55 class Scan_relocs
: public Task
58 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
59 // unblocked when the task completes.
60 Scan_relocs(const General_options
& options
, Symbol_table
* symtab
,
61 Object
* object
, Read_relocs_data
* rd
, Task_token
* symtab_lock
,
63 : options_(options
), symtab_(symtab
), object_(object
), rd_(rd
),
64 symtab_lock_(symtab_lock
), blocker_(blocker
)
67 // The standard Task methods.
70 is_runnable(Workqueue
*);
79 class Scan_relocs_locker
;
81 const General_options
& options_
;
82 Symbol_table
* symtab_
;
84 Read_relocs_data
* rd_
;
85 Task_token
* symtab_lock_
;
89 // A class to perform all the relocations for an object file.
91 class Relocate_task
: public Task
94 Relocate_task(const General_options
& options
, const Symbol_table
* symtab
,
95 const Layout
* layout
, Object
* object
, Output_file
* of
,
96 Task_token
* final_blocker
)
97 : options_(options
), symtab_(symtab
), layout_(layout
), object_(object
),
98 of_(of
), final_blocker_(final_blocker
)
101 // The standard Task methods.
104 is_runnable(Workqueue
*);
113 class Relocate_locker
;
115 const General_options
& options_
;
116 const Symbol_table
* symtab_
;
117 const Layout
* layout_
;
120 Task_token
* final_blocker_
;
123 // Integer swapping routines used by relocation functions. FIXME:
124 // Maybe these should be more general, and/or shared with elfcpp.
126 // Endian simply indicates whether the host is big endian or not,
127 // based on the results of the configure script.
132 // Used for template specializations.
133 #ifdef WORDS_BIGENDIAN
134 static const bool host_big_endian
= true;
136 static const bool host_big_endian
= false;
140 // Valtype_base is a template based on size (8, 16, 32, 64) which
141 // defines a typedef Valtype for the unsigned integer of the specified
148 struct Valtype_base
<8>
150 typedef unsigned char Valtype
;
154 struct Valtype_base
<16>
156 typedef uint16_t Valtype
;
160 struct Valtype_base
<32>
162 typedef uint32_t Valtype
;
166 struct Valtype_base
<64>
168 typedef uint64_t Valtype
;
171 // Convert_host is a template based on size and on whether the host
172 // and target have the same endianness. It defines the type Valtype,
173 // and defines a function convert_host which takes an argument of type
174 // Valtype and swaps it if the host and target have different
177 template<int size
, bool same_endian
>
181 struct Convert_host
<size
, true>
183 typedef typename Valtype_base
<size
>::Valtype Valtype
;
185 static inline Valtype
186 convert_host(Valtype v
)
191 struct Convert_host
<8, false>
193 typedef Valtype_base
<8>::Valtype Valtype
;
195 static inline Valtype
196 convert_host(Valtype v
)
201 struct Convert_host
<16, false>
203 typedef Valtype_base
<16>::Valtype Valtype
;
205 static inline Valtype
206 convert_host(Valtype v
)
207 { return bswap_16(v
); }
211 struct Convert_host
<32, false>
213 typedef Valtype_base
<32>::Valtype Valtype
;
215 static inline Valtype
216 convert_host(Valtype v
)
217 { return bswap_32(v
); }
221 struct Convert_host
<64, false>
223 typedef Valtype_base
<64>::Valtype Valtype
;
225 static inline Valtype
226 convert_host(Valtype v
)
227 { return bswap_64(v
); }
230 // Convert is a template based on size and on whether we have a big
231 // endian target. It defines Valtype and convert_host like
232 // Convert_host. That is, it is just like Convert_host except in the
233 // meaning of the second template parameter.
235 template<int size
, bool big_endian
>
238 typedef typename Valtype_base
<size
>::Valtype Valtype
;
240 static inline Valtype
241 convert_host(Valtype v
)
242 { return Convert_host
<size
, big_endian
== Endian::host_big_endian
>
246 // Swap is a template based on size and on whether the target is big
247 // endian. It defines the type Valtype and the functions readval and
248 // writeval. The functions read and write values of the appropriate
249 // size out of buffers, swapping them if necessary.
251 template<int size
, bool big_endian
>
254 typedef typename Valtype_base
<size
>::Valtype Valtype
;
256 static inline Valtype
257 readval(const Valtype
* wv
)
258 { return Convert
<size
, big_endian
>::convert_host(*wv
); }
261 writeval(Valtype
* wv
, Valtype v
)
262 { *wv
= Convert
<size
, big_endian
>::convert_host(v
); }
265 // Swap_unaligned is a template based on size and on whether the
266 // target is big endian. It defines the type Valtype and the
267 // functions readval_unaligned and writeval_unaligned. The functions
268 // read and write values of the appropriate size out of buffers which
269 // may be misaligned.
271 template<int size
, bool big_endian
>
272 class Swap_unaligned
;
274 template<bool big_endian
>
275 class Swap_unaligned
<8, big_endian
>
278 typedef typename Valtype_base
<8>::Valtype Valtype
;
280 static inline Valtype
281 readval_unaligned(const unsigned char* wv
)
285 writeval_unaligned(unsigned char* wv
, Valtype v
)
290 class Swap_unaligned
<16, false>
293 typedef Valtype_base
<16>::Valtype Valtype
;
295 static inline Valtype
296 readval_unaligned(const unsigned char* wv
)
298 return (wv
[1] << 8) | wv
[0];
302 writeval_unaligned(unsigned char* wv
, Valtype v
)
310 class Swap_unaligned
<16, true>
313 typedef Valtype_base
<16>::Valtype Valtype
;
315 static inline Valtype
316 readval_unaligned(const unsigned char* wv
)
318 return (wv
[0] << 8) | wv
[1];
322 writeval_unaligned(unsigned char* wv
, Valtype v
)
330 class Swap_unaligned
<32, false>
333 typedef Valtype_base
<32>::Valtype Valtype
;
335 static inline Valtype
336 readval_unaligned(const unsigned char* wv
)
338 return (wv
[3] << 24) | (wv
[2] << 16) | (wv
[1] << 8) | wv
[0];
342 writeval_unaligned(unsigned char* wv
, Valtype v
)
352 class Swap_unaligned
<32, true>
355 typedef Valtype_base
<32>::Valtype Valtype
;
357 static inline Valtype
358 readval_unaligned(const unsigned char* wv
)
360 return (wv
[0] << 24) | (wv
[1] << 16) | (wv
[2] << 8) | wv
[3];
364 writeval_unaligned(unsigned char* wv
, Valtype v
)
374 class Swap_unaligned
<64, false>
377 typedef Valtype_base
<64>::Valtype Valtype
;
379 static inline Valtype
380 readval_unaligned(const unsigned char* wv
)
382 return ((static_cast<Valtype
>(wv
[7]) << 56)
383 | (static_cast<Valtype
>(wv
[6]) << 48)
384 | (static_cast<Valtype
>(wv
[5]) << 40)
385 | (static_cast<Valtype
>(wv
[4]) << 32)
386 | (static_cast<Valtype
>(wv
[3]) << 24)
387 | (static_cast<Valtype
>(wv
[2]) << 16)
388 | (static_cast<Valtype
>(wv
[1]) << 8)
389 | static_cast<Valtype
>(wv
[0]));
393 writeval_unaligned(unsigned char* wv
, Valtype v
)
407 class Swap_unaligned
<64, true>
410 typedef Valtype_base
<64>::Valtype Valtype
;
412 static inline Valtype
413 readval_unaligned(const unsigned char* wv
)
415 return ((static_cast<Valtype
>(wv
[0]) << 56)
416 | (static_cast<Valtype
>(wv
[1]) << 48)
417 | (static_cast<Valtype
>(wv
[2]) << 40)
418 | (static_cast<Valtype
>(wv
[3]) << 32)
419 | (static_cast<Valtype
>(wv
[4]) << 24)
420 | (static_cast<Valtype
>(wv
[5]) << 16)
421 | (static_cast<Valtype
>(wv
[6]) << 8)
422 | static_cast<Valtype
>(wv
[7]));
426 writeval_unaligned(unsigned char* wv
, Valtype v
)
439 // Standard relocation routines which are used on many targets. Here
440 // SIZE and BIG_ENDIAN refer to the target, not the relocation type.
442 template<int size
, bool big_endian
>
443 class Relocate_functions
446 // Do a simple relocation with the addend in the section contents.
447 // VALSIZE is the size of the value.
448 template<int valsize
>
450 rel(unsigned char* view
, typename Swap
<valsize
, big_endian
>::Valtype value
)
452 typedef typename Swap
<valsize
, big_endian
>::Valtype Valtype
;
453 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
454 Valtype x
= Swap
<valsize
, big_endian
>::readval(wv
);
455 Swap
<valsize
, big_endian
>::writeval(wv
, x
+ value
);
458 // Do a simple PC relative relocation with the addend in the section
459 // contents. VALSIZE is the size of the value.
460 template<int valsize
>
462 pcrel(unsigned char* view
, typename Swap
<valsize
, big_endian
>::Valtype value
,
463 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
465 typedef typename Swap
<valsize
, big_endian
>::Valtype Valtype
;
466 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
467 Valtype x
= Swap
<valsize
, big_endian
>::readval(wv
);
468 Swap
<valsize
, big_endian
>::writeval(wv
, x
+ value
- address
);
471 typedef Relocate_functions
<size
, big_endian
> This
;
474 // Do a simple 8-bit REL relocation with the addend in the object
477 rel8(unsigned char* view
, unsigned char value
)
479 This::template rel
<8>(view
, value
);
482 // Do a simple 8-bit PC relative relocation with the addend in the
485 pcrel8(unsigned char* view
, unsigned char value
,
486 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
488 This::template pcrel
<8>(view
, value
, address
);
491 // Do a simple 16-bit REL relocation with the addend in the object
494 rel16(unsigned char* view
, elfcpp::Elf_Half value
)
496 This::template rel
<16>(view
, value
);
499 // Do a simple 32-bit PC relative REL relocation with the addend in
500 // the object file data.
502 pcrel16(unsigned char* view
, elfcpp::Elf_Word value
,
503 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
505 This::template pcrel
<16>(view
, value
, address
);
508 // Do a simple 32-bit REL relocation with the addend in the section
511 rel32(unsigned char* view
, elfcpp::Elf_Word value
)
513 This::template rel
<32>(view
, value
);
516 // Do a simple 32-bit PC relative REL relocation with the addend in
517 // the section contents.
519 pcrel32(unsigned char* view
, elfcpp::Elf_Word value
,
520 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
522 This::template pcrel
<32>(view
, value
, address
);
525 // Do a simple 64-bit REL relocation with the addend in the section
528 rel64(unsigned char* view
, elfcpp::Elf_Word value
)
530 This::template rel
<64>(view
, value
);
533 // Do a simple 64-bit PC relative REL relocation with the addend in
534 // the section contents.
536 pcrel64(unsigned char* view
, elfcpp::Elf_Word value
,
537 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
539 This::template pcrel
<64>(view
, value
, address
);
543 } // End namespace gold.
545 #endif // !defined(GOLD_RELOC_H)