OSDN Git Service

2009-05-28 Doug Kwan <dougkwan@google.com>
[pf3gnuchains/pf3gnuchains3x.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.