1 // arm.cc -- arm target support for gold.
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>.
7 // This file is part of gold.
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.
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.
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.
32 #include "parameters.h"
39 #include "copy-relocs.h"
41 #include "target-reloc.h"
42 #include "target-select.h"
51 template<bool big_endian>
52 class Output_data_plt_arm;
54 // The arm target class.
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
77 // Coming soon (pending patches):
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.
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
93 template<bool big_endian>
94 class Target_arm : public Sized_target<32, big_endian>
97 typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
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)
106 // Process the relocations to determine unreferenced sections for
107 // garbage collection.
109 gc_process_relocs(const General_options& options,
110 Symbol_table* symtab,
112 Sized_relobj<32, big_endian>* object,
113 unsigned int data_shndx,
114 unsigned int sh_type,
115 const unsigned char* prelocs,
117 Output_section* output_section,
118 bool needs_special_offset_handling,
119 size_t local_symbol_count,
120 const unsigned char* plocal_symbols);
122 // Scan the relocations to look for symbol adjustments.
124 scan_relocs(const General_options& options,
125 Symbol_table* symtab,
127 Sized_relobj<32, big_endian>* object,
128 unsigned int data_shndx,
129 unsigned int sh_type,
130 const unsigned char* prelocs,
132 Output_section* output_section,
133 bool needs_special_offset_handling,
134 size_t local_symbol_count,
135 const unsigned char* plocal_symbols);
137 // Finalize the sections.
139 do_finalize_sections(Layout*);
141 // Return the value to use for a dynamic symbol which requires special
144 do_dynsym_value(const Symbol*) const;
146 // Relocate a section.
148 relocate_section(const Relocate_info<32, big_endian>*,
149 unsigned int sh_type,
150 const unsigned char* prelocs,
152 Output_section* output_section,
153 bool needs_special_offset_handling,
155 elfcpp::Elf_types<32>::Elf_Addr view_address,
156 section_size_type view_size);
158 // Scan the relocs during a relocatable link.
160 scan_relocatable_relocs(const General_options& options,
161 Symbol_table* symtab,
163 Sized_relobj<32, big_endian>* object,
164 unsigned int data_shndx,
165 unsigned int sh_type,
166 const unsigned char* prelocs,
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*);
174 // Relocate a section during a relocatable link.
176 relocate_for_relocatable(const Relocate_info<32, big_endian>*,
177 unsigned int sh_type,
178 const unsigned char* prelocs,
180 Output_section* output_section,
181 off_t offset_in_output_section,
182 const Relocatable_relocs*,
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);
189 // Return whether SYM is defined by the ABI.
191 do_is_defined_by_abi(Symbol* sym) const
192 { return strcmp(sym->name(), "__tls_get_addr") == 0; }
194 // Return the size of the GOT section.
198 gold_assert(this->got_ != NULL);
199 return this->got_->data_size();
202 // Map platform-specific reloc types
204 get_real_reloc_type (unsigned int r_type);
207 // The class which scans relocations.
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);
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,
234 unsupported_reloc_local(Sized_relobj<32, big_endian>*,
235 unsigned int r_type);
238 unsupported_reloc_global(Sized_relobj<32, big_endian>*,
239 unsigned int r_type, Symbol*);
242 // The class which implements relocation.
252 // Do a relocation. Return false if the caller should not issue
253 // any warnings about this relocation.
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,
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
270 get_size_for_reloc(unsigned int, Relobj*);
273 // Get the GOT section, creating it if necessary.
274 Output_data_got<32, big_endian>*
275 got_section(Symbol_table*, Layout*);
277 // Get the GOT PLT section.
279 got_plt_section() const
281 gold_assert(this->got_plt_ != NULL);
282 return this->got_plt_;
285 // Create a PLT entry for a global symbol.
287 make_plt_entry(Symbol_table*, Layout*, Symbol*);
289 // Get the PLT section.
290 const Output_data_plt_arm<big_endian>*
293 gold_assert(this->plt_ != NULL);
297 // Get the dynamic reloc section, creating it if necessary.
299 rel_dyn_section(Layout*);
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.
305 may_need_copy_reloc(Symbol* gsym)
307 return (!parameters->options().shared()
308 && gsym->is_from_dynobj()
309 && gsym->type() != elfcpp::STT_FUNC);
312 // Add a potential copy relocation.
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)
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));
325 // Information about this specific target which we pass to the
326 // general Target structure.
327 static const Target::Target_info arm_info;
329 // The types of GOT entries needed for this platform.
332 GOT_TYPE_STANDARD = 0 // GOT entry for a regular symbol
336 Output_data_got<32, big_endian>* got_;
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_;
349 template<bool big_endian>
350 const Target::Target_info Target_arm<big_endian>::arm_info =
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
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)
366 // Get the GOT section, creating it if necessary.
368 template<bool big_endian>
369 Output_data_got<32, big_endian>*
370 Target_arm<big_endian>::got_section(Symbol_table* symtab, Layout* layout)
372 if (this->got_ == NULL)
374 gold_assert(symtab != NULL && layout != NULL);
376 this->got_ = new Output_data_got<32, big_endian>();
379 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
381 | elfcpp::SHF_WRITE),
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
389 this->got_plt_ = new Output_data_space(4, "** GOT PLT");
390 os = layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
392 | elfcpp::SHF_WRITE),
396 // The first three entries are reserved.
397 this->got_plt_->set_current_data_size(3 * 4);
399 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
400 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
402 0, 0, elfcpp::STT_OBJECT,
404 elfcpp::STV_HIDDEN, 0,
410 // Get the dynamic reloc section, creating it if necessary.
412 template<bool big_endian>
413 typename Target_arm<big_endian>::Reloc_section*
414 Target_arm<big_endian>::rel_dyn_section(Layout* layout)
416 if (this->rel_dyn_ == NULL)
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_);
423 return this->rel_dyn_;
426 // A class to handle the PLT data.
428 template<bool big_endian>
429 class Output_data_plt_arm : public Output_section_data
432 typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
435 Output_data_plt_arm(Layout*, Output_data_space*);
437 // Add an entry to the PLT.
439 add_entry(Symbol* gsym);
441 // Return the .rel.plt section data.
444 { return this->rel_; }
448 do_adjust_output_section(Output_section* os);
450 // Write to a map file.
452 do_print_to_mapfile(Mapfile* mapfile) const
453 { mapfile->print_output_data(this, _("** PLT")); }
456 // Template for the first PLT entry.
457 static const uint32_t first_plt_entry[5];
459 // Template for subsequent PLT entries.
460 static const uint32_t plt_entry[3];
462 // Set the final size.
464 set_final_data_size()
466 this->set_data_size(sizeof(first_plt_entry)
467 + this->count_ * sizeof(plt_entry));
470 // Write out the PLT data.
472 do_write(Output_file*);
474 // The reloc section.
476 // The .got.plt section.
477 Output_data_space* got_plt_;
478 // The number of PLT entries.
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.
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)
491 this->rel_ = new Reloc_section(false);
492 layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
493 elfcpp::SHF_ALLOC, this->rel_);
496 template<bool big_endian>
498 Output_data_plt_arm<big_endian>::do_adjust_output_section(Output_section* os)
503 // Add an entry to the PLT.
505 template<bool big_endian>
507 Output_data_plt_arm<big_endian>::add_entry(Symbol* gsym)
509 gold_assert(!gsym->has_plt_offset());
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));
518 section_offset_type got_offset = this->got_plt_->current_data_size();
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);
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_,
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.
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.
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] =
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] - .
551 // Subsequent entries in the PLT.
553 template<bool big_endian>
554 const uint32_t Output_data_plt_arm<big_endian>::plt_entry[3] =
556 0xe28fc600, // add ip, pc, #0xNN00000
557 0xe28cca00, // add ip, ip, #0xNN000
558 0xe5bcf000, // ldr pc, [ip, #0xNNN]!
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.
565 template<bool big_endian>
567 Output_data_plt_arm<big_endian>::do_write(Output_file* of)
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);
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,
579 unsigned char* pov = oview;
581 elfcpp::Elf_types<32>::Elf_Addr plt_address = this->address();
582 elfcpp::Elf_types<32>::Elf_Addr got_address = this->got_plt_->address();
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);
594 unsigned char* got_pov = got_view;
596 memset(got_pov, 0, 12);
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;
607 pov += sizeof(plt_entry),
609 plt_offset += sizeof(plt_entry),
610 plt_rel_offset += rel_size,
613 // Set and adjust the PLT entry itself.
614 int32_t offset = ((got_address + got_offset)
615 - (plt_address + plt_offset + 8));
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);
625 // Set the entry in the GOT.
626 elfcpp::Swap<32, big_endian>::writeval(got_pov, plt_address);
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);
632 of->write_output_view(offset, oview_size, oview);
633 of->write_output_view(got_file_offset, got_size, got_view);
636 // Create a PLT entry for a global symbol.
638 template<bool big_endian>
640 Target_arm<big_endian>::make_plt_entry(Symbol_table* symtab, Layout* layout,
643 if (gsym->has_plt_offset())
646 if (this->plt_ == NULL)
648 // Create the GOT sections first.
649 this->got_section(symtab, layout);
651 this->plt_ = new Output_data_plt_arm<big_endian>(layout, this->got_plt_);
652 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
654 | elfcpp::SHF_EXECINSTR),
657 this->plt_->add_entry(gsym);
660 // Report an unsupported relocation against a local symbol.
662 template<bool big_endian>
664 Target_arm<big_endian>::Scan::unsupported_reloc_local(
665 Sized_relobj<32, big_endian>* object,
668 gold_error(_("%s: unsupported reloc %u against local symbol"),
669 object->name().c_str(), r_type);
672 // Scan a relocation for a local symbol.
674 template<bool big_endian>
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 */,
685 const elfcpp::Sym<32, big_endian>&)
687 r_type = get_real_reloc_type(r_type);
690 case elfcpp::R_ARM_NONE:
694 unsupported_reloc_local(object, r_type);
699 // Report an unsupported relocation against a global symbol.
701 template<bool big_endian>
703 Target_arm<big_endian>::Scan::unsupported_reloc_global(
704 Sized_relobj<32, big_endian>* object,
708 gold_error(_("%s: unsupported reloc %u against global symbol %s"),
709 object->name().c_str(), r_type, gsym->demangled_name().c_str());
712 // Scan a relocation for a global symbol.
714 template<bool big_endian>
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 */,
727 r_type = get_real_reloc_type(r_type);
730 case elfcpp::R_ARM_NONE:
734 unsupported_reloc_global(object, r_type, gsym);
739 // Process relocations for gc.
741 template<bool big_endian>
743 Target_arm<big_endian>::gc_process_relocs(const General_options& options,
744 Symbol_table* symtab,
746 Sized_relobj<32, big_endian>* object,
747 unsigned int data_shndx,
749 const unsigned char* prelocs,
751 Output_section* output_section,
752 bool needs_special_offset_handling,
753 size_t local_symbol_count,
754 const unsigned char* plocal_symbols)
756 typedef Target_arm<big_endian> Arm;
757 typedef typename Target_arm<big_endian>::Scan Scan;
759 gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan>(
769 needs_special_offset_handling,
774 // Scan relocations for a section.
776 template<bool big_endian>
778 Target_arm<big_endian>::scan_relocs(const General_options& options,
779 Symbol_table* symtab,
781 Sized_relobj<32, big_endian>* object,
782 unsigned int data_shndx,
783 unsigned int sh_type,
784 const unsigned char* prelocs,
786 Output_section* output_section,
787 bool needs_special_offset_handling,
788 size_t local_symbol_count,
789 const unsigned char* plocal_symbols)
791 typedef typename Target_arm<big_endian>::Scan Scan;
792 if (sh_type == elfcpp::SHT_RELA)
794 gold_error(_("%s: unsupported RELA reloc section"),
795 object->name().c_str());
799 gold::scan_relocs<32, big_endian, Target_arm, elfcpp::SHT_REL, Scan>(
809 needs_special_offset_handling,
814 // Finalize the sections.
816 template<bool big_endian>
818 Target_arm<big_endian>::do_finalize_sections(Layout* layout)
820 // Fill in some more dynamic tags.
821 Output_data_dynamic* const odyn = layout->dynamic_data();
824 if (this->got_plt_ != NULL)
825 odyn->add_section_address(elfcpp::DT_PLTGOT, this->got_plt_);
827 if (this->plt_ != NULL)
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);
835 if (this->rel_dyn_ != NULL)
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);
844 if (!parameters->options().shared())
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);
852 // Emit any relocs we saved in an attempt to avoid generating COPY
854 if (this->copy_relocs_.any_saved_relocs())
855 this->copy_relocs_.emit(this->rel_dyn_section(layout));
858 // Perform a relocation.
860 template<bool big_endian>
862 Target_arm<big_endian>::Relocate::relocate(
863 const Relocate_info<32, big_endian>* /* relinfo */,
864 Target_arm* /* target */,
865 Output_section* /* output_section */,
867 const elfcpp::Rel<32, big_endian>& /* rel */,
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 */ )
877 case elfcpp::R_ARM_NONE:
887 // Relocate section data.
889 template<bool big_endian>
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,
896 Output_section* output_section,
897 bool needs_special_offset_handling,
899 elfcpp::Elf_types<32>::Elf_Addr address,
900 section_size_type view_size)
902 typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
903 gold_assert(sh_type == elfcpp::SHT_REL);
905 gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
912 needs_special_offset_handling,
918 // Return the size of a relocation while scanning during a relocatable
921 template<bool big_endian>
923 Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
927 r_type = get_real_reloc_type(r_type);
930 case elfcpp::R_ARM_NONE:
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:
945 case elfcpp::R_ARM_TARGET1:
946 // This should have been mapped to another type already.
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);
959 object->error(_("unsupported reloc %u in object file"), r_type);
964 // Scan the relocs during a relocatable link.
966 template<bool big_endian>
968 Target_arm<big_endian>::scan_relocatable_relocs(
969 const General_options& options,
970 Symbol_table* symtab,
972 Sized_relobj<32, big_endian>* object,
973 unsigned int data_shndx,
974 unsigned int sh_type,
975 const unsigned char* prelocs,
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)
983 gold_assert(sh_type == elfcpp::SHT_REL);
985 typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
986 Relocatable_size_for_reloc> Scan_relocatable_relocs;
988 gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
989 Scan_relocatable_relocs>(
998 needs_special_offset_handling,
1004 // Relocate a section during a relocatable link.
1006 template<bool big_endian>
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,
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)
1022 gold_assert(sh_type == elfcpp::SHT_REL);
1024 gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
1029 offset_in_output_section,
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.
1043 template<bool big_endian>
1045 Target_arm<big_endian>::do_dynsym_value(const Symbol* gsym) const
1047 gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
1048 return this->plt_section()->address() + gsym->plt_offset();
1051 // Map platform-specific relocs to real relocs
1053 template<bool big_endian>
1055 Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type)
1059 case elfcpp::R_ARM_TARGET1:
1060 // This is either R_ARM_ABS32 or R_ARM_REL32;
1061 return elfcpp::R_ARM_ABS32;
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;
1072 // The selector for arm object files.
1074 template<bool big_endian>
1075 class Target_selector_arm : public Target_selector
1078 Target_selector_arm()
1079 : Target_selector(elfcpp::EM_ARM, 32, big_endian,
1080 (big_endian ? "elf32-bigarm" : "elf32-littlearm"))
1084 do_instantiate_target()
1085 { return new Target_arm<big_endian>(); }
1088 Target_selector_arm<false> target_selector_arm;
1089 Target_selector_arm<true> target_selector_armbe;
1091 } // End anonymous namespace.