OSDN Git Service

2009-05-29 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 template<bool big_endian>
52 class Output_data_plt_arm;
53
54 // The arm target class.
55 //
56 // This is a very simple port of gold for ARM-EABI.  It is intended for
57 // supporting Android only for the time being.  Only these relocation types
58 // are supported.
59 //
60 // R_ARM_NONE
61 // R_ARM_ABS32
62 // R_ARM_REL32
63 // R_ARM_THM_CALL
64 // R_ARM_COPY
65 // R_ARM_GLOB_DAT
66 // R_ARM_BASE_PREL
67 // R_ARM_JUMP_SLOT
68 // R_ARM_RELATIVE
69 // R_ARM_GOTOFF32
70 // R_ARM_GOT_BREL
71 // R_ARM_PLT32
72 // R_ARM_CALL
73 // R_ARM_JUMP24
74 // R_ARM_TARGET1
75 // R_ARM_PREL31
76 // 
77 // Coming soon (pending patches):
78 // - Local scanner
79 // - Global scanner
80 // - Relocation
81 // - Defining section symbols __exidx_start and __exidx_stop.
82 // - Support interworking.
83 // - Mergeing all .ARM.xxx.yyy sections into .ARM.xxx.  Currently, they
84 //   are incorrectly merged into an .ARM section.
85 //
86 // TODOs:
87 // - Create a PT_ARM_EXIDX program header for a shared object that
88 //   might throw an exception.
89 // - Support more relocation types as needed. 
90 // - Make PLTs more flexible for different architecture features like
91 //   Thumb-2 and BE8.
92
93 template<bool big_endian>
94 class Target_arm : public Sized_target<32, big_endian>
95 {
96  public:
97   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
98     Reloc_section;
99
100   Target_arm()
101     : Sized_target<32, big_endian>(&arm_info),
102       got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
103       copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL)
104   { }
105
106   // Process the relocations to determine unreferenced sections for 
107   // garbage collection.
108   void
109   gc_process_relocs(const General_options& options,
110                     Symbol_table* symtab,
111                     Layout* layout,
112                     Sized_relobj<32, big_endian>* object,
113                     unsigned int data_shndx,
114                     unsigned int sh_type,
115                     const unsigned char* prelocs,
116                     size_t reloc_count,
117                     Output_section* output_section,
118                     bool needs_special_offset_handling,
119                     size_t local_symbol_count,
120                     const unsigned char* plocal_symbols);
121
122   // Scan the relocations to look for symbol adjustments.
123   void
124   scan_relocs(const General_options& options,
125               Symbol_table* symtab,
126               Layout* layout,
127               Sized_relobj<32, big_endian>* object,
128               unsigned int data_shndx,
129               unsigned int sh_type,
130               const unsigned char* prelocs,
131               size_t reloc_count,
132               Output_section* output_section,
133               bool needs_special_offset_handling,
134               size_t local_symbol_count,
135               const unsigned char* plocal_symbols);
136
137   // Finalize the sections.
138   void
139   do_finalize_sections(Layout*);
140
141   // Return the value to use for a dynamic symbol which requires special
142   // treatment.
143   uint64_t
144   do_dynsym_value(const Symbol*) const;
145
146   // Relocate a section.
147   void
148   relocate_section(const Relocate_info<32, big_endian>*,
149                    unsigned int sh_type,
150                    const unsigned char* prelocs,
151                    size_t reloc_count,
152                    Output_section* output_section,
153                    bool needs_special_offset_handling,
154                    unsigned char* view,
155                    elfcpp::Elf_types<32>::Elf_Addr view_address,
156                    section_size_type view_size);
157
158   // Scan the relocs during a relocatable link.
159   void
160   scan_relocatable_relocs(const General_options& options,
161                           Symbol_table* symtab,
162                           Layout* layout,
163                           Sized_relobj<32, big_endian>* object,
164                           unsigned int data_shndx,
165                           unsigned int sh_type,
166                           const unsigned char* prelocs,
167                           size_t reloc_count,
168                           Output_section* output_section,
169                           bool needs_special_offset_handling,
170                           size_t local_symbol_count,
171                           const unsigned char* plocal_symbols,
172                           Relocatable_relocs*);
173
174   // Relocate a section during a relocatable link.
175   void
176   relocate_for_relocatable(const Relocate_info<32, big_endian>*,
177                            unsigned int sh_type,
178                            const unsigned char* prelocs,
179                            size_t reloc_count,
180                            Output_section* output_section,
181                            off_t offset_in_output_section,
182                            const Relocatable_relocs*,
183                            unsigned char* view,
184                            elfcpp::Elf_types<32>::Elf_Addr view_address,
185                            section_size_type view_size,
186                            unsigned char* reloc_view,
187                            section_size_type reloc_view_size);
188
189   // Return whether SYM is defined by the ABI.
190   bool
191   do_is_defined_by_abi(Symbol* sym) const
192   { return strcmp(sym->name(), "__tls_get_addr") == 0; }
193
194   // Return the size of the GOT section.
195   section_size_type
196   got_size()
197   {
198     gold_assert(this->got_ != NULL);
199     return this->got_->data_size();
200   }
201
202   // Map platform-specific reloc types
203   static unsigned int
204   get_real_reloc_type (unsigned int r_type);
205
206  private:
207   // The class which scans relocations.
208   class Scan
209   {
210    public:
211     Scan()
212     { }
213
214     inline void
215     local(const General_options& options, Symbol_table* symtab,
216           Layout* layout, Target_arm* target,
217           Sized_relobj<32, big_endian>* object,
218           unsigned int data_shndx,
219           Output_section* output_section,
220           const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
221           const elfcpp::Sym<32, big_endian>& lsym);
222
223     inline void
224     global(const General_options& options, Symbol_table* symtab,
225            Layout* layout, Target_arm* target,
226            Sized_relobj<32, big_endian>* object,
227            unsigned int data_shndx,
228            Output_section* output_section,
229            const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
230            Symbol* gsym);
231
232    private:
233     static void
234     unsupported_reloc_local(Sized_relobj<32, big_endian>*,
235                             unsigned int r_type);
236
237     static void
238     unsupported_reloc_global(Sized_relobj<32, big_endian>*,
239                              unsigned int r_type, Symbol*);
240   };
241
242   // The class which implements relocation.
243   class Relocate
244   {
245    public:
246     Relocate()
247     { }
248
249     ~Relocate()
250     { }
251
252     // Do a relocation.  Return false if the caller should not issue
253     // any warnings about this relocation.
254     inline bool
255     relocate(const Relocate_info<32, big_endian>*, Target_arm*,
256              Output_section*,  size_t relnum,
257              const elfcpp::Rel<32, big_endian>&,
258              unsigned int r_type, const Sized_symbol<32>*,
259              const Symbol_value<32>*,
260              unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
261              section_size_type);
262   };
263
264   // A class which returns the size required for a relocation type,
265   // used while scanning relocs during a relocatable link.
266   class Relocatable_size_for_reloc
267   {
268    public:
269     unsigned int
270     get_size_for_reloc(unsigned int, Relobj*);
271   };
272
273   // Get the GOT section, creating it if necessary.
274   Output_data_got<32, big_endian>*
275   got_section(Symbol_table*, Layout*);
276
277   // Get the GOT PLT section.
278   Output_data_space*
279   got_plt_section() const
280   {
281     gold_assert(this->got_plt_ != NULL);
282     return this->got_plt_;
283   }
284
285   // Create a PLT entry for a global symbol.
286   void
287   make_plt_entry(Symbol_table*, Layout*, Symbol*);
288
289   // Get the PLT section.
290   const Output_data_plt_arm<big_endian>*
291   plt_section() const
292   {
293     gold_assert(this->plt_ != NULL);
294     return this->plt_;
295   }
296
297   // Get the dynamic reloc section, creating it if necessary.
298   Reloc_section*
299   rel_dyn_section(Layout*);
300
301   // Return true if the symbol may need a COPY relocation.
302   // References from an executable object to non-function symbols
303   // defined in a dynamic object may need a COPY relocation.
304   bool
305   may_need_copy_reloc(Symbol* gsym)
306   {
307     return (!parameters->options().shared()
308             && gsym->is_from_dynobj()
309             && gsym->type() != elfcpp::STT_FUNC);
310   }
311
312   // Add a potential copy relocation.
313   void
314   copy_reloc(Symbol_table* symtab, Layout* layout,
315              Sized_relobj<32, big_endian>* object,
316              unsigned int shndx, Output_section* output_section,
317              Symbol* sym, const elfcpp::Rel<32, big_endian>& reloc)
318   {
319     this->copy_relocs_.copy_reloc(symtab, layout,
320                                   symtab->get_sized_symbol<32>(sym),
321                                   object, shndx, output_section, reloc,
322                                   this->rel_dyn_section(layout));
323   }
324
325   // Information about this specific target which we pass to the
326   // general Target structure.
327   static const Target::Target_info arm_info;
328
329   // The types of GOT entries needed for this platform.
330   enum Got_type
331   {
332     GOT_TYPE_STANDARD = 0       // GOT entry for a regular symbol
333   };
334
335   // The GOT section.
336   Output_data_got<32, big_endian>* got_;
337   // The PLT section.
338   Output_data_plt_arm<big_endian>* plt_;
339   // The GOT PLT section.
340   Output_data_space* got_plt_;
341   // The dynamic reloc section.
342   Reloc_section* rel_dyn_;
343   // Relocs saved to avoid a COPY reloc.
344   Copy_relocs<elfcpp::SHT_REL, 32, big_endian> copy_relocs_;
345   // Space for variables copied with a COPY reloc.
346   Output_data_space* dynbss_;
347 };
348
349 template<bool big_endian>
350 const Target::Target_info Target_arm<big_endian>::arm_info =
351 {
352   32,                   // size
353   big_endian,           // is_big_endian
354   elfcpp::EM_ARM,       // machine_code
355   false,                // has_make_symbol
356   false,                // has_resolve
357   false,                // has_code_fill
358   true,                 // is_default_stack_executable
359   '\0',                 // wrap_char
360   "/usr/lib/libc.so.1", // dynamic_linker
361   0x8000,               // default_text_segment_address
362   0x1000,               // abi_pagesize (overridable by -z max-page-size)
363   0x1000                // common_pagesize (overridable by -z common-page-size)
364 };
365
366 // Get the GOT section, creating it if necessary.
367
368 template<bool big_endian>
369 Output_data_got<32, big_endian>*
370 Target_arm<big_endian>::got_section(Symbol_table* symtab, Layout* layout)
371 {
372   if (this->got_ == NULL)
373     {
374       gold_assert(symtab != NULL && layout != NULL);
375
376       this->got_ = new Output_data_got<32, big_endian>();
377
378       Output_section* os;
379       os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
380                                            (elfcpp::SHF_ALLOC
381                                             | elfcpp::SHF_WRITE),
382                                            this->got_);
383       os->set_is_relro();
384
385       // The old GNU linker creates a .got.plt section.  We just
386       // create another set of data in the .got section.  Note that we
387       // always create a PLT if we create a GOT, although the PLT
388       // might be empty.
389       this->got_plt_ = new Output_data_space(4, "** GOT PLT");
390       os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
391                                            (elfcpp::SHF_ALLOC
392                                             | elfcpp::SHF_WRITE),
393                                            this->got_plt_);
394       os->set_is_relro();
395
396       // The first three entries are reserved.
397       this->got_plt_->set_current_data_size(3 * 4);
398
399       // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
400       symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
401                                     this->got_plt_,
402                                     0, 0, elfcpp::STT_OBJECT,
403                                     elfcpp::STB_LOCAL,
404                                     elfcpp::STV_HIDDEN, 0,
405                                     false, false);
406     }
407   return this->got_;
408 }
409
410 // Get the dynamic reloc section, creating it if necessary.
411
412 template<bool big_endian>
413 typename Target_arm<big_endian>::Reloc_section*
414 Target_arm<big_endian>::rel_dyn_section(Layout* layout)
415 {
416   if (this->rel_dyn_ == NULL)
417     {
418       gold_assert(layout != NULL);
419       this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
420       layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
421                                       elfcpp::SHF_ALLOC, this->rel_dyn_);
422     }
423   return this->rel_dyn_;
424 }
425
426 // A class to handle the PLT data.
427
428 template<bool big_endian>
429 class Output_data_plt_arm : public Output_section_data
430 {
431  public:
432   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
433     Reloc_section;
434
435   Output_data_plt_arm(Layout*, Output_data_space*);
436
437   // Add an entry to the PLT.
438   void
439   add_entry(Symbol* gsym);
440
441   // Return the .rel.plt section data.
442   const Reloc_section*
443   rel_plt() const
444   { return this->rel_; }
445
446  protected:
447   void
448   do_adjust_output_section(Output_section* os);
449
450   // Write to a map file.
451   void
452   do_print_to_mapfile(Mapfile* mapfile) const
453   { mapfile->print_output_data(this, _("** PLT")); }
454
455  private:
456   // Template for the first PLT entry.
457   static const uint32_t first_plt_entry[5];
458
459   // Template for subsequent PLT entries. 
460   static const uint32_t plt_entry[3];
461
462   // Set the final size.
463   void
464   set_final_data_size()
465   {
466     this->set_data_size(sizeof(first_plt_entry)
467                         + this->count_ * sizeof(plt_entry));
468   }
469
470   // Write out the PLT data.
471   void
472   do_write(Output_file*);
473
474   // The reloc section.
475   Reloc_section* rel_;
476   // The .got.plt section.
477   Output_data_space* got_plt_;
478   // The number of PLT entries.
479   unsigned int count_;
480 };
481
482 // Create the PLT section.  The ordinary .got section is an argument,
483 // since we need to refer to the start.  We also create our own .got
484 // section just for PLT entries.
485
486 template<bool big_endian>
487 Output_data_plt_arm<big_endian>::Output_data_plt_arm(Layout* layout,
488                                                      Output_data_space* got_plt)
489   : Output_section_data(4), got_plt_(got_plt), count_(0)
490 {
491   this->rel_ = new Reloc_section(false);
492   layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
493                                   elfcpp::SHF_ALLOC, this->rel_);
494 }
495
496 template<bool big_endian>
497 void
498 Output_data_plt_arm<big_endian>::do_adjust_output_section(Output_section* os)
499 {
500   os->set_entsize(0);
501 }
502
503 // Add an entry to the PLT.
504
505 template<bool big_endian>
506 void
507 Output_data_plt_arm<big_endian>::add_entry(Symbol* gsym)
508 {
509   gold_assert(!gsym->has_plt_offset());
510
511   // Note that when setting the PLT offset we skip the initial
512   // reserved PLT entry.
513   gsym->set_plt_offset((this->count_) * sizeof(plt_entry)
514                        + sizeof(first_plt_entry));
515
516   ++this->count_;
517
518   section_offset_type got_offset = this->got_plt_->current_data_size();
519
520   // Every PLT entry needs a GOT entry which points back to the PLT
521   // entry (this will be changed by the dynamic linker, normally
522   // lazily when the function is called).
523   this->got_plt_->set_current_data_size(got_offset + 4);
524
525   // Every PLT entry needs a reloc.
526   gsym->set_needs_dynsym_entry();
527   this->rel_->add_global(gsym, elfcpp::R_ARM_JUMP_SLOT, this->got_plt_,
528                          got_offset);
529
530   // Note that we don't need to save the symbol.  The contents of the
531   // PLT are independent of which symbols are used.  The symbols only
532   // appear in the relocations.
533 }
534
535 // ARM PLTs.
536 // FIXME:  This is not very flexible.  Right now this has only been tested
537 // on armv5te.  If we are to support additional architecture features like
538 // Thumb-2 or BE8, we need to make this more flexible like GNU ld.
539
540 // The first entry in the PLT.
541 template<bool big_endian>
542 const uint32_t Output_data_plt_arm<big_endian>::first_plt_entry[5] =
543 {
544   0xe52de004,   // str   lr, [sp, #-4]!
545   0xe59fe004,   // ldr   lr, [pc, #4]
546   0xe08fe00e,   // add   lr, pc, lr 
547   0xe5bef008,   // ldr   pc, [lr, #8]!
548   0x00000000,   // &GOT[0] - .
549 };
550
551 // Subsequent entries in the PLT.
552
553 template<bool big_endian>
554 const uint32_t Output_data_plt_arm<big_endian>::plt_entry[3] =
555 {
556   0xe28fc600,   // add   ip, pc, #0xNN00000
557   0xe28cca00,   // add   ip, ip, #0xNN000
558   0xe5bcf000,   // ldr   pc, [ip, #0xNNN]!
559 };
560
561 // Write out the PLT.  This uses the hand-coded instructions above,
562 // and adjusts them as needed.  This is all specified by the arm ELF
563 // Processor Supplement.
564
565 template<bool big_endian>
566 void
567 Output_data_plt_arm<big_endian>::do_write(Output_file* of)
568 {
569   const off_t offset = this->offset();
570   const section_size_type oview_size =
571     convert_to_section_size_type(this->data_size());
572   unsigned char* const oview = of->get_output_view(offset, oview_size);
573
574   const off_t got_file_offset = this->got_plt_->offset();
575   const section_size_type got_size =
576     convert_to_section_size_type(this->got_plt_->data_size());
577   unsigned char* const got_view = of->get_output_view(got_file_offset,
578                                                       got_size);
579   unsigned char* pov = oview;
580
581   elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
582   elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();
583
584   // Write first PLT entry.  All but the last word are constants.
585   const size_t num_first_plt_words = (sizeof(first_plt_entry)
586                                       / sizeof(plt_entry[0]));
587   for (size_t i = 0; i < num_first_plt_words - 1; i++)
588     elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
589   // Last word in first PLT entry is &GOT[0] - .
590   elfcpp::Swap<32, big_endian>::writeval(pov + 16,
591                                          got_address - (plt_address + 16));
592   pov += sizeof(first_plt_entry);
593
594   unsigned char* got_pov = got_view;
595
596   memset(got_pov, 0, 12);
597   got_pov += 12;
598
599   const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
600   unsigned int plt_offset = sizeof(first_plt_entry);
601   unsigned int plt_rel_offset = 0;
602   unsigned int got_offset = 12;
603   const unsigned int count = this->count_;
604   for (unsigned int i = 0;
605        i < count;
606        ++i,
607          pov += sizeof(plt_entry),
608          got_pov += 4,
609          plt_offset += sizeof(plt_entry),
610          plt_rel_offset += rel_size,
611          got_offset += 4)
612     {
613       // Set and adjust the PLT entry itself.
614       int32_t offset = ((got_address + got_offset)
615                          - (plt_address + plt_offset + 8));
616
617       gold_assert(offset >= 0 && offset < 0x0fffffff);
618       uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff);
619       elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
620       uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff);
621       elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1);
622       uint32_t plt_insn2 = plt_entry[2] | (offset & 0xfff);
623       elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
624
625       // Set the entry in the GOT.
626       elfcpp::Swap<32, big_endian>::writeval(got_pov, plt_address);
627     }
628
629   gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
630   gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
631
632   of->write_output_view(offset, oview_size, oview);
633   of->write_output_view(got_file_offset, got_size, got_view);
634 }
635
636 // Create a PLT entry for a global symbol.
637
638 template<bool big_endian>
639 void
640 Target_arm<big_endian>::make_plt_entry(Symbol_table* symtab, Layout* layout,
641                                        Symbol* gsym)
642 {
643   if (gsym->has_plt_offset())
644     return;
645
646   if (this->plt_ == NULL)
647     {
648       // Create the GOT sections first.
649       this->got_section(symtab, layout);
650
651       this->plt_ = new Output_data_plt_arm<big_endian>(layout, this->got_plt_);
652       layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
653                                       (elfcpp::SHF_ALLOC
654                                        | elfcpp::SHF_EXECINSTR),
655                                       this->plt_);
656     }
657   this->plt_->add_entry(gsym);
658 }
659
660 // Report an unsupported relocation against a local symbol.
661
662 template<bool big_endian>
663 void
664 Target_arm<big_endian>::Scan::unsupported_reloc_local(
665     Sized_relobj<32, big_endian>* object,
666     unsigned int r_type)
667 {
668   gold_error(_("%s: unsupported reloc %u against local symbol"),
669              object->name().c_str(), r_type);
670 }
671
672 // Scan a relocation for a local symbol.
673
674 template<bool big_endian>
675 inline void
676 Target_arm<big_endian>::Scan::local(const General_options&,
677                                     Symbol_table* /* symtab */,
678                                     Layout* /* layout */,
679                                     Target_arm* /* target */,
680                                     Sized_relobj<32, big_endian>* object,
681                                     unsigned int /* data_shndx */,
682                                     Output_section* /* output_section */,
683                                     const elfcpp::Rel<32, big_endian>& /* reloc */,
684                                     unsigned int r_type,
685                                     const elfcpp::Sym<32, big_endian>&)
686 {
687   r_type = get_real_reloc_type(r_type);
688   switch (r_type)
689     {
690     case elfcpp::R_ARM_NONE:
691       break;
692
693     default:
694       unsupported_reloc_local(object, r_type);
695       break;
696     }
697 }
698
699 // Report an unsupported relocation against a global symbol.
700
701 template<bool big_endian>
702 void
703 Target_arm<big_endian>::Scan::unsupported_reloc_global(
704     Sized_relobj<32, big_endian>* object,
705     unsigned int r_type,
706     Symbol* gsym)
707 {
708   gold_error(_("%s: unsupported reloc %u against global symbol %s"),
709              object->name().c_str(), r_type, gsym->demangled_name().c_str());
710 }
711
712 // Scan a relocation for a global symbol.
713
714 template<bool big_endian>
715 inline void
716 Target_arm<big_endian>::Scan::global(const General_options&,
717                                      Symbol_table* /* symtab */,
718                                      Layout* /* layout */,
719                                      Target_arm* /* target */,
720                                      Sized_relobj<32, big_endian>* object,
721                                      unsigned int /* data_shndx */,
722                                      Output_section* /* output_section */,
723                                      const elfcpp::Rel<32, big_endian>& /* reloc */,
724                                      unsigned int r_type,
725                                      Symbol* gsym)
726 {
727   r_type = get_real_reloc_type(r_type);
728   switch (r_type)
729     {
730     case elfcpp::R_ARM_NONE:
731       break;
732
733     default:
734       unsupported_reloc_global(object, r_type, gsym);
735       break;
736     }
737 }
738
739 // Process relocations for gc.
740
741 template<bool big_endian>
742 void
743 Target_arm<big_endian>::gc_process_relocs(const General_options& options,
744                                           Symbol_table* symtab,
745                                           Layout* layout,
746                                           Sized_relobj<32, big_endian>* object,
747                                           unsigned int data_shndx,
748                                           unsigned int,
749                                           const unsigned char* prelocs,
750                                           size_t reloc_count,
751                                           Output_section* output_section,
752                                           bool needs_special_offset_handling,
753                                           size_t local_symbol_count,
754                                           const unsigned char* plocal_symbols)
755 {
756   typedef Target_arm<big_endian> Arm;
757   typedef typename Target_arm<big_endian>::Scan Scan;
758
759   gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan>(
760     options,
761     symtab,
762     layout,
763     this,
764     object,
765     data_shndx,
766     prelocs,
767     reloc_count,
768     output_section,
769     needs_special_offset_handling,
770     local_symbol_count,
771     plocal_symbols);
772 }
773
774 // Scan relocations for a section.
775
776 template<bool big_endian>
777 void
778 Target_arm<big_endian>::scan_relocs(const General_options& options,
779                                     Symbol_table* symtab,
780                                     Layout* layout,
781                                     Sized_relobj<32, big_endian>* object,
782                                     unsigned int data_shndx,
783                                     unsigned int sh_type,
784                                     const unsigned char* prelocs,
785                                     size_t reloc_count,
786                                     Output_section* output_section,
787                                     bool needs_special_offset_handling,
788                                     size_t local_symbol_count,
789                                     const unsigned char* plocal_symbols)
790 {
791   typedef typename Target_arm<big_endian>::Scan Scan;
792   if (sh_type == elfcpp::SHT_RELA)
793     {
794       gold_error(_("%s: unsupported RELA reloc section"),
795                  object->name().c_str());
796       return;
797     }
798
799   gold::scan_relocs<32, big_endian, Target_arm, elfcpp::SHT_REL, Scan>(
800     options,
801     symtab,
802     layout,
803     this,
804     object,
805     data_shndx,
806     prelocs,
807     reloc_count,
808     output_section,
809     needs_special_offset_handling,
810     local_symbol_count,
811     plocal_symbols);
812 }
813
814 // Finalize the sections.
815
816 template<bool big_endian>
817 void
818 Target_arm<big_endian>::do_finalize_sections(Layout* layout)
819 {
820   // Fill in some more dynamic tags.
821   Output_data_dynamic* const odyn = layout->dynamic_data();
822   if (odyn != NULL)
823     {
824       if (this->got_plt_ != NULL)
825         odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
826
827       if (this->plt_ != NULL)
828         {
829           const Output_data* od = this->plt_->rel_plt();
830           odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
831           odyn->add_section_address(elfcpp::DT_JMPREL, od);
832           odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL);
833         }
834
835       if (this->rel_dyn_ != NULL)
836         {
837           const Output_data* od = this->rel_dyn_;
838           odyn->add_section_address(elfcpp::DT_REL, od);
839           odyn->add_section_size(elfcpp::DT_RELSZ, od);
840           odyn->add_constant(elfcpp::DT_RELENT,
841                              elfcpp::Elf_sizes<32>::rel_size);
842         }
843
844       if (!parameters->options().shared())
845         {
846           // The value of the DT_DEBUG tag is filled in by the dynamic
847           // linker at run time, and used by the debugger.
848           odyn->add_constant(elfcpp::DT_DEBUG, 0);
849         }
850     }
851
852   // Emit any relocs we saved in an attempt to avoid generating COPY
853   // relocs.
854   if (this->copy_relocs_.any_saved_relocs())
855     this->copy_relocs_.emit(this->rel_dyn_section(layout));
856 }
857
858 // Perform a relocation.
859
860 template<bool big_endian>
861 inline bool
862 Target_arm<big_endian>::Relocate::relocate(
863     const Relocate_info<32, big_endian>* /* relinfo */,
864     Target_arm* /* target */,
865     Output_section* /* output_section */,
866     size_t /* relnum */,
867     const elfcpp::Rel<32, big_endian>& /* rel */,
868     unsigned int r_type,
869     const Sized_symbol<32>* /* gsym */,
870     const Symbol_value<32>* /* psymval */,
871     unsigned char* /* view */,
872     elfcpp::Elf_types<32>::Elf_Addr /* address */,
873     section_size_type /* view_size */ )
874 {
875   switch (r_type)
876     {
877     case elfcpp::R_ARM_NONE:
878       break;
879
880     default:
881       gold_unreachable();
882     }
883
884   return true;
885 }
886
887 // Relocate section data.
888
889 template<bool big_endian>
890 void
891 Target_arm<big_endian>::relocate_section(
892     const Relocate_info<32, big_endian>* relinfo,
893     unsigned int sh_type,
894     const unsigned char* prelocs,
895     size_t reloc_count,
896     Output_section* output_section,
897     bool needs_special_offset_handling,
898     unsigned char* view,
899     elfcpp::Elf_types<32>::Elf_Addr address,
900     section_size_type view_size)
901 {
902   typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
903   gold_assert(sh_type == elfcpp::SHT_REL);
904
905   gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
906                          Arm_relocate>(
907     relinfo,
908     this,
909     prelocs,
910     reloc_count,
911     output_section,
912     needs_special_offset_handling,
913     view,
914     address,
915     view_size);
916 }
917
918 // Return the size of a relocation while scanning during a relocatable
919 // link.
920
921 template<bool big_endian>
922 unsigned int
923 Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
924     unsigned int r_type,
925     Relobj* object)
926 {
927   r_type = get_real_reloc_type(r_type);
928   switch (r_type)
929     {
930     case elfcpp::R_ARM_NONE:
931       return 0;
932
933     case elfcpp::R_ARM_ABS32:
934     case elfcpp::R_ARM_REL32:
935     case elfcpp::R_ARM_THM_CALL:
936     case elfcpp::R_ARM_GOTOFF32:
937     case elfcpp::R_ARM_BASE_PREL:
938     case elfcpp::R_ARM_GOT_BREL:
939     case elfcpp::R_ARM_PLT32:
940     case elfcpp::R_ARM_CALL:
941     case elfcpp::R_ARM_JUMP24:
942     case elfcpp::R_ARM_PREL31:
943       return 4;
944
945     case elfcpp::R_ARM_TARGET1:
946       // This should have been mapped to another type already.
947       // Fall through.
948     case elfcpp::R_ARM_COPY:
949     case elfcpp::R_ARM_GLOB_DAT:
950     case elfcpp::R_ARM_JUMP_SLOT:
951     case elfcpp::R_ARM_RELATIVE:
952       // These are relocations which should only be seen by the
953       // dynamic linker, and should never be seen here.
954       gold_error(_("%s: unexpected reloc %u in object file"),
955                  object->name().c_str(), r_type);
956       return 0;
957
958     default:
959       object->error(_("unsupported reloc %u in object file"), r_type);
960       return 0;
961     }
962 }
963
964 // Scan the relocs during a relocatable link.
965
966 template<bool big_endian>
967 void
968 Target_arm<big_endian>::scan_relocatable_relocs(
969     const General_options& options,
970     Symbol_table* symtab,
971     Layout* layout,
972     Sized_relobj<32, big_endian>* object,
973     unsigned int data_shndx,
974     unsigned int sh_type,
975     const unsigned char* prelocs,
976     size_t reloc_count,
977     Output_section* output_section,
978     bool needs_special_offset_handling,
979     size_t local_symbol_count,
980     const unsigned char* plocal_symbols,
981     Relocatable_relocs* rr)
982 {
983   gold_assert(sh_type == elfcpp::SHT_REL);
984
985   typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
986     Relocatable_size_for_reloc> Scan_relocatable_relocs;
987
988   gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
989       Scan_relocatable_relocs>(
990     options,
991     symtab,
992     layout,
993     object,
994     data_shndx,
995     prelocs,
996     reloc_count,
997     output_section,
998     needs_special_offset_handling,
999     local_symbol_count,
1000     plocal_symbols,
1001     rr);
1002 }
1003
1004 // Relocate a section during a relocatable link.
1005
1006 template<bool big_endian>
1007 void
1008 Target_arm<big_endian>::relocate_for_relocatable(
1009     const Relocate_info<32, big_endian>* relinfo,
1010     unsigned int sh_type,
1011     const unsigned char* prelocs,
1012     size_t reloc_count,
1013     Output_section* output_section,
1014     off_t offset_in_output_section,
1015     const Relocatable_relocs* rr,
1016     unsigned char* view,
1017     elfcpp::Elf_types<32>::Elf_Addr view_address,
1018     section_size_type view_size,
1019     unsigned char* reloc_view,
1020     section_size_type reloc_view_size)
1021 {
1022   gold_assert(sh_type == elfcpp::SHT_REL);
1023
1024   gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
1025     relinfo,
1026     prelocs,
1027     reloc_count,
1028     output_section,
1029     offset_in_output_section,
1030     rr,
1031     view,
1032     view_address,
1033     view_size,
1034     reloc_view,
1035     reloc_view_size);
1036 }
1037
1038 // Return the value to use for a dynamic symbol which requires special
1039 // treatment.  This is how we support equality comparisons of function
1040 // pointers across shared library boundaries, as described in the
1041 // processor specific ABI supplement.
1042
1043 template<bool big_endian>
1044 uint64_t
1045 Target_arm<big_endian>::do_dynsym_value(const Symbol* gsym) const
1046 {
1047   gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
1048   return this->plt_section()->address() + gsym->plt_offset();
1049 }
1050
1051 // Map platform-specific relocs to real relocs
1052 //
1053 template<bool big_endian>
1054 unsigned int
1055 Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type)
1056 {
1057   switch (r_type)
1058     {
1059     case elfcpp::R_ARM_TARGET1:
1060       // This is either R_ARM_ABS32 or R_ARM_REL32;
1061       return elfcpp::R_ARM_ABS32;
1062
1063     case elfcpp::R_ARM_TARGET2:
1064       // This can be any reloc type but ususally is R_ARM_GOT_PREL
1065       return elfcpp::R_ARM_GOT_PREL;
1066
1067     default:
1068       return r_type;
1069     }
1070 }
1071
1072 // The selector for arm object files.
1073
1074 template<bool big_endian>
1075 class Target_selector_arm : public Target_selector
1076 {
1077  public:
1078   Target_selector_arm()
1079     : Target_selector(elfcpp::EM_ARM, 32, big_endian,
1080                       (big_endian ? "elf32-bigarm" : "elf32-littlearm"))
1081   { }
1082
1083   Target*
1084   do_instantiate_target()
1085   { return new Target_arm<big_endian>(); }
1086 };
1087
1088 Target_selector_arm<false> target_selector_arm;
1089 Target_selector_arm<true> target_selector_armbe;
1090
1091 } // End anonymous namespace.