*** empty log message ***
[deliverable/binutils-gdb.git] / gold / arm.cc
CommitLineData
4a657b0d
DK
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
46namespace
47{
48
49using namespace gold;
50
94cdfcff
DK
51template<bool big_endian>
52class Output_data_plt_arm;
53
4a657b0d
DK
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):
4a657b0d
DK
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.
94cdfcff
DK
90// - Make PLTs more flexible for different architecture features like
91// Thumb-2 and BE8.
4a657b0d
DK
92
93template<bool big_endian>
94class 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()
94cdfcff
DK
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)
4a657b0d
DK
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
94cdfcff 141 // Return the value to use for a dynamic symbol which requires special
4a657b0d
DK
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
94cdfcff
DK
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
4a657b0d
DK
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
94cdfcff
DK
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
4a657b0d
DK
325 // Information about this specific target which we pass to the
326 // general Target structure.
327 static const Target::Target_info arm_info;
94cdfcff
DK
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_;
4a657b0d
DK
347};
348
349template<bool big_endian>
350const 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
94cdfcff
DK
366// Get the GOT section, creating it if necessary.
367
368template<bool big_endian>
369Output_data_got<32, big_endian>*
370Target_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
412template<bool big_endian>
413typename Target_arm<big_endian>::Reloc_section*
414Target_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
428template<bool big_endian>
429class 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
486template<bool big_endian>
487Output_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
496template<bool big_endian>
497void
498Output_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
505template<bool big_endian>
506void
507Output_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.
541template<bool big_endian>
542const 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
553template<bool big_endian>
554const 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
565template<bool big_endian>
566void
567Output_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
638template<bool big_endian>
639void
640Target_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
4a657b0d
DK
660// Report an unsupported relocation against a local symbol.
661
662template<bool big_endian>
663void
664Target_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
674template<bool big_endian>
675inline void
676Target_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
701template<bool big_endian>
702void
703Target_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
714template<bool big_endian>
715inline void
716Target_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
741template<bool big_endian>
742void
743Target_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
776template<bool big_endian>
777void
778Target_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
816template<bool big_endian>
817void
94cdfcff 818Target_arm<big_endian>::do_finalize_sections(Layout* layout)
4a657b0d 819{
94cdfcff
DK
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));
4a657b0d
DK
856}
857
858// Perform a relocation.
859
860template<bool big_endian>
861inline bool
862Target_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
889template<bool big_endian>
890void
891Target_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
921template<bool big_endian>
922unsigned int
923Target_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
966template<bool big_endian>
967void
968Target_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
1006template<bool big_endian>
1007void
1008Target_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
94cdfcff
DK
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
4a657b0d
DK
1043template<bool big_endian>
1044uint64_t
94cdfcff 1045Target_arm<big_endian>::do_dynsym_value(const Symbol* gsym) const
4a657b0d 1046{
94cdfcff
DK
1047 gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
1048 return this->plt_section()->address() + gsym->plt_offset();
4a657b0d
DK
1049}
1050
1051// Map platform-specific relocs to real relocs
1052//
1053template<bool big_endian>
1054unsigned int
1055Target_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
1074template<bool big_endian>
1075class 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
1088Target_selector_arm<false> target_selector_arm;
1089Target_selector_arm<true> target_selector_armbe;
1090
1091} // End anonymous namespace.
This page took 0.063902 seconds and 4 git commands to generate.