OSDN Git Service

2009-06-02 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 // - 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 // - Make PLTs more flexible for different architecture features like
89 //   Thumb-2 and BE8.
90
91 template<bool big_endian>
92 class Target_arm : public Sized_target<32, big_endian>
93 {
94  public:
95   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
96     Reloc_section;
97
98   Target_arm()
99     : Sized_target<32, big_endian>(&arm_info),
100       got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
101       copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL)
102   { }
103
104   // Process the relocations to determine unreferenced sections for 
105   // garbage collection.
106   void
107   gc_process_relocs(const General_options& options,
108                     Symbol_table* symtab,
109                     Layout* layout,
110                     Sized_relobj<32, big_endian>* object,
111                     unsigned int data_shndx,
112                     unsigned int sh_type,
113                     const unsigned char* prelocs,
114                     size_t reloc_count,
115                     Output_section* output_section,
116                     bool needs_special_offset_handling,
117                     size_t local_symbol_count,
118                     const unsigned char* plocal_symbols);
119
120   // Scan the relocations to look for symbol adjustments.
121   void
122   scan_relocs(const General_options& options,
123               Symbol_table* symtab,
124               Layout* layout,
125               Sized_relobj<32, big_endian>* object,
126               unsigned int data_shndx,
127               unsigned int sh_type,
128               const unsigned char* prelocs,
129               size_t reloc_count,
130               Output_section* output_section,
131               bool needs_special_offset_handling,
132               size_t local_symbol_count,
133               const unsigned char* plocal_symbols);
134
135   // Finalize the sections.
136   void
137   do_finalize_sections(Layout*);
138
139   // Return the value to use for a dynamic symbol which requires special
140   // treatment.
141   uint64_t
142   do_dynsym_value(const Symbol*) const;
143
144   // Relocate a section.
145   void
146   relocate_section(const Relocate_info<32, big_endian>*,
147                    unsigned int sh_type,
148                    const unsigned char* prelocs,
149                    size_t reloc_count,
150                    Output_section* output_section,
151                    bool needs_special_offset_handling,
152                    unsigned char* view,
153                    elfcpp::Elf_types<32>::Elf_Addr view_address,
154                    section_size_type view_size);
155
156   // Scan the relocs during a relocatable link.
157   void
158   scan_relocatable_relocs(const General_options& options,
159                           Symbol_table* symtab,
160                           Layout* layout,
161                           Sized_relobj<32, big_endian>* object,
162                           unsigned int data_shndx,
163                           unsigned int sh_type,
164                           const unsigned char* prelocs,
165                           size_t reloc_count,
166                           Output_section* output_section,
167                           bool needs_special_offset_handling,
168                           size_t local_symbol_count,
169                           const unsigned char* plocal_symbols,
170                           Relocatable_relocs*);
171
172   // Relocate a section during a relocatable link.
173   void
174   relocate_for_relocatable(const Relocate_info<32, big_endian>*,
175                            unsigned int sh_type,
176                            const unsigned char* prelocs,
177                            size_t reloc_count,
178                            Output_section* output_section,
179                            off_t offset_in_output_section,
180                            const Relocatable_relocs*,
181                            unsigned char* view,
182                            elfcpp::Elf_types<32>::Elf_Addr view_address,
183                            section_size_type view_size,
184                            unsigned char* reloc_view,
185                            section_size_type reloc_view_size);
186
187   // Return whether SYM is defined by the ABI.
188   bool
189   do_is_defined_by_abi(Symbol* sym) const
190   { return strcmp(sym->name(), "__tls_get_addr") == 0; }
191
192   // Return the size of the GOT section.
193   section_size_type
194   got_size()
195   {
196     gold_assert(this->got_ != NULL);
197     return this->got_->data_size();
198   }
199
200   // Map platform-specific reloc types
201   static unsigned int
202   get_real_reloc_type (unsigned int r_type);
203
204  private:
205   // The class which scans relocations.
206   class Scan
207   {
208    public:
209     Scan()
210       : issued_non_pic_error_(false)
211     { }
212
213     inline void
214     local(const General_options& options, Symbol_table* symtab,
215           Layout* layout, Target_arm* target,
216           Sized_relobj<32, big_endian>* object,
217           unsigned int data_shndx,
218           Output_section* output_section,
219           const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
220           const elfcpp::Sym<32, big_endian>& lsym);
221
222     inline void
223     global(const General_options& options, Symbol_table* symtab,
224            Layout* layout, Target_arm* target,
225            Sized_relobj<32, big_endian>* object,
226            unsigned int data_shndx,
227            Output_section* output_section,
228            const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
229            Symbol* gsym);
230
231    private:
232     static void
233     unsupported_reloc_local(Sized_relobj<32, big_endian>*,
234                             unsigned int r_type);
235
236     static void
237     unsupported_reloc_global(Sized_relobj<32, big_endian>*,
238                              unsigned int r_type, Symbol*);
239
240     void
241     check_non_pic(Relobj*, unsigned int r_type);
242
243     // Almost identical to Symbol::needs_plt_entry except that it also
244     // handles STT_ARM_TFUNC.
245     static bool
246     symbol_needs_plt_entry(const Symbol* sym)
247     {
248       // An undefined symbol from an executable does not need a PLT entry.
249       if (sym->is_undefined() && !parameters->options().shared())
250         return false;
251
252       return (!parameters->doing_static_link()
253               && (sym->type() == elfcpp::STT_FUNC
254                   || sym->type() == elfcpp::STT_ARM_TFUNC)
255               && (sym->is_from_dynobj()
256                   || sym->is_undefined()
257                   || sym->is_preemptible()));
258     }
259
260     // Whether we have issued an error about a non-PIC compilation.
261     bool issued_non_pic_error_;
262   };
263
264   // The class which implements relocation.
265   class Relocate
266   {
267    public:
268     Relocate()
269     { }
270
271     ~Relocate()
272     { }
273
274     // Return whether the static relocation needs to be applied.
275     inline bool
276     should_apply_static_reloc(const Sized_symbol<32>* gsym,
277                               int ref_flags,
278                               bool is_32bit,
279                               Output_section* output_section);
280
281     // Do a relocation.  Return false if the caller should not issue
282     // any warnings about this relocation.
283     inline bool
284     relocate(const Relocate_info<32, big_endian>*, Target_arm*,
285              Output_section*,  size_t relnum,
286              const elfcpp::Rel<32, big_endian>&,
287              unsigned int r_type, const Sized_symbol<32>*,
288              const Symbol_value<32>*,
289              unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
290              section_size_type);
291   };
292
293   // A class which returns the size required for a relocation type,
294   // used while scanning relocs during a relocatable link.
295   class Relocatable_size_for_reloc
296   {
297    public:
298     unsigned int
299     get_size_for_reloc(unsigned int, Relobj*);
300   };
301
302   // Get the GOT section, creating it if necessary.
303   Output_data_got<32, big_endian>*
304   got_section(Symbol_table*, Layout*);
305
306   // Get the GOT PLT section.
307   Output_data_space*
308   got_plt_section() const
309   {
310     gold_assert(this->got_plt_ != NULL);
311     return this->got_plt_;
312   }
313
314   // Create a PLT entry for a global symbol.
315   void
316   make_plt_entry(Symbol_table*, Layout*, Symbol*);
317
318   // Get the PLT section.
319   const Output_data_plt_arm<big_endian>*
320   plt_section() const
321   {
322     gold_assert(this->plt_ != NULL);
323     return this->plt_;
324   }
325
326   // Get the dynamic reloc section, creating it if necessary.
327   Reloc_section*
328   rel_dyn_section(Layout*);
329
330   // Return true if the symbol may need a COPY relocation.
331   // References from an executable object to non-function symbols
332   // defined in a dynamic object may need a COPY relocation.
333   bool
334   may_need_copy_reloc(Symbol* gsym)
335   {
336     return (!parameters->options().shared()
337             && gsym->is_from_dynobj()
338             && gsym->type() != elfcpp::STT_FUNC
339             && gsym->type() != elfcpp::STT_ARM_TFUNC);
340   }
341
342   // Add a potential copy relocation.
343   void
344   copy_reloc(Symbol_table* symtab, Layout* layout,
345              Sized_relobj<32, big_endian>* object,
346              unsigned int shndx, Output_section* output_section,
347              Symbol* sym, const elfcpp::Rel<32, big_endian>& reloc)
348   {
349     this->copy_relocs_.copy_reloc(symtab, layout,
350                                   symtab->get_sized_symbol<32>(sym),
351                                   object, shndx, output_section, reloc,
352                                   this->rel_dyn_section(layout));
353   }
354
355   // Information about this specific target which we pass to the
356   // general Target structure.
357   static const Target::Target_info arm_info;
358
359   // The types of GOT entries needed for this platform.
360   enum Got_type
361   {
362     GOT_TYPE_STANDARD = 0       // GOT entry for a regular symbol
363   };
364
365   // The GOT section.
366   Output_data_got<32, big_endian>* got_;
367   // The PLT section.
368   Output_data_plt_arm<big_endian>* plt_;
369   // The GOT PLT section.
370   Output_data_space* got_plt_;
371   // The dynamic reloc section.
372   Reloc_section* rel_dyn_;
373   // Relocs saved to avoid a COPY reloc.
374   Copy_relocs<elfcpp::SHT_REL, 32, big_endian> copy_relocs_;
375   // Space for variables copied with a COPY reloc.
376   Output_data_space* dynbss_;
377 };
378
379 template<bool big_endian>
380 const Target::Target_info Target_arm<big_endian>::arm_info =
381 {
382   32,                   // size
383   big_endian,           // is_big_endian
384   elfcpp::EM_ARM,       // machine_code
385   false,                // has_make_symbol
386   false,                // has_resolve
387   false,                // has_code_fill
388   true,                 // is_default_stack_executable
389   '\0',                 // wrap_char
390   "/usr/lib/libc.so.1", // dynamic_linker
391   0x8000,               // default_text_segment_address
392   0x1000,               // abi_pagesize (overridable by -z max-page-size)
393   0x1000                // common_pagesize (overridable by -z common-page-size)
394 };
395
396 // Get the GOT section, creating it if necessary.
397
398 template<bool big_endian>
399 Output_data_got<32, big_endian>*
400 Target_arm<big_endian>::got_section(Symbol_table* symtab, Layout* layout)
401 {
402   if (this->got_ == NULL)
403     {
404       gold_assert(symtab != NULL && layout != NULL);
405
406       this->got_ = new Output_data_got<32, big_endian>();
407
408       Output_section* os;
409       os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
410                                            (elfcpp::SHF_ALLOC
411                                             | elfcpp::SHF_WRITE),
412                                            this->got_);
413       os->set_is_relro();
414
415       // The old GNU linker creates a .got.plt section.  We just
416       // create another set of data in the .got section.  Note that we
417       // always create a PLT if we create a GOT, although the PLT
418       // might be empty.
419       this->got_plt_ = new Output_data_space(4, "** GOT PLT");
420       os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
421                                            (elfcpp::SHF_ALLOC
422                                             | elfcpp::SHF_WRITE),
423                                            this->got_plt_);
424       os->set_is_relro();
425
426       // The first three entries are reserved.
427       this->got_plt_->set_current_data_size(3 * 4);
428
429       // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
430       symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
431                                     this->got_plt_,
432                                     0, 0, elfcpp::STT_OBJECT,
433                                     elfcpp::STB_LOCAL,
434                                     elfcpp::STV_HIDDEN, 0,
435                                     false, false);
436     }
437   return this->got_;
438 }
439
440 // Get the dynamic reloc section, creating it if necessary.
441
442 template<bool big_endian>
443 typename Target_arm<big_endian>::Reloc_section*
444 Target_arm<big_endian>::rel_dyn_section(Layout* layout)
445 {
446   if (this->rel_dyn_ == NULL)
447     {
448       gold_assert(layout != NULL);
449       this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
450       layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
451                                       elfcpp::SHF_ALLOC, this->rel_dyn_);
452     }
453   return this->rel_dyn_;
454 }
455
456 // A class to handle the PLT data.
457
458 template<bool big_endian>
459 class Output_data_plt_arm : public Output_section_data
460 {
461  public:
462   typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
463     Reloc_section;
464
465   Output_data_plt_arm(Layout*, Output_data_space*);
466
467   // Add an entry to the PLT.
468   void
469   add_entry(Symbol* gsym);
470
471   // Return the .rel.plt section data.
472   const Reloc_section*
473   rel_plt() const
474   { return this->rel_; }
475
476  protected:
477   void
478   do_adjust_output_section(Output_section* os);
479
480   // Write to a map file.
481   void
482   do_print_to_mapfile(Mapfile* mapfile) const
483   { mapfile->print_output_data(this, _("** PLT")); }
484
485  private:
486   // Template for the first PLT entry.
487   static const uint32_t first_plt_entry[5];
488
489   // Template for subsequent PLT entries. 
490   static const uint32_t plt_entry[3];
491
492   // Set the final size.
493   void
494   set_final_data_size()
495   {
496     this->set_data_size(sizeof(first_plt_entry)
497                         + this->count_ * sizeof(plt_entry));
498   }
499
500   // Write out the PLT data.
501   void
502   do_write(Output_file*);
503
504   // The reloc section.
505   Reloc_section* rel_;
506   // The .got.plt section.
507   Output_data_space* got_plt_;
508   // The number of PLT entries.
509   unsigned int count_;
510 };
511
512 // Create the PLT section.  The ordinary .got section is an argument,
513 // since we need to refer to the start.  We also create our own .got
514 // section just for PLT entries.
515
516 template<bool big_endian>
517 Output_data_plt_arm<big_endian>::Output_data_plt_arm(Layout* layout,
518                                                      Output_data_space* got_plt)
519   : Output_section_data(4), got_plt_(got_plt), count_(0)
520 {
521   this->rel_ = new Reloc_section(false);
522   layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
523                                   elfcpp::SHF_ALLOC, this->rel_);
524 }
525
526 template<bool big_endian>
527 void
528 Output_data_plt_arm<big_endian>::do_adjust_output_section(Output_section* os)
529 {
530   os->set_entsize(0);
531 }
532
533 // Add an entry to the PLT.
534
535 template<bool big_endian>
536 void
537 Output_data_plt_arm<big_endian>::add_entry(Symbol* gsym)
538 {
539   gold_assert(!gsym->has_plt_offset());
540
541   // Note that when setting the PLT offset we skip the initial
542   // reserved PLT entry.
543   gsym->set_plt_offset((this->count_) * sizeof(plt_entry)
544                        + sizeof(first_plt_entry));
545
546   ++this->count_;
547
548   section_offset_type got_offset = this->got_plt_->current_data_size();
549
550   // Every PLT entry needs a GOT entry which points back to the PLT
551   // entry (this will be changed by the dynamic linker, normally
552   // lazily when the function is called).
553   this->got_plt_->set_current_data_size(got_offset + 4);
554
555   // Every PLT entry needs a reloc.
556   gsym->set_needs_dynsym_entry();
557   this->rel_->add_global(gsym, elfcpp::R_ARM_JUMP_SLOT, this->got_plt_,
558                          got_offset);
559
560   // Note that we don't need to save the symbol.  The contents of the
561   // PLT are independent of which symbols are used.  The symbols only
562   // appear in the relocations.
563 }
564
565 // ARM PLTs.
566 // FIXME:  This is not very flexible.  Right now this has only been tested
567 // on armv5te.  If we are to support additional architecture features like
568 // Thumb-2 or BE8, we need to make this more flexible like GNU ld.
569
570 // The first entry in the PLT.
571 template<bool big_endian>
572 const uint32_t Output_data_plt_arm<big_endian>::first_plt_entry[5] =
573 {
574   0xe52de004,   // str   lr, [sp, #-4]!
575   0xe59fe004,   // ldr   lr, [pc, #4]
576   0xe08fe00e,   // add   lr, pc, lr 
577   0xe5bef008,   // ldr   pc, [lr, #8]!
578   0x00000000,   // &GOT[0] - .
579 };
580
581 // Subsequent entries in the PLT.
582
583 template<bool big_endian>
584 const uint32_t Output_data_plt_arm<big_endian>::plt_entry[3] =
585 {
586   0xe28fc600,   // add   ip, pc, #0xNN00000
587   0xe28cca00,   // add   ip, ip, #0xNN000
588   0xe5bcf000,   // ldr   pc, [ip, #0xNNN]!
589 };
590
591 // Write out the PLT.  This uses the hand-coded instructions above,
592 // and adjusts them as needed.  This is all specified by the arm ELF
593 // Processor Supplement.
594
595 template<bool big_endian>
596 void
597 Output_data_plt_arm<big_endian>::do_write(Output_file* of)
598 {
599   const off_t offset = this->offset();
600   const section_size_type oview_size =
601     convert_to_section_size_type(this->data_size());
602   unsigned char* const oview = of->get_output_view(offset, oview_size);
603
604   const off_t got_file_offset = this->got_plt_->offset();
605   const section_size_type got_size =
606     convert_to_section_size_type(this->got_plt_->data_size());
607   unsigned char* const got_view = of->get_output_view(got_file_offset,
608                                                       got_size);
609   unsigned char* pov = oview;
610
611   elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
612   elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();
613
614   // Write first PLT entry.  All but the last word are constants.
615   const size_t num_first_plt_words = (sizeof(first_plt_entry)
616                                       / sizeof(plt_entry[0]));
617   for (size_t i = 0; i < num_first_plt_words - 1; i++)
618     elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
619   // Last word in first PLT entry is &GOT[0] - .
620   elfcpp::Swap<32, big_endian>::writeval(pov + 16,
621                                          got_address - (plt_address + 16));
622   pov += sizeof(first_plt_entry);
623
624   unsigned char* got_pov = got_view;
625
626   memset(got_pov, 0, 12);
627   got_pov += 12;
628
629   const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
630   unsigned int plt_offset = sizeof(first_plt_entry);
631   unsigned int plt_rel_offset = 0;
632   unsigned int got_offset = 12;
633   const unsigned int count = this->count_;
634   for (unsigned int i = 0;
635        i < count;
636        ++i,
637          pov += sizeof(plt_entry),
638          got_pov += 4,
639          plt_offset += sizeof(plt_entry),
640          plt_rel_offset += rel_size,
641          got_offset += 4)
642     {
643       // Set and adjust the PLT entry itself.
644       int32_t offset = ((got_address + got_offset)
645                          - (plt_address + plt_offset + 8));
646
647       gold_assert(offset >= 0 && offset < 0x0fffffff);
648       uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff);
649       elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
650       uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff);
651       elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1);
652       uint32_t plt_insn2 = plt_entry[2] | (offset & 0xfff);
653       elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
654
655       // Set the entry in the GOT.
656       elfcpp::Swap<32, big_endian>::writeval(got_pov, plt_address);
657     }
658
659   gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
660   gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);
661
662   of->write_output_view(offset, oview_size, oview);
663   of->write_output_view(got_file_offset, got_size, got_view);
664 }
665
666 // Create a PLT entry for a global symbol.
667
668 template<bool big_endian>
669 void
670 Target_arm<big_endian>::make_plt_entry(Symbol_table* symtab, Layout* layout,
671                                        Symbol* gsym)
672 {
673   if (gsym->has_plt_offset())
674     return;
675
676   if (this->plt_ == NULL)
677     {
678       // Create the GOT sections first.
679       this->got_section(symtab, layout);
680
681       this->plt_ = new Output_data_plt_arm<big_endian>(layout, this->got_plt_);
682       layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
683                                       (elfcpp::SHF_ALLOC
684                                        | elfcpp::SHF_EXECINSTR),
685                                       this->plt_);
686     }
687   this->plt_->add_entry(gsym);
688 }
689
690 // Report an unsupported relocation against a local symbol.
691
692 template<bool big_endian>
693 void
694 Target_arm<big_endian>::Scan::unsupported_reloc_local(
695     Sized_relobj<32, big_endian>* object,
696     unsigned int r_type)
697 {
698   gold_error(_("%s: unsupported reloc %u against local symbol"),
699              object->name().c_str(), r_type);
700 }
701
702 // We are about to emit a dynamic relocation of type R_TYPE.  If the
703 // dynamic linker does not support it, issue an error.  The GNU linker
704 // only issues a non-PIC error for an allocated read-only section.
705 // Here we know the section is allocated, but we don't know that it is
706 // read-only.  But we check for all the relocation types which the
707 // glibc dynamic linker supports, so it seems appropriate to issue an
708 // error even if the section is not read-only.
709
710 template<bool big_endian>
711 void
712 Target_arm<big_endian>::Scan::check_non_pic(Relobj* object,
713                                             unsigned int r_type)
714 {
715   switch (r_type)
716     {
717     // These are the relocation types supported by glibc for ARM.
718     case elfcpp::R_ARM_RELATIVE:
719     case elfcpp::R_ARM_COPY:
720     case elfcpp::R_ARM_GLOB_DAT:
721     case elfcpp::R_ARM_JUMP_SLOT:
722     case elfcpp::R_ARM_ABS32:
723     case elfcpp::R_ARM_PC24:
724     // FIXME: The following 3 types are not supported by Android's dynamic
725     // linker.
726     case elfcpp::R_ARM_TLS_DTPMOD32:
727     case elfcpp::R_ARM_TLS_DTPOFF32:
728     case elfcpp::R_ARM_TLS_TPOFF32:
729       return;
730
731     default:
732       // This prevents us from issuing more than one error per reloc
733       // section.  But we can still wind up issuing more than one
734       // error per object file.
735       if (this->issued_non_pic_error_)
736         return;
737       object->error(_("requires unsupported dynamic reloc; "
738                       "recompile with -fPIC"));
739       this->issued_non_pic_error_ = true;
740       return;
741
742     case elfcpp::R_ARM_NONE:
743       gold_unreachable();
744     }
745 }
746
747 // Scan a relocation for a local symbol.
748 // FIXME: This only handles a subset of relocation types used by Android
749 // on ARM v5te devices.
750
751 template<bool big_endian>
752 inline void
753 Target_arm<big_endian>::Scan::local(const General_options&,
754                                     Symbol_table* symtab,
755                                     Layout* layout,
756                                     Target_arm* target,
757                                     Sized_relobj<32, big_endian>* object,
758                                     unsigned int data_shndx,
759                                     Output_section* output_section,
760                                     const elfcpp::Rel<32, big_endian>& reloc,
761                                     unsigned int r_type,
762                                     const elfcpp::Sym<32, big_endian>&)
763 {
764   r_type = get_real_reloc_type(r_type);
765   switch (r_type)
766     {
767     case elfcpp::R_ARM_NONE:
768       break;
769
770     case elfcpp::R_ARM_ABS32:
771       // If building a shared library (or a position-independent
772       // executable), we need to create a dynamic relocation for
773       // this location. The relocation applied at link time will
774       // apply the link-time value, so we flag the location with
775       // an R_ARM_RELATIVE relocation so the dynamic loader can
776       // relocate it easily.
777       if (parameters->options().output_is_position_independent())
778         {
779           Reloc_section* rel_dyn = target->rel_dyn_section(layout);
780           unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
781           // If we are to add more other reloc types than R_ARM_ABS32,
782           // we need to add check_non_pic(object, r_type) here.
783           rel_dyn->add_local_relative(object, r_sym, elfcpp::R_ARM_RELATIVE,
784                                       output_section, data_shndx,
785                                       reloc.get_r_offset());
786         }
787       break;
788
789     case elfcpp::R_ARM_REL32:
790     case elfcpp::R_ARM_THM_CALL:
791     case elfcpp::R_ARM_CALL:
792     case elfcpp::R_ARM_PREL31:
793     case elfcpp::R_ARM_JUMP24:
794     case elfcpp::R_ARM_PLT32:
795       break;
796
797     case elfcpp::R_ARM_GOTOFF32:
798       // We need a GOT section:
799       target->got_section(symtab, layout);
800       break;
801
802     case elfcpp::R_ARM_BASE_PREL:
803       // FIXME: What about this?
804       break;
805
806     case elfcpp::R_ARM_GOT_BREL:
807       {
808         // The symbol requires a GOT entry.
809         Output_data_got<32, big_endian>* got =
810           target->got_section(symtab, layout);
811         unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
812         if (got->add_local(object, r_sym, GOT_TYPE_STANDARD))
813           {
814             // If we are generating a shared object, we need to add a
815             // dynamic RELATIVE relocation for this symbol's GOT entry.
816             if (parameters->options().output_is_position_independent())
817               {
818                 Reloc_section* rel_dyn = target->rel_dyn_section(layout);
819                 unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
820                 rel_dyn->add_local_relative(
821                     object, r_sym, elfcpp::R_ARM_RELATIVE, got,
822                     object->local_got_offset(r_sym, GOT_TYPE_STANDARD));
823               }
824           }
825       }
826       break;
827
828     case elfcpp::R_ARM_TARGET1:
829       // This should have been mapped to another type already.
830       // Fall through.
831     case elfcpp::R_ARM_COPY:
832     case elfcpp::R_ARM_GLOB_DAT:
833     case elfcpp::R_ARM_JUMP_SLOT:
834     case elfcpp::R_ARM_RELATIVE:
835       // These are relocations which should only be seen by the
836       // dynamic linker, and should never be seen here.
837       gold_error(_("%s: unexpected reloc %u in object file"),
838                  object->name().c_str(), r_type);
839       break;
840
841     default:
842       unsupported_reloc_local(object, r_type);
843       break;
844     }
845 }
846
847 // Report an unsupported relocation against a global symbol.
848
849 template<bool big_endian>
850 void
851 Target_arm<big_endian>::Scan::unsupported_reloc_global(
852     Sized_relobj<32, big_endian>* object,
853     unsigned int r_type,
854     Symbol* gsym)
855 {
856   gold_error(_("%s: unsupported reloc %u against global symbol %s"),
857              object->name().c_str(), r_type, gsym->demangled_name().c_str());
858 }
859
860 // Scan a relocation for a global symbol.
861 // FIXME: This only handles a subset of relocation types used by Android
862 // on ARM v5te devices.
863
864 template<bool big_endian>
865 inline void
866 Target_arm<big_endian>::Scan::global(const General_options&,
867                                      Symbol_table* symtab,
868                                      Layout* layout,
869                                      Target_arm* target,
870                                      Sized_relobj<32, big_endian>* object,
871                                      unsigned int data_shndx,
872                                      Output_section* output_section,
873                                      const elfcpp::Rel<32, big_endian>& reloc,
874                                      unsigned int r_type,
875                                      Symbol* gsym)
876 {
877   r_type = get_real_reloc_type(r_type);
878   switch (r_type)
879     {
880     case elfcpp::R_ARM_NONE:
881       break;
882
883     case elfcpp::R_ARM_ABS32:
884       {
885         // Make a dynamic relocation if necessary.
886         if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
887           {
888             if (target->may_need_copy_reloc(gsym))
889               {
890                 target->copy_reloc(symtab, layout, object,
891                                    data_shndx, output_section, gsym, reloc);
892               }
893             else if (gsym->can_use_relative_reloc(false))
894               {
895                 // If we are to add more other reloc types than R_ARM_ABS32,
896                 // we need to add check_non_pic(object, r_type) here.
897                 Reloc_section* rel_dyn = target->rel_dyn_section(layout);
898                 rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE,
899                                              output_section, object,
900                                              data_shndx, reloc.get_r_offset());
901               }
902             else
903               {
904                 // If we are to add more other reloc types than R_ARM_ABS32,
905                 // we need to add check_non_pic(object, r_type) here.
906                 Reloc_section* rel_dyn = target->rel_dyn_section(layout);
907                 rel_dyn->add_global(gsym, r_type, output_section, object,
908                                     data_shndx, reloc.get_r_offset());
909               }
910           }
911       }
912       break;
913
914     case elfcpp::R_ARM_REL32:
915     case elfcpp::R_ARM_PREL31:
916       {
917         // Make a dynamic relocation if necessary.
918         int flags = Symbol::NON_PIC_REF;
919         if (gsym->needs_dynamic_reloc(flags))
920           {
921             if (target->may_need_copy_reloc(gsym))
922               {
923                 target->copy_reloc(symtab, layout, object,
924                                    data_shndx, output_section, gsym, reloc);
925               }
926             else
927               {
928                 check_non_pic(object, r_type);
929                 Reloc_section* rel_dyn = target->rel_dyn_section(layout);
930                 rel_dyn->add_global(gsym, r_type, output_section, object,
931                                     data_shndx, reloc.get_r_offset());
932               }
933           }
934       }
935       break;
936
937     case elfcpp::R_ARM_JUMP24:
938     case elfcpp::R_ARM_THM_CALL:
939     case elfcpp::R_ARM_CALL:
940       {
941         if (Target_arm<big_endian>::Scan::symbol_needs_plt_entry(gsym))
942           target->make_plt_entry(symtab, layout, gsym);
943         // Make a dynamic relocation if necessary.
944         int flags = Symbol::NON_PIC_REF;
945         if (gsym->type() == elfcpp::STT_FUNC
946             | gsym->type() == elfcpp::STT_ARM_TFUNC)
947           flags |= Symbol::FUNCTION_CALL;
948         if (gsym->needs_dynamic_reloc(flags))
949           {
950             if (target->may_need_copy_reloc(gsym))
951               {
952                 target->copy_reloc(symtab, layout, object,
953                                    data_shndx, output_section, gsym,
954                                    reloc);
955               }
956             else
957               {
958                 check_non_pic(object, r_type);
959                 Reloc_section* rel_dyn = target->rel_dyn_section(layout);
960                 rel_dyn->add_global(gsym, r_type, output_section, object,
961                                     data_shndx, reloc.get_r_offset());
962               }
963           }
964       }
965       break;
966
967     case elfcpp::R_ARM_PLT32:
968       // If the symbol is fully resolved, this is just a relative
969       // local reloc.  Otherwise we need a PLT entry.
970       if (gsym->final_value_is_known())
971         break;
972       // If building a shared library, we can also skip the PLT entry
973       // if the symbol is defined in the output file and is protected
974       // or hidden.
975       if (gsym->is_defined()
976           && !gsym->is_from_dynobj()
977           && !gsym->is_preemptible())
978         break;
979       target->make_plt_entry(symtab, layout, gsym);
980       break;
981
982     case elfcpp::R_ARM_GOTOFF32:
983       // We need a GOT section.
984       target->got_section(symtab, layout);
985       break;
986
987     case elfcpp::R_ARM_BASE_PREL:
988       // FIXME: What about this?
989       break;
990       
991     case elfcpp::R_ARM_GOT_BREL:
992       {
993         // The symbol requires a GOT entry.
994         Output_data_got<32, big_endian>* got =
995           target->got_section(symtab, layout);
996         if (gsym->final_value_is_known())
997           got->add_global(gsym, GOT_TYPE_STANDARD);
998         else
999           {
1000             // If this symbol is not fully resolved, we need to add a
1001             // GOT entry with a dynamic relocation.
1002             Reloc_section* rel_dyn = target->rel_dyn_section(layout);
1003             if (gsym->is_from_dynobj()
1004                 || gsym->is_undefined()
1005                 || gsym->is_preemptible())
1006               got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
1007                                        rel_dyn, elfcpp::R_ARM_GLOB_DAT);
1008             else
1009               {
1010                 if (got->add_global(gsym, GOT_TYPE_STANDARD))
1011                   rel_dyn->add_global_relative(
1012                       gsym, elfcpp::R_ARM_RELATIVE, got,
1013                       gsym->got_offset(GOT_TYPE_STANDARD));
1014               }
1015           }
1016       }
1017       break;
1018
1019     case elfcpp::R_ARM_TARGET1:
1020       // This should have been mapped to another type already.
1021       // Fall through.
1022     case elfcpp::R_ARM_COPY:
1023     case elfcpp::R_ARM_GLOB_DAT:
1024     case elfcpp::R_ARM_JUMP_SLOT:
1025     case elfcpp::R_ARM_RELATIVE:
1026       // These are relocations which should only be seen by the
1027       // dynamic linker, and should never be seen here.
1028       gold_error(_("%s: unexpected reloc %u in object file"),
1029                  object->name().c_str(), r_type);
1030       break;
1031
1032     default:
1033       unsupported_reloc_global(object, r_type, gsym);
1034       break;
1035     }
1036 }
1037
1038 // Process relocations for gc.
1039
1040 template<bool big_endian>
1041 void
1042 Target_arm<big_endian>::gc_process_relocs(const General_options& options,
1043                                           Symbol_table* symtab,
1044                                           Layout* layout,
1045                                           Sized_relobj<32, big_endian>* object,
1046                                           unsigned int data_shndx,
1047                                           unsigned int,
1048                                           const unsigned char* prelocs,
1049                                           size_t reloc_count,
1050                                           Output_section* output_section,
1051                                           bool needs_special_offset_handling,
1052                                           size_t local_symbol_count,
1053                                           const unsigned char* plocal_symbols)
1054 {
1055   typedef Target_arm<big_endian> Arm;
1056   typedef typename Target_arm<big_endian>::Scan Scan;
1057
1058   gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan>(
1059     options,
1060     symtab,
1061     layout,
1062     this,
1063     object,
1064     data_shndx,
1065     prelocs,
1066     reloc_count,
1067     output_section,
1068     needs_special_offset_handling,
1069     local_symbol_count,
1070     plocal_symbols);
1071 }
1072
1073 // Scan relocations for a section.
1074
1075 template<bool big_endian>
1076 void
1077 Target_arm<big_endian>::scan_relocs(const General_options& options,
1078                                     Symbol_table* symtab,
1079                                     Layout* layout,
1080                                     Sized_relobj<32, big_endian>* object,
1081                                     unsigned int data_shndx,
1082                                     unsigned int sh_type,
1083                                     const unsigned char* prelocs,
1084                                     size_t reloc_count,
1085                                     Output_section* output_section,
1086                                     bool needs_special_offset_handling,
1087                                     size_t local_symbol_count,
1088                                     const unsigned char* plocal_symbols)
1089 {
1090   typedef typename Target_arm<big_endian>::Scan Scan;
1091   if (sh_type == elfcpp::SHT_RELA)
1092     {
1093       gold_error(_("%s: unsupported RELA reloc section"),
1094                  object->name().c_str());
1095       return;
1096     }
1097
1098   gold::scan_relocs<32, big_endian, Target_arm, elfcpp::SHT_REL, Scan>(
1099     options,
1100     symtab,
1101     layout,
1102     this,
1103     object,
1104     data_shndx,
1105     prelocs,
1106     reloc_count,
1107     output_section,
1108     needs_special_offset_handling,
1109     local_symbol_count,
1110     plocal_symbols);
1111 }
1112
1113 // Finalize the sections.
1114
1115 template<bool big_endian>
1116 void
1117 Target_arm<big_endian>::do_finalize_sections(Layout* layout)
1118 {
1119   // Fill in some more dynamic tags.
1120   Output_data_dynamic* const odyn = layout->dynamic_data();
1121   if (odyn != NULL)
1122     {
1123       if (this->got_plt_ != NULL)
1124         odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
1125
1126       if (this->plt_ != NULL)
1127         {
1128           const Output_data* od = this->plt_->rel_plt();
1129           odyn->add_section_size(elfcpp::DT_PLTRELSZ, od);
1130           odyn->add_section_address(elfcpp::DT_JMPREL, od);
1131           odyn->add_constant(elfcpp::DT_PLTREL, elfcpp::DT_REL);
1132         }
1133
1134       if (this->rel_dyn_ != NULL)
1135         {
1136           const Output_data* od = this->rel_dyn_;
1137           odyn->add_section_address(elfcpp::DT_REL, od);
1138           odyn->add_section_size(elfcpp::DT_RELSZ, od);
1139           odyn->add_constant(elfcpp::DT_RELENT,
1140                              elfcpp::Elf_sizes<32>::rel_size);
1141         }
1142
1143       if (!parameters->options().shared())
1144         {
1145           // The value of the DT_DEBUG tag is filled in by the dynamic
1146           // linker at run time, and used by the debugger.
1147           odyn->add_constant(elfcpp::DT_DEBUG, 0);
1148         }
1149     }
1150
1151   // Emit any relocs we saved in an attempt to avoid generating COPY
1152   // relocs.
1153   if (this->copy_relocs_.any_saved_relocs())
1154     this->copy_relocs_.emit(this->rel_dyn_section(layout));
1155 }
1156
1157 // Return whether a direct absolute static relocation needs to be applied.
1158 // In cases where Scan::local() or Scan::global() has created
1159 // a dynamic relocation other than R_ARM_RELATIVE, the addend
1160 // of the relocation is carried in the data, and we must not
1161 // apply the static relocation.
1162
1163 template<bool big_endian>
1164 inline bool
1165 Target_arm<big_endian>::Relocate::should_apply_static_reloc(
1166     const Sized_symbol<32>* gsym,
1167     int ref_flags,
1168     bool is_32bit,
1169     Output_section* output_section)
1170 {
1171   // If the output section is not allocated, then we didn't call
1172   // scan_relocs, we didn't create a dynamic reloc, and we must apply
1173   // the reloc here.
1174   if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
1175       return true;
1176
1177   // For local symbols, we will have created a non-RELATIVE dynamic
1178   // relocation only if (a) the output is position independent,
1179   // (b) the relocation is absolute (not pc- or segment-relative), and
1180   // (c) the relocation is not 32 bits wide.
1181   if (gsym == NULL)
1182     return !(parameters->options().output_is_position_independent()
1183              && (ref_flags & Symbol::ABSOLUTE_REF)
1184              && !is_32bit);
1185
1186   // For global symbols, we use the same helper routines used in the
1187   // scan pass.  If we did not create a dynamic relocation, or if we
1188   // created a RELATIVE dynamic relocation, we should apply the static
1189   // relocation.
1190   bool has_dyn = gsym->needs_dynamic_reloc(ref_flags);
1191   bool is_rel = (ref_flags & Symbol::ABSOLUTE_REF)
1192                  && gsym->can_use_relative_reloc(ref_flags
1193                                                  & Symbol::FUNCTION_CALL);
1194   return !has_dyn || is_rel;
1195 }
1196
1197 // Perform a relocation.
1198
1199 template<bool big_endian>
1200 inline bool
1201 Target_arm<big_endian>::Relocate::relocate(
1202     const Relocate_info<32, big_endian>* /* relinfo */,
1203     Target_arm* /* target */,
1204     Output_section* /* output_section */,
1205     size_t /* relnum */,
1206     const elfcpp::Rel<32, big_endian>& /* rel */,
1207     unsigned int r_type,
1208     const Sized_symbol<32>* /* gsym */,
1209     const Symbol_value<32>* /* psymval */,
1210     unsigned char* /* view */,
1211     elfcpp::Elf_types<32>::Elf_Addr /* address */,
1212     section_size_type /* view_size */ )
1213 {
1214   switch (r_type)
1215     {
1216     case elfcpp::R_ARM_NONE:
1217       break;
1218
1219     default:
1220       gold_unreachable();
1221     }
1222
1223   return true;
1224 }
1225
1226 // Relocate section data.
1227
1228 template<bool big_endian>
1229 void
1230 Target_arm<big_endian>::relocate_section(
1231     const Relocate_info<32, big_endian>* relinfo,
1232     unsigned int sh_type,
1233     const unsigned char* prelocs,
1234     size_t reloc_count,
1235     Output_section* output_section,
1236     bool needs_special_offset_handling,
1237     unsigned char* view,
1238     elfcpp::Elf_types<32>::Elf_Addr address,
1239     section_size_type view_size)
1240 {
1241   typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
1242   gold_assert(sh_type == elfcpp::SHT_REL);
1243
1244   gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
1245                          Arm_relocate>(
1246     relinfo,
1247     this,
1248     prelocs,
1249     reloc_count,
1250     output_section,
1251     needs_special_offset_handling,
1252     view,
1253     address,
1254     view_size);
1255 }
1256
1257 // Return the size of a relocation while scanning during a relocatable
1258 // link.
1259
1260 template<bool big_endian>
1261 unsigned int
1262 Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
1263     unsigned int r_type,
1264     Relobj* object)
1265 {
1266   r_type = get_real_reloc_type(r_type);
1267   switch (r_type)
1268     {
1269     case elfcpp::R_ARM_NONE:
1270       return 0;
1271
1272     case elfcpp::R_ARM_ABS32:
1273     case elfcpp::R_ARM_REL32:
1274     case elfcpp::R_ARM_THM_CALL:
1275     case elfcpp::R_ARM_GOTOFF32:
1276     case elfcpp::R_ARM_BASE_PREL:
1277     case elfcpp::R_ARM_GOT_BREL:
1278     case elfcpp::R_ARM_PLT32:
1279     case elfcpp::R_ARM_CALL:
1280     case elfcpp::R_ARM_JUMP24:
1281     case elfcpp::R_ARM_PREL31:
1282       return 4;
1283
1284     case elfcpp::R_ARM_TARGET1:
1285       // This should have been mapped to another type already.
1286       // Fall through.
1287     case elfcpp::R_ARM_COPY:
1288     case elfcpp::R_ARM_GLOB_DAT:
1289     case elfcpp::R_ARM_JUMP_SLOT:
1290     case elfcpp::R_ARM_RELATIVE:
1291       // These are relocations which should only be seen by the
1292       // dynamic linker, and should never be seen here.
1293       gold_error(_("%s: unexpected reloc %u in object file"),
1294                  object->name().c_str(), r_type);
1295       return 0;
1296
1297     default:
1298       object->error(_("unsupported reloc %u in object file"), r_type);
1299       return 0;
1300     }
1301 }
1302
1303 // Scan the relocs during a relocatable link.
1304
1305 template<bool big_endian>
1306 void
1307 Target_arm<big_endian>::scan_relocatable_relocs(
1308     const General_options& options,
1309     Symbol_table* symtab,
1310     Layout* layout,
1311     Sized_relobj<32, big_endian>* object,
1312     unsigned int data_shndx,
1313     unsigned int sh_type,
1314     const unsigned char* prelocs,
1315     size_t reloc_count,
1316     Output_section* output_section,
1317     bool needs_special_offset_handling,
1318     size_t local_symbol_count,
1319     const unsigned char* plocal_symbols,
1320     Relocatable_relocs* rr)
1321 {
1322   gold_assert(sh_type == elfcpp::SHT_REL);
1323
1324   typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
1325     Relocatable_size_for_reloc> Scan_relocatable_relocs;
1326
1327   gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
1328       Scan_relocatable_relocs>(
1329     options,
1330     symtab,
1331     layout,
1332     object,
1333     data_shndx,
1334     prelocs,
1335     reloc_count,
1336     output_section,
1337     needs_special_offset_handling,
1338     local_symbol_count,
1339     plocal_symbols,
1340     rr);
1341 }
1342
1343 // Relocate a section during a relocatable link.
1344
1345 template<bool big_endian>
1346 void
1347 Target_arm<big_endian>::relocate_for_relocatable(
1348     const Relocate_info<32, big_endian>* relinfo,
1349     unsigned int sh_type,
1350     const unsigned char* prelocs,
1351     size_t reloc_count,
1352     Output_section* output_section,
1353     off_t offset_in_output_section,
1354     const Relocatable_relocs* rr,
1355     unsigned char* view,
1356     elfcpp::Elf_types<32>::Elf_Addr view_address,
1357     section_size_type view_size,
1358     unsigned char* reloc_view,
1359     section_size_type reloc_view_size)
1360 {
1361   gold_assert(sh_type == elfcpp::SHT_REL);
1362
1363   gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
1364     relinfo,
1365     prelocs,
1366     reloc_count,
1367     output_section,
1368     offset_in_output_section,
1369     rr,
1370     view,
1371     view_address,
1372     view_size,
1373     reloc_view,
1374     reloc_view_size);
1375 }
1376
1377 // Return the value to use for a dynamic symbol which requires special
1378 // treatment.  This is how we support equality comparisons of function
1379 // pointers across shared library boundaries, as described in the
1380 // processor specific ABI supplement.
1381
1382 template<bool big_endian>
1383 uint64_t
1384 Target_arm<big_endian>::do_dynsym_value(const Symbol* gsym) const
1385 {
1386   gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
1387   return this->plt_section()->address() + gsym->plt_offset();
1388 }
1389
1390 // Map platform-specific relocs to real relocs
1391 //
1392 template<bool big_endian>
1393 unsigned int
1394 Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type)
1395 {
1396   switch (r_type)
1397     {
1398     case elfcpp::R_ARM_TARGET1:
1399       // This is either R_ARM_ABS32 or R_ARM_REL32;
1400       return elfcpp::R_ARM_ABS32;
1401
1402     case elfcpp::R_ARM_TARGET2:
1403       // This can be any reloc type but ususally is R_ARM_GOT_PREL
1404       return elfcpp::R_ARM_GOT_PREL;
1405
1406     default:
1407       return r_type;
1408     }
1409 }
1410
1411 // The selector for arm object files.
1412
1413 template<bool big_endian>
1414 class Target_selector_arm : public Target_selector
1415 {
1416  public:
1417   Target_selector_arm()
1418     : Target_selector(elfcpp::EM_ARM, 32, big_endian,
1419                       (big_endian ? "elf32-bigarm" : "elf32-littlearm"))
1420   { }
1421
1422   Target*
1423   do_instantiate_target()
1424   { return new Target_arm<big_endian>(); }
1425 };
1426
1427 Target_selector_arm<false> target_selector_arm;
1428 Target_selector_arm<true> target_selector_armbe;
1429
1430 } // End anonymous namespace.