1 // reloc.h -- relocate input files for gold -*- C++ -*-
14 class Read_relocs_data
;
18 // A class to read the relocations for an object file, and then queue
19 // up a task to see if they require any GOT/PLT/COPY relocations in
22 class Read_relocs
: public Task
25 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
26 // unblocked when the Scan_relocs task completes.
27 Read_relocs(const General_options
& options
, Symbol_table
* symtab
,
28 Layout
* layout
, Object
* object
, Task_token
* symtab_lock
,
30 : options_(options
), symtab_(symtab
), layout_(layout
), object_(object
),
31 symtab_lock_(symtab_lock
), blocker_(blocker
)
34 // The standard Task methods.
37 is_runnable(Workqueue
*);
46 const General_options
& options_
;
47 Symbol_table
* symtab_
;
50 Task_token
* symtab_lock_
;
54 // Scan the relocations for an object to see if they require any
55 // GOT/PLT/COPY relocations.
57 class Scan_relocs
: public Task
60 // SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
61 // unblocked when the task completes.
62 Scan_relocs(const General_options
& options
, Symbol_table
* symtab
,
63 Layout
* layout
, Object
* object
, Read_relocs_data
* rd
,
64 Task_token
* symtab_lock
, Task_token
* blocker
)
65 : options_(options
), symtab_(symtab
), layout_(layout
), object_(object
),
66 rd_(rd
), symtab_lock_(symtab_lock
), blocker_(blocker
)
69 // The standard Task methods.
72 is_runnable(Workqueue
*);
81 class Scan_relocs_locker
;
83 const General_options
& options_
;
84 Symbol_table
* symtab_
;
87 Read_relocs_data
* rd_
;
88 Task_token
* symtab_lock_
;
92 // A class to perform all the relocations for an object file.
94 class Relocate_task
: public Task
97 Relocate_task(const General_options
& options
, const Symbol_table
* symtab
,
98 const Layout
* layout
, Object
* object
, Output_file
* of
,
99 Task_token
* final_blocker
)
100 : options_(options
), symtab_(symtab
), layout_(layout
), object_(object
),
101 of_(of
), final_blocker_(final_blocker
)
104 // The standard Task methods.
107 is_runnable(Workqueue
*);
116 class Relocate_locker
;
118 const General_options
& options_
;
119 const Symbol_table
* symtab_
;
120 const Layout
* layout_
;
123 Task_token
* final_blocker_
;
126 // Integer swapping routines used by relocation functions. FIXME:
127 // Maybe these should be more general, and/or shared with elfcpp.
129 // Endian simply indicates whether the host is big endian or not,
130 // based on the results of the configure script.
135 // Used for template specializations.
136 #ifdef WORDS_BIGENDIAN
137 static const bool host_big_endian
= true;
139 static const bool host_big_endian
= false;
143 // Valtype_base is a template based on size (8, 16, 32, 64) which
144 // defines a typedef Valtype for the unsigned integer of the specified
151 struct Valtype_base
<8>
153 typedef unsigned char Valtype
;
157 struct Valtype_base
<16>
159 typedef uint16_t Valtype
;
163 struct Valtype_base
<32>
165 typedef uint32_t Valtype
;
169 struct Valtype_base
<64>
171 typedef uint64_t Valtype
;
174 // Convert_host is a template based on size and on whether the host
175 // and target have the same endianness. It defines the type Valtype,
176 // and defines a function convert_host which takes an argument of type
177 // Valtype and swaps it if the host and target have different
180 template<int size
, bool same_endian
>
184 struct Convert_host
<size
, true>
186 typedef typename Valtype_base
<size
>::Valtype Valtype
;
188 static inline Valtype
189 convert_host(Valtype v
)
194 struct Convert_host
<8, false>
196 typedef Valtype_base
<8>::Valtype Valtype
;
198 static inline Valtype
199 convert_host(Valtype v
)
204 struct Convert_host
<16, false>
206 typedef Valtype_base
<16>::Valtype Valtype
;
208 static inline Valtype
209 convert_host(Valtype v
)
210 { return bswap_16(v
); }
214 struct Convert_host
<32, false>
216 typedef Valtype_base
<32>::Valtype Valtype
;
218 static inline Valtype
219 convert_host(Valtype v
)
220 { return bswap_32(v
); }
224 struct Convert_host
<64, false>
226 typedef Valtype_base
<64>::Valtype Valtype
;
228 static inline Valtype
229 convert_host(Valtype v
)
230 { return bswap_64(v
); }
233 // Convert is a template based on size and on whether we have a big
234 // endian target. It defines Valtype and convert_host like
235 // Convert_host. That is, it is just like Convert_host except in the
236 // meaning of the second template parameter.
238 template<int size
, bool big_endian
>
241 typedef typename Valtype_base
<size
>::Valtype Valtype
;
243 static inline Valtype
244 convert_host(Valtype v
)
245 { return Convert_host
<size
, big_endian
== Endian::host_big_endian
>
249 // Swap is a template based on size and on whether the target is big
250 // endian. It defines the type Valtype and the functions readval and
251 // writeval. The functions read and write values of the appropriate
252 // size out of buffers, swapping them if necessary.
254 template<int size
, bool big_endian
>
257 typedef typename Valtype_base
<size
>::Valtype Valtype
;
259 static inline Valtype
260 readval(const Valtype
* wv
)
261 { return Convert
<size
, big_endian
>::convert_host(*wv
); }
264 writeval(Valtype
* wv
, Valtype v
)
265 { *wv
= Convert
<size
, big_endian
>::convert_host(v
); }
268 // Swap_unaligned is a template based on size and on whether the
269 // target is big endian. It defines the type Valtype and the
270 // functions readval_unaligned and writeval_unaligned. The functions
271 // read and write values of the appropriate size out of buffers which
272 // may be misaligned.
274 template<int size
, bool big_endian
>
275 class Swap_unaligned
;
277 template<bool big_endian
>
278 class Swap_unaligned
<8, big_endian
>
281 typedef typename Valtype_base
<8>::Valtype Valtype
;
283 static inline Valtype
284 readval_unaligned(const unsigned char* wv
)
288 writeval_unaligned(unsigned char* wv
, Valtype v
)
293 class Swap_unaligned
<16, false>
296 typedef Valtype_base
<16>::Valtype Valtype
;
298 static inline Valtype
299 readval_unaligned(const unsigned char* wv
)
301 return (wv
[1] << 8) | wv
[0];
305 writeval_unaligned(unsigned char* wv
, Valtype v
)
313 class Swap_unaligned
<16, true>
316 typedef Valtype_base
<16>::Valtype Valtype
;
318 static inline Valtype
319 readval_unaligned(const unsigned char* wv
)
321 return (wv
[0] << 8) | wv
[1];
325 writeval_unaligned(unsigned char* wv
, Valtype v
)
333 class Swap_unaligned
<32, false>
336 typedef Valtype_base
<32>::Valtype Valtype
;
338 static inline Valtype
339 readval_unaligned(const unsigned char* wv
)
341 return (wv
[3] << 24) | (wv
[2] << 16) | (wv
[1] << 8) | wv
[0];
345 writeval_unaligned(unsigned char* wv
, Valtype v
)
355 class Swap_unaligned
<32, true>
358 typedef Valtype_base
<32>::Valtype Valtype
;
360 static inline Valtype
361 readval_unaligned(const unsigned char* wv
)
363 return (wv
[0] << 24) | (wv
[1] << 16) | (wv
[2] << 8) | wv
[3];
367 writeval_unaligned(unsigned char* wv
, Valtype v
)
377 class Swap_unaligned
<64, false>
380 typedef Valtype_base
<64>::Valtype Valtype
;
382 static inline Valtype
383 readval_unaligned(const unsigned char* wv
)
385 return ((static_cast<Valtype
>(wv
[7]) << 56)
386 | (static_cast<Valtype
>(wv
[6]) << 48)
387 | (static_cast<Valtype
>(wv
[5]) << 40)
388 | (static_cast<Valtype
>(wv
[4]) << 32)
389 | (static_cast<Valtype
>(wv
[3]) << 24)
390 | (static_cast<Valtype
>(wv
[2]) << 16)
391 | (static_cast<Valtype
>(wv
[1]) << 8)
392 | static_cast<Valtype
>(wv
[0]));
396 writeval_unaligned(unsigned char* wv
, Valtype v
)
410 class Swap_unaligned
<64, true>
413 typedef Valtype_base
<64>::Valtype Valtype
;
415 static inline Valtype
416 readval_unaligned(const unsigned char* wv
)
418 return ((static_cast<Valtype
>(wv
[0]) << 56)
419 | (static_cast<Valtype
>(wv
[1]) << 48)
420 | (static_cast<Valtype
>(wv
[2]) << 40)
421 | (static_cast<Valtype
>(wv
[3]) << 32)
422 | (static_cast<Valtype
>(wv
[4]) << 24)
423 | (static_cast<Valtype
>(wv
[5]) << 16)
424 | (static_cast<Valtype
>(wv
[6]) << 8)
425 | static_cast<Valtype
>(wv
[7]));
429 writeval_unaligned(unsigned char* wv
, Valtype v
)
442 // Standard relocation routines which are used on many targets. Here
443 // SIZE and BIG_ENDIAN refer to the target, not the relocation type.
445 template<int size
, bool big_endian
>
446 class Relocate_functions
449 // Do a simple relocation with the addend in the section contents.
450 // VALSIZE is the size of the value.
451 template<int valsize
>
453 rel(unsigned char* view
, typename Swap
<valsize
, big_endian
>::Valtype value
)
455 typedef typename Swap
<valsize
, big_endian
>::Valtype Valtype
;
456 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
457 Valtype x
= Swap
<valsize
, big_endian
>::readval(wv
);
458 Swap
<valsize
, big_endian
>::writeval(wv
, x
+ value
);
461 // Do a simple PC relative relocation with the addend in the section
462 // contents. VALSIZE is the size of the value.
463 template<int valsize
>
465 pcrel(unsigned char* view
, typename Swap
<valsize
, big_endian
>::Valtype value
,
466 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
468 typedef typename Swap
<valsize
, big_endian
>::Valtype Valtype
;
469 Valtype
* wv
= reinterpret_cast<Valtype
*>(view
);
470 Valtype x
= Swap
<valsize
, big_endian
>::readval(wv
);
471 Swap
<valsize
, big_endian
>::writeval(wv
, x
+ value
- address
);
474 typedef Relocate_functions
<size
, big_endian
> This
;
477 // Do a simple 8-bit REL relocation with the addend in the object
480 rel8(unsigned char* view
, unsigned char value
)
482 This::template rel
<8>(view
, value
);
485 // Do a simple 8-bit PC relative relocation with the addend in the
488 pcrel8(unsigned char* view
, unsigned char value
,
489 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
491 This::template pcrel
<8>(view
, value
, address
);
494 // Do a simple 16-bit REL relocation with the addend in the object
497 rel16(unsigned char* view
, elfcpp::Elf_Half value
)
499 This::template rel
<16>(view
, value
);
502 // Do a simple 32-bit PC relative REL relocation with the addend in
503 // the object file data.
505 pcrel16(unsigned char* view
, elfcpp::Elf_Word value
,
506 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
508 This::template pcrel
<16>(view
, value
, address
);
511 // Do a simple 32-bit REL relocation with the addend in the section
514 rel32(unsigned char* view
, elfcpp::Elf_Word value
)
516 This::template rel
<32>(view
, value
);
519 // Do a simple 32-bit PC relative REL relocation with the addend in
520 // the section contents.
522 pcrel32(unsigned char* view
, elfcpp::Elf_Word value
,
523 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
525 This::template pcrel
<32>(view
, value
, address
);
528 // Do a simple 64-bit REL relocation with the addend in the section
531 rel64(unsigned char* view
, elfcpp::Elf_Word value
)
533 This::template rel
<64>(view
, value
);
536 // Do a simple 64-bit PC relative REL relocation with the addend in
537 // the section contents.
539 pcrel64(unsigned char* view
, elfcpp::Elf_Word value
,
540 typename
elfcpp::Elf_types
<size
>::Elf_Addr address
)
542 This::template pcrel
<64>(view
, value
, address
);
546 } // End namespace gold.
548 #endif // !defined(GOLD_RELOC_H)
This page took 0.041211 seconds and 5 git commands to generate.