580b3ef92fb592bf291f3745e7813951d5496cff
[deliverable/binutils-gdb.git] / gold / arm.cc
1 // arm.cc -- arm target support for gold.
2
3 // Copyright 2009 Free Software Foundation, Inc.
4 // Written by Doug Kwan <dougkwan@google.com> based on the i386 code
5 // by Ian Lance Taylor <iant@google.com>.
6
7 // This file is part of gold.
8
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 3 of the License, or
12 // (at your option) any later version.
13
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 // MA 02110-1301, USA.
23
24 #include "gold.h"
25
26 #include <cstring>
27 #include <limits>
28 #include <cstdio>
29 #include <string>
30
31 #include "elfcpp.h"
32 #include "parameters.h"
33 #include "reloc.h"
34 #include "arm.h"
35 #include "object.h"
36 #include "symtab.h"
37 #include "layout.h"
38 #include "output.h"
39 #include "copy-relocs.h"
40 #include "target.h"
41 #include "target-reloc.h"
42 #include "target-select.h"
43 #include "tls.h"
44 #include "defstd.h"
45
46 namespace
47 {
48
49 using namespace gold;
50
51 // The arm target class.
52 //
53 // This is a very simple port of gold for ARM-EABI. It is intended for
54 // supporting Android only for the time being. Only these relocation types
55 // are supported.
56 //
57 // R_ARM_NONE
58 // R_ARM_ABS32
59 // R_ARM_REL32
60 // R_ARM_THM_CALL
61 // R_ARM_COPY
62 // R_ARM_GLOB_DAT
63 // R_ARM_BASE_PREL
64 // R_ARM_JUMP_SLOT
65 // R_ARM_RELATIVE
66 // R_ARM_GOTOFF32
67 // R_ARM_GOT_BREL
68 // R_ARM_PLT32
69 // R_ARM_CALL
70 // R_ARM_JUMP24
71 // R_ARM_TARGET1
72 // R_ARM_PREL31
73 //
74 // Coming soon (pending patches):
75 // - Support for dynamic symbols (GOT, PLT and etc).
76 // - Local scanner
77 // - Global scanner
78 // - Relocation
79 // - Defining section symbols __exidx_start and __exidx_stop.
80 // - Support interworking.
81 // - Mergeing all .ARM.xxx.yyy sections into .ARM.xxx. Currently, they
82 // are incorrectly merged into an .ARM section.
83 //
84 // TODOs:
85 // - Create a PT_ARM_EXIDX program header for a shared object that
86 // might throw an exception.
87 // - Support more relocation types as needed.
88
89 template<bool big_endian>
90 class Target_arm : public Sized_target<32, big_endian>
91 {
92 public:
93 typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
94 Reloc_section;
95
96 Target_arm()
97 : Sized_target<32, big_endian>(&arm_info)
98 { }
99
100 // Process the relocations to determine unreferenced sections for
101 // garbage collection.
102 void
103 gc_process_relocs(const General_options& options,
104 Symbol_table* symtab,
105 Layout* layout,
106 Sized_relobj<32, big_endian>* object,
107 unsigned int data_shndx,
108 unsigned int sh_type,
109 const unsigned char* prelocs,
110 size_t reloc_count,
111 Output_section* output_section,
112 bool needs_special_offset_handling,
113 size_t local_symbol_count,
114 const unsigned char* plocal_symbols);
115
116 // Scan the relocations to look for symbol adjustments.
117 void
118 scan_relocs(const General_options& options,
119 Symbol_table* symtab,
120 Layout* layout,
121 Sized_relobj<32, big_endian>* object,
122 unsigned int data_shndx,
123 unsigned int sh_type,
124 const unsigned char* prelocs,
125 size_t reloc_count,
126 Output_section* output_section,
127 bool needs_special_offset_handling,
128 size_t local_symbol_count,
129 const unsigned char* plocal_symbols);
130
131 // Finalize the sections.
132 void
133 do_finalize_sections(Layout*);
134
135 // Return the value to use for a dynamic which requires special
136 // treatment.
137 uint64_t
138 do_dynsym_value(const Symbol*) const;
139
140 // Relocate a section.
141 void
142 relocate_section(const Relocate_info<32, big_endian>*,
143 unsigned int sh_type,
144 const unsigned char* prelocs,
145 size_t reloc_count,
146 Output_section* output_section,
147 bool needs_special_offset_handling,
148 unsigned char* view,
149 elfcpp::Elf_types<32>::Elf_Addr view_address,
150 section_size_type view_size);
151
152 // Scan the relocs during a relocatable link.
153 void
154 scan_relocatable_relocs(const General_options& options,
155 Symbol_table* symtab,
156 Layout* layout,
157 Sized_relobj<32, big_endian>* object,
158 unsigned int data_shndx,
159 unsigned int sh_type,
160 const unsigned char* prelocs,
161 size_t reloc_count,
162 Output_section* output_section,
163 bool needs_special_offset_handling,
164 size_t local_symbol_count,
165 const unsigned char* plocal_symbols,
166 Relocatable_relocs*);
167
168 // Relocate a section during a relocatable link.
169 void
170 relocate_for_relocatable(const Relocate_info<32, big_endian>*,
171 unsigned int sh_type,
172 const unsigned char* prelocs,
173 size_t reloc_count,
174 Output_section* output_section,
175 off_t offset_in_output_section,
176 const Relocatable_relocs*,
177 unsigned char* view,
178 elfcpp::Elf_types<32>::Elf_Addr view_address,
179 section_size_type view_size,
180 unsigned char* reloc_view,
181 section_size_type reloc_view_size);
182
183 // Return whether SYM is defined by the ABI.
184 bool
185 do_is_defined_by_abi(Symbol* sym) const
186 { return strcmp(sym->name(), "__tls_get_addr") == 0; }
187
188 // Map platform-specific reloc types
189 static unsigned int
190 get_real_reloc_type (unsigned int r_type);
191
192 private:
193 // The class which scans relocations.
194 class Scan
195 {
196 public:
197 Scan()
198 { }
199
200 inline void
201 local(const General_options& options, Symbol_table* symtab,
202 Layout* layout, Target_arm* target,
203 Sized_relobj<32, big_endian>* object,
204 unsigned int data_shndx,
205 Output_section* output_section,
206 const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
207 const elfcpp::Sym<32, big_endian>& lsym);
208
209 inline void
210 global(const General_options& options, Symbol_table* symtab,
211 Layout* layout, Target_arm* target,
212 Sized_relobj<32, big_endian>* object,
213 unsigned int data_shndx,
214 Output_section* output_section,
215 const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
216 Symbol* gsym);
217
218 private:
219 static void
220 unsupported_reloc_local(Sized_relobj<32, big_endian>*,
221 unsigned int r_type);
222
223 static void
224 unsupported_reloc_global(Sized_relobj<32, big_endian>*,
225 unsigned int r_type, Symbol*);
226 };
227
228 // The class which implements relocation.
229 class Relocate
230 {
231 public:
232 Relocate()
233 { }
234
235 ~Relocate()
236 { }
237
238 // Do a relocation. Return false if the caller should not issue
239 // any warnings about this relocation.
240 inline bool
241 relocate(const Relocate_info<32, big_endian>*, Target_arm*,
242 Output_section*, size_t relnum,
243 const elfcpp::Rel<32, big_endian>&,
244 unsigned int r_type, const Sized_symbol<32>*,
245 const Symbol_value<32>*,
246 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
247 section_size_type);
248 };
249
250 // A class which returns the size required for a relocation type,
251 // used while scanning relocs during a relocatable link.
252 class Relocatable_size_for_reloc
253 {
254 public:
255 unsigned int
256 get_size_for_reloc(unsigned int, Relobj*);
257 };
258
259 // Information about this specific target which we pass to the
260 // general Target structure.
261 static const Target::Target_info arm_info;
262 };
263
264 template<bool big_endian>
265 const Target::Target_info Target_arm<big_endian>::arm_info =
266 {
267 32, // size
268 big_endian, // is_big_endian
269 elfcpp::EM_ARM, // machine_code
270 false, // has_make_symbol
271 false, // has_resolve
272 false, // has_code_fill
273 true, // is_default_stack_executable
274 '\0', // wrap_char
275 "/usr/lib/libc.so.1", // dynamic_linker
276 0x8000, // default_text_segment_address
277 0x1000, // abi_pagesize (overridable by -z max-page-size)
278 0x1000 // common_pagesize (overridable by -z common-page-size)
279 };
280
281 // Report an unsupported relocation against a local symbol.
282
283 template<bool big_endian>
284 void
285 Target_arm<big_endian>::Scan::unsupported_reloc_local(
286 Sized_relobj<32, big_endian>* object,
287 unsigned int r_type)
288 {
289 gold_error(_("%s: unsupported reloc %u against local symbol"),
290 object->name().c_str(), r_type);
291 }
292
293 // Scan a relocation for a local symbol.
294
295 template<bool big_endian>
296 inline void
297 Target_arm<big_endian>::Scan::local(const General_options&,
298 Symbol_table* /* symtab */,
299 Layout* /* layout */,
300 Target_arm* /* target */,
301 Sized_relobj<32, big_endian>* object,
302 unsigned int /* data_shndx */,
303 Output_section* /* output_section */,
304 const elfcpp::Rel<32, big_endian>& /* reloc */,
305 unsigned int r_type,
306 const elfcpp::Sym<32, big_endian>&)
307 {
308 r_type = get_real_reloc_type(r_type);
309 switch (r_type)
310 {
311 case elfcpp::R_ARM_NONE:
312 break;
313
314 default:
315 unsupported_reloc_local(object, r_type);
316 break;
317 }
318 }
319
320 // Report an unsupported relocation against a global symbol.
321
322 template<bool big_endian>
323 void
324 Target_arm<big_endian>::Scan::unsupported_reloc_global(
325 Sized_relobj<32, big_endian>* object,
326 unsigned int r_type,
327 Symbol* gsym)
328 {
329 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
330 object->name().c_str(), r_type, gsym->demangled_name().c_str());
331 }
332
333 // Scan a relocation for a global symbol.
334
335 template<bool big_endian>
336 inline void
337 Target_arm<big_endian>::Scan::global(const General_options&,
338 Symbol_table* /* symtab */,
339 Layout* /* layout */,
340 Target_arm* /* target */,
341 Sized_relobj<32, big_endian>* object,
342 unsigned int /* data_shndx */,
343 Output_section* /* output_section */,
344 const elfcpp::Rel<32, big_endian>& /* reloc */,
345 unsigned int r_type,
346 Symbol* gsym)
347 {
348 r_type = get_real_reloc_type(r_type);
349 switch (r_type)
350 {
351 case elfcpp::R_ARM_NONE:
352 break;
353
354 default:
355 unsupported_reloc_global(object, r_type, gsym);
356 break;
357 }
358 }
359
360 // Process relocations for gc.
361
362 template<bool big_endian>
363 void
364 Target_arm<big_endian>::gc_process_relocs(const General_options& options,
365 Symbol_table* symtab,
366 Layout* layout,
367 Sized_relobj<32, big_endian>* object,
368 unsigned int data_shndx,
369 unsigned int,
370 const unsigned char* prelocs,
371 size_t reloc_count,
372 Output_section* output_section,
373 bool needs_special_offset_handling,
374 size_t local_symbol_count,
375 const unsigned char* plocal_symbols)
376 {
377 typedef Target_arm<big_endian> Arm;
378 typedef typename Target_arm<big_endian>::Scan Scan;
379
380 gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan>(
381 options,
382 symtab,
383 layout,
384 this,
385 object,
386 data_shndx,
387 prelocs,
388 reloc_count,
389 output_section,
390 needs_special_offset_handling,
391 local_symbol_count,
392 plocal_symbols);
393 }
394
395 // Scan relocations for a section.
396
397 template<bool big_endian>
398 void
399 Target_arm<big_endian>::scan_relocs(const General_options& options,
400 Symbol_table* symtab,
401 Layout* layout,
402 Sized_relobj<32, big_endian>* object,
403 unsigned int data_shndx,
404 unsigned int sh_type,
405 const unsigned char* prelocs,
406 size_t reloc_count,
407 Output_section* output_section,
408 bool needs_special_offset_handling,
409 size_t local_symbol_count,
410 const unsigned char* plocal_symbols)
411 {
412 typedef typename Target_arm<big_endian>::Scan Scan;
413 if (sh_type == elfcpp::SHT_RELA)
414 {
415 gold_error(_("%s: unsupported RELA reloc section"),
416 object->name().c_str());
417 return;
418 }
419
420 gold::scan_relocs<32, big_endian, Target_arm, elfcpp::SHT_REL, Scan>(
421 options,
422 symtab,
423 layout,
424 this,
425 object,
426 data_shndx,
427 prelocs,
428 reloc_count,
429 output_section,
430 needs_special_offset_handling,
431 local_symbol_count,
432 plocal_symbols);
433 }
434
435 // Finalize the sections.
436
437 template<bool big_endian>
438 void
439 Target_arm<big_endian>::do_finalize_sections(Layout* /* layout */)
440 {
441 gold_unreachable ();
442 }
443
444 // Perform a relocation.
445
446 template<bool big_endian>
447 inline bool
448 Target_arm<big_endian>::Relocate::relocate(
449 const Relocate_info<32, big_endian>* /* relinfo */,
450 Target_arm* /* target */,
451 Output_section* /* output_section */,
452 size_t /* relnum */,
453 const elfcpp::Rel<32, big_endian>& /* rel */,
454 unsigned int r_type,
455 const Sized_symbol<32>* /* gsym */,
456 const Symbol_value<32>* /* psymval */,
457 unsigned char* /* view */,
458 elfcpp::Elf_types<32>::Elf_Addr /* address */,
459 section_size_type /* view_size */ )
460 {
461 switch (r_type)
462 {
463 case elfcpp::R_ARM_NONE:
464 break;
465
466 default:
467 gold_unreachable();
468 }
469
470 return true;
471 }
472
473 // Relocate section data.
474
475 template<bool big_endian>
476 void
477 Target_arm<big_endian>::relocate_section(
478 const Relocate_info<32, big_endian>* relinfo,
479 unsigned int sh_type,
480 const unsigned char* prelocs,
481 size_t reloc_count,
482 Output_section* output_section,
483 bool needs_special_offset_handling,
484 unsigned char* view,
485 elfcpp::Elf_types<32>::Elf_Addr address,
486 section_size_type view_size)
487 {
488 typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
489 gold_assert(sh_type == elfcpp::SHT_REL);
490
491 gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
492 Arm_relocate>(
493 relinfo,
494 this,
495 prelocs,
496 reloc_count,
497 output_section,
498 needs_special_offset_handling,
499 view,
500 address,
501 view_size);
502 }
503
504 // Return the size of a relocation while scanning during a relocatable
505 // link.
506
507 template<bool big_endian>
508 unsigned int
509 Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
510 unsigned int r_type,
511 Relobj* object)
512 {
513 r_type = get_real_reloc_type(r_type);
514 switch (r_type)
515 {
516 case elfcpp::R_ARM_NONE:
517 return 0;
518
519 case elfcpp::R_ARM_ABS32:
520 case elfcpp::R_ARM_REL32:
521 case elfcpp::R_ARM_THM_CALL:
522 case elfcpp::R_ARM_GOTOFF32:
523 case elfcpp::R_ARM_BASE_PREL:
524 case elfcpp::R_ARM_GOT_BREL:
525 case elfcpp::R_ARM_PLT32:
526 case elfcpp::R_ARM_CALL:
527 case elfcpp::R_ARM_JUMP24:
528 case elfcpp::R_ARM_PREL31:
529 return 4;
530
531 case elfcpp::R_ARM_TARGET1:
532 // This should have been mapped to another type already.
533 // Fall through.
534 case elfcpp::R_ARM_COPY:
535 case elfcpp::R_ARM_GLOB_DAT:
536 case elfcpp::R_ARM_JUMP_SLOT:
537 case elfcpp::R_ARM_RELATIVE:
538 // These are relocations which should only be seen by the
539 // dynamic linker, and should never be seen here.
540 gold_error(_("%s: unexpected reloc %u in object file"),
541 object->name().c_str(), r_type);
542 return 0;
543
544 default:
545 object->error(_("unsupported reloc %u in object file"), r_type);
546 return 0;
547 }
548 }
549
550 // Scan the relocs during a relocatable link.
551
552 template<bool big_endian>
553 void
554 Target_arm<big_endian>::scan_relocatable_relocs(
555 const General_options& options,
556 Symbol_table* symtab,
557 Layout* layout,
558 Sized_relobj<32, big_endian>* object,
559 unsigned int data_shndx,
560 unsigned int sh_type,
561 const unsigned char* prelocs,
562 size_t reloc_count,
563 Output_section* output_section,
564 bool needs_special_offset_handling,
565 size_t local_symbol_count,
566 const unsigned char* plocal_symbols,
567 Relocatable_relocs* rr)
568 {
569 gold_assert(sh_type == elfcpp::SHT_REL);
570
571 typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
572 Relocatable_size_for_reloc> Scan_relocatable_relocs;
573
574 gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
575 Scan_relocatable_relocs>(
576 options,
577 symtab,
578 layout,
579 object,
580 data_shndx,
581 prelocs,
582 reloc_count,
583 output_section,
584 needs_special_offset_handling,
585 local_symbol_count,
586 plocal_symbols,
587 rr);
588 }
589
590 // Relocate a section during a relocatable link.
591
592 template<bool big_endian>
593 void
594 Target_arm<big_endian>::relocate_for_relocatable(
595 const Relocate_info<32, big_endian>* relinfo,
596 unsigned int sh_type,
597 const unsigned char* prelocs,
598 size_t reloc_count,
599 Output_section* output_section,
600 off_t offset_in_output_section,
601 const Relocatable_relocs* rr,
602 unsigned char* view,
603 elfcpp::Elf_types<32>::Elf_Addr view_address,
604 section_size_type view_size,
605 unsigned char* reloc_view,
606 section_size_type reloc_view_size)
607 {
608 gold_assert(sh_type == elfcpp::SHT_REL);
609
610 gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
611 relinfo,
612 prelocs,
613 reloc_count,
614 output_section,
615 offset_in_output_section,
616 rr,
617 view,
618 view_address,
619 view_size,
620 reloc_view,
621 reloc_view_size);
622 }
623
624 template<bool big_endian>
625 uint64_t
626 Target_arm<big_endian>::do_dynsym_value(const Symbol* /*gsym*/) const
627 {
628 gold_unreachable ();
629 return 0;
630 }
631
632 // Map platform-specific relocs to real relocs
633 //
634 template<bool big_endian>
635 unsigned int
636 Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type)
637 {
638 switch (r_type)
639 {
640 case elfcpp::R_ARM_TARGET1:
641 // This is either R_ARM_ABS32 or R_ARM_REL32;
642 return elfcpp::R_ARM_ABS32;
643
644 case elfcpp::R_ARM_TARGET2:
645 // This can be any reloc type but ususally is R_ARM_GOT_PREL
646 return elfcpp::R_ARM_GOT_PREL;
647
648 default:
649 return r_type;
650 }
651 }
652
653 // The selector for arm object files.
654
655 template<bool big_endian>
656 class Target_selector_arm : public Target_selector
657 {
658 public:
659 Target_selector_arm()
660 : Target_selector(elfcpp::EM_ARM, 32, big_endian,
661 (big_endian ? "elf32-bigarm" : "elf32-littlearm"))
662 { }
663
664 Target*
665 do_instantiate_target()
666 { return new Target_arm<big_endian>(); }
667 };
668
669 Target_selector_arm<false> target_selector_arm;
670 Target_selector_arm<true> target_selector_armbe;
671
672 } // End anonymous namespace.
This page took 0.05532 seconds and 3 git commands to generate.