GNU Binutils with patches for OS216
修訂 | 47a9f4fcab30d2f9a1485a7a2634f40feb22bd60 (tree) |
---|---|
時間 | 2016-03-18 07:07:49 |
作者 | Vladimir Radosavljevic <vladimir.radosavljevic@imgt...> |
Commiter | Cary Coutant |
Add MIPS-64 support.
gold/
* mips.cc (enum Special_relocation_symbol): New enum type.
(is_readonly_section): New function.
(eh_reloc): Likewise.
(Mips_got_entry::is_section_symbol_): New member.
(Mips_got_entry::is_section_symbol): New method.
(Mips_got_info::record_local_got_symbol): Add is_section_symbol
argument.
(Mips_relobj::mips_elf_options_section_name): New method.
(Mips_output_data_got::record_local_got_symbol): Add
is_section_symbol argument, and pass it to
Mips_got_info::record_local_got_symbol.
(Mips_output_data_got::got_offset): Add addend argument, and pass
it to Relobj::local_got_offset.
(struct Mips_output_reloc_writer): New type.
(class Mips_output_data_reloc): New class.
(Mips_output_data_plt::Reloc_section): Change type to
Mips_output_data_reloc.
(Target_mips::Reloc_section): Likewise.
(Mips_reloc_types::get_r_addend): Remove unsigned from return type.
(Mips_classify_reloc::get_r_type2): New method.
(Mips_classify_reloc::get_r_type3): Likewise.
(Mips_classify_reloc::get_r_ssym): Likewise.
(Target_mips::Reloca_section): Remove.
(Relocate::should_apply_static_reloc): Rename from
should_apply_r_mips_32_reloc.
(Target_mips::copy_reloc): Replace Reltype parameter with r_type
and r_offset.
(Mips_relocate_functions::Valtype): New type.
(Mips_relocate_functions::Valtype64): New type.
(Mips_relocate_functions::check_overflow): New method.
(Mips_relocate_functions::mips_reloc_unshuffle): Move to public
interface.
(Mips_relocate_functions::mips_reloc_shuffle): Likewise.
(Mips_relocate_functions::rel16): Add support for resolving
relocations for Mips64.
(Mips_relocate_functions::rel32): Likewise.
(Mips_relocate_functions::reljalr): Likewise.
(Mips_relocate_functions::relpc32): Likewise.
(Mips_relocate_functions::rel26): Likewise.
(Mips_relocate_functions::relpc16): Likewise.
(Mips_relocate_functions::relmicromips_pc7_s1): Likewise.
(Mips_relocate_functions::relmicromips_pc10_s1): Likewise.
(Mips_relocate_functions::relmicromips_pc16_s1): Likewise.
(Mips_relocate_functions::do_relhi16): Likewise.
(Mips_relocate_functions::do_relgot16_local): Likewise.
(Mips_relocate_functions::rello16): Likewise.
(Mips_relocate_functions::relgot): Likewise.
(Mips_relocate_functions::relgotpage): Likewise.
(Mips_relocate_functions::relgotofst): Likewise.
(Mips_relocate_functions::relgot_hi16): Likewise.
(Mips_relocate_functions::relgot_lo16): Likewise.
(Mips_relocate_functions::relgprel): Likewise.
(Mips_relocate_functions::relgprel32): Likewise.
(Mips_relocate_functions::tlsrelhi16): Likewise.
(Mips_relocate_functions::tlsrello16): Likewise.
(Mips_relocate_functions::tlsrel32): Likewise.
(Mips_relocate_functions::relsub): Likewise.
(Mips_relocate_functions::releh): New method.
(Mips_relocate_functions::rel64): Likewise.
(Mips_got_info::record_local_got_symbol): Add is_section_symbol and
pass it to Mips_got_entry.
(Mips_got_info::add_local_entries): Pass addend argument
to code functions, and for STT_SECTION symbols call
add_symbolless_local_addend.
(Mips_got_info::add_tls_entries): Pass addend argument to code
functions.
(Mips_relobj::do_read_symbols): Read gp value that was used to
create object.
(Mips_output_data_plt::plt_entry): Remove opcode from l[wd]
instruction. Opcode for instruction will be selected later.
(Target_mips::gc_process_relocs): Add case for SHT_RELA.
(Target_mips::scan_relocatable_relocs): Likewise.
(Target_mips::emit_relocs_scan): Likewise.
(Target_mips::relocate_relocs): Likewise.
(Target_mips::do_finalize_sections): Skip objects for merging
processor specific flags in which all input sections will be
discarded.
(mips_get_size_for_reloc): Add case for R_MIPS_EH.
(Target_mips::Scan::get_reference_flags): Likewise.
(Target_mips::relocate_special_relocatable): Call rel26 method with
calculate_only and calculated_value arguments.
(Target_mips::Scan::local): Add case for R_MIPS_EH. Don't create a
dynamic relocation against a readonly sections, and pass
is_section_symbol to Mips_got_info::record_local_got_symbol.
(Target_mips::Scan::global): Add case for R_MIPS_EH. Don't create a
dynamic relocation against a readonly sections, and pass r_type
and r_offset to Target_mips::copy_reloc.
(Target_mips::Relocate::relocate): Add support for resolving
relocations for Mips64.
(Target_mips::mips_info): Add case for Mips64 default dynamic
linker name.
(Target_selector_mips): Correct emulation names.
@@ -1,5 +1,100 @@ | ||
1 | 1 | 2016-03-17 Vladimir Radosavljevic <vladimir.radosavljevic@imgtec.com> |
2 | 2 | |
3 | + * mips.cc (enum Special_relocation_symbol): New enum type. | |
4 | + (is_readonly_section): New function. | |
5 | + (eh_reloc): Likewise. | |
6 | + (Mips_got_entry::is_section_symbol_): New member. | |
7 | + (Mips_got_entry::is_section_symbol): New method. | |
8 | + (Mips_got_info::record_local_got_symbol): Add is_section_symbol | |
9 | + argument. | |
10 | + (Mips_relobj::mips_elf_options_section_name): New method. | |
11 | + (Mips_output_data_got::record_local_got_symbol): Add | |
12 | + is_section_symbol argument, and pass it to | |
13 | + Mips_got_info::record_local_got_symbol. | |
14 | + (Mips_output_data_got::got_offset): Add addend argument, and pass | |
15 | + it to Relobj::local_got_offset. | |
16 | + (struct Mips_output_reloc_writer): New type. | |
17 | + (class Mips_output_data_reloc): New class. | |
18 | + (Mips_output_data_plt::Reloc_section): Change type to | |
19 | + Mips_output_data_reloc. | |
20 | + (Target_mips::Reloc_section): Likewise. | |
21 | + (Mips_reloc_types::get_r_addend): Remove unsigned from return type. | |
22 | + (Mips_classify_reloc::get_r_type2): New method. | |
23 | + (Mips_classify_reloc::get_r_type3): Likewise. | |
24 | + (Mips_classify_reloc::get_r_ssym): Likewise. | |
25 | + (Target_mips::Reloca_section): Remove. | |
26 | + (Relocate::should_apply_static_reloc): Rename from | |
27 | + should_apply_r_mips_32_reloc. | |
28 | + (Target_mips::copy_reloc): Replace Reltype parameter with r_type | |
29 | + and r_offset. | |
30 | + (Mips_relocate_functions::Valtype): New type. | |
31 | + (Mips_relocate_functions::Valtype64): New type. | |
32 | + (Mips_relocate_functions::check_overflow): New method. | |
33 | + (Mips_relocate_functions::mips_reloc_unshuffle): Move to public | |
34 | + interface. | |
35 | + (Mips_relocate_functions::mips_reloc_shuffle): Likewise. | |
36 | + (Mips_relocate_functions::rel16): Add support for resolving | |
37 | + relocations for Mips64. | |
38 | + (Mips_relocate_functions::rel32): Likewise. | |
39 | + (Mips_relocate_functions::reljalr): Likewise. | |
40 | + (Mips_relocate_functions::relpc32): Likewise. | |
41 | + (Mips_relocate_functions::rel26): Likewise. | |
42 | + (Mips_relocate_functions::relpc16): Likewise. | |
43 | + (Mips_relocate_functions::relmicromips_pc7_s1): Likewise. | |
44 | + (Mips_relocate_functions::relmicromips_pc10_s1): Likewise. | |
45 | + (Mips_relocate_functions::relmicromips_pc16_s1): Likewise. | |
46 | + (Mips_relocate_functions::do_relhi16): Likewise. | |
47 | + (Mips_relocate_functions::do_relgot16_local): Likewise. | |
48 | + (Mips_relocate_functions::rello16): Likewise. | |
49 | + (Mips_relocate_functions::relgot): Likewise. | |
50 | + (Mips_relocate_functions::relgotpage): Likewise. | |
51 | + (Mips_relocate_functions::relgotofst): Likewise. | |
52 | + (Mips_relocate_functions::relgot_hi16): Likewise. | |
53 | + (Mips_relocate_functions::relgot_lo16): Likewise. | |
54 | + (Mips_relocate_functions::relgprel): Likewise. | |
55 | + (Mips_relocate_functions::relgprel32): Likewise. | |
56 | + (Mips_relocate_functions::tlsrelhi16): Likewise. | |
57 | + (Mips_relocate_functions::tlsrello16): Likewise. | |
58 | + (Mips_relocate_functions::tlsrel32): Likewise. | |
59 | + (Mips_relocate_functions::relsub): Likewise. | |
60 | + (Mips_relocate_functions::releh): New method. | |
61 | + (Mips_relocate_functions::rel64): Likewise. | |
62 | + (Mips_got_info::record_local_got_symbol): Add is_section_symbol and | |
63 | + pass it to Mips_got_entry. | |
64 | + (Mips_got_info::add_local_entries): Pass addend argument | |
65 | + to code functions, and for STT_SECTION symbols call | |
66 | + add_symbolless_local_addend. | |
67 | + (Mips_got_info::add_tls_entries): Pass addend argument to code | |
68 | + functions. | |
69 | + (Mips_relobj::do_read_symbols): Read gp value that was used to | |
70 | + create object. | |
71 | + (Mips_output_data_plt::plt_entry): Remove opcode from l[wd] | |
72 | + instruction. Opcode for instruction will be selected later. | |
73 | + (Target_mips::gc_process_relocs): Add case for SHT_RELA. | |
74 | + (Target_mips::scan_relocatable_relocs): Likewise. | |
75 | + (Target_mips::emit_relocs_scan): Likewise. | |
76 | + (Target_mips::relocate_relocs): Likewise. | |
77 | + (Target_mips::do_finalize_sections): Skip objects for merging | |
78 | + processor specific flags in which all input sections will be | |
79 | + discarded. | |
80 | + (mips_get_size_for_reloc): Add case for R_MIPS_EH. | |
81 | + (Target_mips::Scan::get_reference_flags): Likewise. | |
82 | + (Target_mips::relocate_special_relocatable): Call rel26 method with | |
83 | + calculate_only and calculated_value arguments. | |
84 | + (Target_mips::Scan::local): Add case for R_MIPS_EH. Don't create a | |
85 | + dynamic relocation against a readonly sections, and pass | |
86 | + is_section_symbol to Mips_got_info::record_local_got_symbol. | |
87 | + (Target_mips::Scan::global): Add case for R_MIPS_EH. Don't create a | |
88 | + dynamic relocation against a readonly sections, and pass r_type | |
89 | + and r_offset to Target_mips::copy_reloc. | |
90 | + (Target_mips::Relocate::relocate): Add support for resolving | |
91 | + relocations for Mips64. | |
92 | + (Target_mips::mips_info): Add case for Mips64 default dynamic | |
93 | + linker name. | |
94 | + (Target_selector_mips): Correct emulation names. | |
95 | + | |
96 | +2016-03-17 Vladimir Radosavljevic <vladimir.radosavljevic@imgtec.com> | |
97 | + | |
3 | 98 | * mips.cc (class Mips_output_data_la25_stub): Add |
4 | 99 | do_print_to_mapfile function. |
5 | 100 |
@@ -132,6 +132,31 @@ enum Got_tls_type | ||
132 | 132 | GOT_TLS_IE = 4 |
133 | 133 | }; |
134 | 134 | |
135 | +// Values found in the r_ssym field of a relocation entry. | |
136 | +enum Special_relocation_symbol | |
137 | +{ | |
138 | + RSS_UNDEF = 0, // None - value is zero. | |
139 | + RSS_GP = 1, // Value of GP. | |
140 | + RSS_GP0 = 2, // Value of GP in object being relocated. | |
141 | + RSS_LOC = 3 // Address of location being relocated. | |
142 | +}; | |
143 | + | |
144 | +// Whether the section is readonly. | |
145 | +static inline bool | |
146 | +is_readonly_section(Output_section* output_section) | |
147 | +{ | |
148 | + elfcpp::Elf_Xword section_flags = output_section->flags(); | |
149 | + elfcpp::Elf_Word section_type = output_section->type(); | |
150 | + | |
151 | + if (section_type == elfcpp::SHT_NOBITS) | |
152 | + return false; | |
153 | + | |
154 | + if (section_flags & elfcpp::SHF_WRITE) | |
155 | + return false; | |
156 | + | |
157 | + return true; | |
158 | +} | |
159 | + | |
135 | 160 | // Return TRUE if a relocation of type R_TYPE from OBJECT might |
136 | 161 | // require an la25 stub. See also local_pic_function, which determines |
137 | 162 | // whether the destination function ever requires a stub. |
@@ -232,6 +257,12 @@ got_lo16_reloc(unsigned int r_type) | ||
232 | 257 | } |
233 | 258 | |
234 | 259 | static inline bool |
260 | +eh_reloc(unsigned int r_type) | |
261 | +{ | |
262 | + return (r_type == elfcpp::R_MIPS_EH); | |
263 | +} | |
264 | + | |
265 | +static inline bool | |
235 | 266 | got_disp_reloc(unsigned int r_type) |
236 | 267 | { |
237 | 268 | return (r_type == elfcpp::R_MIPS_GOT_DISP |
@@ -401,13 +432,15 @@ class Mips_got_entry | ||
401 | 432 | public: |
402 | 433 | Mips_got_entry(Mips_relobj<size, big_endian>* object, unsigned int symndx, |
403 | 434 | Mips_address addend, unsigned char tls_type, |
404 | - unsigned int shndx) | |
405 | - : object_(object), symndx_(symndx), tls_type_(tls_type), shndx_(shndx) | |
435 | + unsigned int shndx, bool is_section_symbol) | |
436 | + : object_(object), symndx_(symndx), tls_type_(tls_type), | |
437 | + is_section_symbol_(is_section_symbol), shndx_(shndx) | |
406 | 438 | { this->d.addend = addend; } |
407 | 439 | |
408 | 440 | Mips_got_entry(Mips_relobj<size, big_endian>* object, Mips_symbol<size>* sym, |
409 | 441 | unsigned char tls_type) |
410 | - : object_(object), symndx_(-1U), tls_type_(tls_type), shndx_(-1U) | |
442 | + : object_(object), symndx_(-1U), tls_type_(tls_type), | |
443 | + is_section_symbol_(false), shndx_(-1U) | |
411 | 444 | { this->d.sym = sym; } |
412 | 445 | |
413 | 446 | // Return whether this entry is for a local symbol. |
@@ -501,6 +534,11 @@ class Mips_got_entry | ||
501 | 534 | shndx() const |
502 | 535 | { return this->shndx_; } |
503 | 536 | |
537 | + // Return whether this is a STT_SECTION symbol. | |
538 | + bool | |
539 | + is_section_symbol() const | |
540 | + { return this->is_section_symbol_; } | |
541 | + | |
504 | 542 | private: |
505 | 543 | // The input object that needs the GOT entry. |
506 | 544 | Mips_relobj<size, big_endian>* object_; |
@@ -522,6 +560,9 @@ class Mips_got_entry | ||
522 | 560 | // symbol entry with r_symndx == 0. |
523 | 561 | unsigned char tls_type_; |
524 | 562 | |
563 | + // Whether this is a STT_SECTION symbol. | |
564 | + bool is_section_symbol_; | |
565 | + | |
525 | 566 | // For local GOT entries, section index of the local symbol. |
526 | 567 | unsigned int shndx_; |
527 | 568 | }; |
@@ -645,7 +686,8 @@ class Mips_got_info | ||
645 | 686 | void |
646 | 687 | record_local_got_symbol(Mips_relobj<size, big_endian>* object, |
647 | 688 | unsigned int symndx, Mips_address addend, |
648 | - unsigned int r_type, unsigned int shndx); | |
689 | + unsigned int r_type, unsigned int shndx, | |
690 | + bool is_section_symbol); | |
649 | 691 | |
650 | 692 | // Reserve GOT entry for a GOT relocation of type R_TYPE against MIPS_SYM, |
651 | 693 | // in OBJECT. FOR_CALL is true if the caller is only interested in |
@@ -1764,6 +1806,10 @@ class Mips_relobj : public Sized_relobj_file<size, big_endian> | ||
1764 | 1806 | do_read_symbols(Read_symbols_data* sd); |
1765 | 1807 | |
1766 | 1808 | private: |
1809 | + // The name of the options section. | |
1810 | + const char* mips_elf_options_section_name() | |
1811 | + { return this->is_newabi() ? ".MIPS.options" : ".options"; } | |
1812 | + | |
1767 | 1813 | // processor-specific flags in ELF file header. |
1768 | 1814 | elfcpp::Elf_Word processor_specific_flags_; |
1769 | 1815 |
@@ -1861,10 +1907,12 @@ class Mips_output_data_got : public Output_data_got<size, big_endian> | ||
1861 | 1907 | void |
1862 | 1908 | record_local_got_symbol(Mips_relobj<size, big_endian>* object, |
1863 | 1909 | unsigned int symndx, Mips_address addend, |
1864 | - unsigned int r_type, unsigned int shndx) | |
1910 | + unsigned int r_type, unsigned int shndx, | |
1911 | + bool is_section_symbol) | |
1865 | 1912 | { |
1866 | 1913 | this->master_got_info_->record_local_got_symbol(object, symndx, addend, |
1867 | - r_type, shndx); | |
1914 | + r_type, shndx, | |
1915 | + is_section_symbol); | |
1868 | 1916 | } |
1869 | 1917 | |
1870 | 1918 | // Reserve GOT entry for a GOT relocation of type R_TYPE against MIPS_SYM, |
@@ -2002,8 +2050,9 @@ class Mips_output_data_got : public Output_data_got<size, big_endian> | ||
2002 | 2050 | // SYMNDX. |
2003 | 2051 | unsigned int |
2004 | 2052 | got_offset(unsigned int symndx, unsigned int got_type, |
2005 | - Sized_relobj_file<size, big_endian>* object) const | |
2006 | - { return object->local_got_offset(symndx, got_type); } | |
2053 | + Sized_relobj_file<size, big_endian>* object, | |
2054 | + uint64_t addend) const | |
2055 | + { return object->local_got_offset(symndx, got_type, addend); } | |
2007 | 2056 | |
2008 | 2057 | // Return the offset of TLS LDM entry. For multi-GOT links, use OBJECT's GOT. |
2009 | 2058 | unsigned int |
@@ -2259,14 +2308,73 @@ class Mips_output_data_la25_stub : public Output_section_data | ||
2259 | 2308 | Unordered_set<Mips_symbol<size>*> symbols_; |
2260 | 2309 | }; |
2261 | 2310 | |
2311 | +// MIPS-specific relocation writer. | |
2312 | + | |
2313 | +template<int sh_type, bool dynamic, int size, bool big_endian> | |
2314 | +struct Mips_output_reloc_writer; | |
2315 | + | |
2316 | +template<int sh_type, bool dynamic, bool big_endian> | |
2317 | +struct Mips_output_reloc_writer<sh_type, dynamic, 32, big_endian> | |
2318 | +{ | |
2319 | + typedef Output_reloc<sh_type, dynamic, 32, big_endian> Output_reloc_type; | |
2320 | + typedef std::vector<Output_reloc_type> Relocs; | |
2321 | + | |
2322 | + static void | |
2323 | + write(typename Relocs::const_iterator p, unsigned char* pov) | |
2324 | + { p->write(pov); } | |
2325 | +}; | |
2326 | + | |
2327 | +template<int sh_type, bool dynamic, bool big_endian> | |
2328 | +struct Mips_output_reloc_writer<sh_type, dynamic, 64, big_endian> | |
2329 | +{ | |
2330 | + typedef Output_reloc<sh_type, dynamic, 64, big_endian> Output_reloc_type; | |
2331 | + typedef std::vector<Output_reloc_type> Relocs; | |
2332 | + | |
2333 | + static void | |
2334 | + write(typename Relocs::const_iterator p, unsigned char* pov) | |
2335 | + { | |
2336 | + elfcpp::Mips64_rel_write<big_endian> orel(pov); | |
2337 | + orel.put_r_offset(p->get_address()); | |
2338 | + orel.put_r_sym(p->get_symbol_index()); | |
2339 | + orel.put_r_ssym(RSS_UNDEF); | |
2340 | + orel.put_r_type(p->type()); | |
2341 | + if (p->type() == elfcpp::R_MIPS_REL32) | |
2342 | + orel.put_r_type2(elfcpp::R_MIPS_64); | |
2343 | + else | |
2344 | + orel.put_r_type2(elfcpp::R_MIPS_NONE); | |
2345 | + orel.put_r_type3(elfcpp::R_MIPS_NONE); | |
2346 | + } | |
2347 | +}; | |
2348 | + | |
2349 | +template<int sh_type, bool dynamic, int size, bool big_endian> | |
2350 | +class Mips_output_data_reloc : public Output_data_reloc<sh_type, dynamic, | |
2351 | + size, big_endian> | |
2352 | +{ | |
2353 | + public: | |
2354 | + Mips_output_data_reloc(bool sort_relocs) | |
2355 | + : Output_data_reloc<sh_type, dynamic, size, big_endian>(sort_relocs) | |
2356 | + { } | |
2357 | + | |
2358 | + protected: | |
2359 | + // Write out the data. | |
2360 | + void | |
2361 | + do_write(Output_file* of) | |
2362 | + { | |
2363 | + typedef Mips_output_reloc_writer<sh_type, dynamic, size, | |
2364 | + big_endian> Writer; | |
2365 | + this->template do_write_generic<Writer>(of); | |
2366 | + } | |
2367 | +}; | |
2368 | + | |
2369 | + | |
2262 | 2370 | // A class to handle the PLT data. |
2263 | 2371 | |
2264 | 2372 | template<int size, bool big_endian> |
2265 | 2373 | class Mips_output_data_plt : public Output_section_data |
2266 | 2374 | { |
2267 | 2375 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address; |
2268 | - typedef Output_data_reloc<elfcpp::SHT_REL, true, | |
2269 | - size, big_endian> Reloc_section; | |
2376 | + typedef Mips_output_data_reloc<elfcpp::SHT_REL, true, | |
2377 | + size, big_endian> Reloc_section; | |
2270 | 2378 | |
2271 | 2379 | public: |
2272 | 2380 | // Create the PLT section. The ordinary .got section is an argument, |
@@ -2877,7 +2985,7 @@ struct Mips_reloc_types<elfcpp::SHT_REL, 32, big_endian> | ||
2877 | 2985 | typedef typename elfcpp::Rel<32, big_endian> Reloc; |
2878 | 2986 | typedef typename elfcpp::Rel_write<32, big_endian> Reloc_write; |
2879 | 2987 | |
2880 | - static unsigned typename elfcpp::Elf_types<32>::Elf_Swxword | |
2988 | + static typename elfcpp::Elf_types<32>::Elf_Swxword | |
2881 | 2989 | get_r_addend(const Reloc*) |
2882 | 2990 | { return 0; } |
2883 | 2991 |
@@ -2893,7 +3001,7 @@ struct Mips_reloc_types<elfcpp::SHT_RELA, 32, big_endian> | ||
2893 | 3001 | typedef typename elfcpp::Rela<32, big_endian> Reloc; |
2894 | 3002 | typedef typename elfcpp::Rela_write<32, big_endian> Reloc_write; |
2895 | 3003 | |
2896 | - static unsigned typename elfcpp::Elf_types<32>::Elf_Swxword | |
3004 | + static typename elfcpp::Elf_types<32>::Elf_Swxword | |
2897 | 3005 | get_r_addend(const Reloc* reloc) |
2898 | 3006 | { return reloc->get_r_addend(); } |
2899 | 3007 |
@@ -2909,7 +3017,7 @@ struct Mips_reloc_types<elfcpp::SHT_REL, 64, big_endian> | ||
2909 | 3017 | typedef typename elfcpp::Mips64_rel<big_endian> Reloc; |
2910 | 3018 | typedef typename elfcpp::Mips64_rel_write<big_endian> Reloc_write; |
2911 | 3019 | |
2912 | - static unsigned typename elfcpp::Elf_types<64>::Elf_Swxword | |
3020 | + static typename elfcpp::Elf_types<64>::Elf_Swxword | |
2913 | 3021 | get_r_addend(const Reloc*) |
2914 | 3022 | { return 0; } |
2915 | 3023 |
@@ -2925,7 +3033,7 @@ struct Mips_reloc_types<elfcpp::SHT_RELA, 64, big_endian> | ||
2925 | 3033 | typedef typename elfcpp::Mips64_rela<big_endian> Reloc; |
2926 | 3034 | typedef typename elfcpp::Mips64_rela_write<big_endian> Reloc_write; |
2927 | 3035 | |
2928 | - static unsigned typename elfcpp::Elf_types<64>::Elf_Swxword | |
3036 | + static typename elfcpp::Elf_types<64>::Elf_Swxword | |
2929 | 3037 | get_r_addend(const Reloc* reloc) |
2930 | 3038 | { return reloc->get_r_addend(); } |
2931 | 3039 |
@@ -2966,6 +3074,18 @@ class Mips_classify_reloc<sh_type_, 32, big_endian> : | ||
2966 | 3074 | get_r_type(const Reltype* reloc) |
2967 | 3075 | { return elfcpp::elf_r_type<32>(reloc->get_r_info()); } |
2968 | 3076 | |
3077 | + static inline unsigned int | |
3078 | + get_r_type2(const Reltype*) | |
3079 | + { return 0; } | |
3080 | + | |
3081 | + static inline unsigned int | |
3082 | + get_r_type3(const Reltype*) | |
3083 | + { return 0; } | |
3084 | + | |
3085 | + static inline unsigned int | |
3086 | + get_r_ssym(const Reltype*) | |
3087 | + { return 0; } | |
3088 | + | |
2969 | 3089 | // Return the explicit addend of the relocation (return 0 for SHT_REL). |
2970 | 3090 | static inline unsigned int |
2971 | 3091 | get_r_addend(const Reltype* reloc) |
@@ -3011,11 +3131,26 @@ class Mips_classify_reloc<sh_type_, 64, big_endian> : | ||
3011 | 3131 | get_r_sym(const Reltype* reloc) |
3012 | 3132 | { return reloc->get_r_sym(); } |
3013 | 3133 | |
3014 | - // Return the type of the relocation. | |
3134 | + // Return the r_type of the relocation. | |
3015 | 3135 | static inline unsigned int |
3016 | 3136 | get_r_type(const Reltype* reloc) |
3017 | 3137 | { return reloc->get_r_type(); } |
3018 | 3138 | |
3139 | + // Return the r_type2 of the relocation. | |
3140 | + static inline unsigned int | |
3141 | + get_r_type2(const Reltype* reloc) | |
3142 | + { return reloc->get_r_type2(); } | |
3143 | + | |
3144 | + // Return the r_type3 of the relocation. | |
3145 | + static inline unsigned int | |
3146 | + get_r_type3(const Reltype* reloc) | |
3147 | + { return reloc->get_r_type3(); } | |
3148 | + | |
3149 | + // Return the special symbol of the relocation. | |
3150 | + static inline unsigned int | |
3151 | + get_r_ssym(const Reltype* reloc) | |
3152 | + { return reloc->get_r_ssym(); } | |
3153 | + | |
3019 | 3154 | // Return the explicit addend of the relocation (return 0 for SHT_REL). |
3020 | 3155 | static inline typename elfcpp::Elf_types<64>::Elf_Swxword |
3021 | 3156 | get_r_addend(const Reltype* reloc) |
@@ -3053,10 +3188,8 @@ template<int size, bool big_endian> | ||
3053 | 3188 | class Target_mips : public Sized_target<size, big_endian> |
3054 | 3189 | { |
3055 | 3190 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address; |
3056 | - typedef Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian> | |
3191 | + typedef Mips_output_data_reloc<elfcpp::SHT_REL, true, size, big_endian> | |
3057 | 3192 | Reloc_section; |
3058 | - typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> | |
3059 | - Reloca_section; | |
3060 | 3193 | typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32; |
3061 | 3194 | typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype; |
3062 | 3195 | typedef typename Mips_reloc_types<elfcpp::SHT_REL, size, big_endian>::Reloc |
@@ -3600,12 +3733,12 @@ class Target_mips : public Sized_target<size, big_endian> | ||
3600 | 3733 | ~Relocate() |
3601 | 3734 | { } |
3602 | 3735 | |
3603 | - // Return whether the R_MIPS_32 relocation needs to be applied. | |
3736 | + // Return whether a R_MIPS_32/R_MIPS_64 relocation needs to be applied. | |
3604 | 3737 | inline bool |
3605 | - should_apply_r_mips_32_reloc(const Mips_symbol<size>* gsym, | |
3606 | - unsigned int r_type, | |
3607 | - Output_section* output_section, | |
3608 | - Target_mips* target); | |
3738 | + should_apply_static_reloc(const Mips_symbol<size>* gsym, | |
3739 | + unsigned int r_type, | |
3740 | + Output_section* output_section, | |
3741 | + Target_mips* target); | |
3609 | 3742 | |
3610 | 3743 | // Do a relocation. Return false if the caller should not issue |
3611 | 3744 | // any warnings about this relocation. |
@@ -3783,15 +3916,12 @@ class Target_mips : public Sized_target<size, big_endian> | ||
3783 | 3916 | copy_reloc(Symbol_table* symtab, Layout* layout, |
3784 | 3917 | Sized_relobj_file<size, big_endian>* object, |
3785 | 3918 | unsigned int shndx, Output_section* output_section, |
3786 | - Symbol* sym, const Reltype& reloc) | |
3919 | + Symbol* sym, unsigned int r_type, Mips_address r_offset) | |
3787 | 3920 | { |
3788 | - unsigned int r_type = | |
3789 | - Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>:: | |
3790 | - get_r_type(&reloc); | |
3791 | 3921 | this->copy_relocs_.copy_reloc(symtab, layout, |
3792 | 3922 | symtab->get_sized_symbol<size>(sym), |
3793 | 3923 | object, shndx, output_section, |
3794 | - r_type, reloc.get_r_offset(), 0, | |
3924 | + r_type, r_offset, 0, | |
3795 | 3925 | this->rel_dyn_section(layout)); |
3796 | 3926 | } |
3797 | 3927 |
@@ -3969,8 +4099,10 @@ template<int size, bool big_endian> | ||
3969 | 4099 | class Mips_relocate_functions : public Relocate_functions<size, big_endian> |
3970 | 4100 | { |
3971 | 4101 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address; |
4102 | + typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype; | |
3972 | 4103 | typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype16; |
3973 | 4104 | typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32; |
4105 | + typedef typename elfcpp::Swap<64, big_endian>::Valtype Valtype64; | |
3974 | 4106 | |
3975 | 4107 | public: |
3976 | 4108 | typedef enum |
@@ -3987,6 +4119,29 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
3987 | 4119 | static typename std::list<reloc_high<size, big_endian> > hi16_relocs; |
3988 | 4120 | static typename std::list<reloc_high<size, big_endian> > got16_relocs; |
3989 | 4121 | |
4122 | + template<int valsize> | |
4123 | + static inline typename This::Status | |
4124 | + check_overflow(Valtype value) | |
4125 | + { | |
4126 | + if (size == 32) | |
4127 | + return (Bits<valsize>::has_overflow32(value) | |
4128 | + ? This::STATUS_OVERFLOW | |
4129 | + : This::STATUS_OKAY); | |
4130 | + | |
4131 | + return (Bits<valsize>::has_overflow(value) | |
4132 | + ? This::STATUS_OVERFLOW | |
4133 | + : This::STATUS_OKAY); | |
4134 | + } | |
4135 | + | |
4136 | + static inline bool | |
4137 | + should_shuffle_micromips_reloc(unsigned int r_type) | |
4138 | + { | |
4139 | + return (micromips_reloc(r_type) | |
4140 | + && r_type != elfcpp::R_MICROMIPS_PC7_S1 | |
4141 | + && r_type != elfcpp::R_MICROMIPS_PC10_S1); | |
4142 | + } | |
4143 | + | |
4144 | + public: | |
3990 | 4145 | // R_MIPS16_26 is used for the mips16 jal and jalx instructions. |
3991 | 4146 | // Most mips16 instructions are 16 bits, but these instructions |
3992 | 4147 | // are 32 bits. |
@@ -4076,14 +4231,6 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4076 | 4231 | // on a little-endian system. This does not apply to R_MICROMIPS_PC7_S1 |
4077 | 4232 | // and R_MICROMIPS_PC10_S1 relocs that apply to 16-bit instructions. |
4078 | 4233 | |
4079 | - static inline bool | |
4080 | - should_shuffle_micromips_reloc(unsigned int r_type) | |
4081 | - { | |
4082 | - return (micromips_reloc(r_type) | |
4083 | - && r_type != elfcpp::R_MICROMIPS_PC7_S1 | |
4084 | - && r_type != elfcpp::R_MICROMIPS_PC10_S1); | |
4085 | - } | |
4086 | - | |
4087 | 4234 | static void |
4088 | 4235 | mips_reloc_unshuffle(unsigned char* view, unsigned int r_type, |
4089 | 4236 | bool jal_shuffle) |
@@ -4142,43 +4289,49 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4142 | 4289 | elfcpp::Swap<16, big_endian>::writeval(view, first); |
4143 | 4290 | } |
4144 | 4291 | |
4145 | - public: | |
4146 | 4292 | // R_MIPS_16: S + sign-extend(A) |
4147 | 4293 | static inline typename This::Status |
4148 | 4294 | rel16(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4149 | 4295 | const Symbol_value<size>* psymval, Mips_address addend_a, |
4150 | - bool extract_addend, unsigned int r_type) | |
4296 | + bool extract_addend, bool calculate_only, Valtype* calculated_value) | |
4151 | 4297 | { |
4152 | - mips_reloc_unshuffle(view, r_type, false); | |
4153 | 4298 | Valtype16* wv = reinterpret_cast<Valtype16*>(view); |
4154 | 4299 | Valtype16 val = elfcpp::Swap<16, big_endian>::readval(wv); |
4155 | 4300 | |
4156 | - Valtype32 addend = (extract_addend ? Bits<16>::sign_extend32(val) | |
4157 | - : Bits<16>::sign_extend32(addend_a)); | |
4301 | + Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val) | |
4302 | + : addend_a); | |
4158 | 4303 | |
4159 | - Valtype32 x = psymval->value(object, addend); | |
4304 | + Valtype x = psymval->value(object, addend); | |
4160 | 4305 | val = Bits<16>::bit_select32(val, x, 0xffffU); |
4161 | - elfcpp::Swap<16, big_endian>::writeval(wv, val); | |
4162 | - mips_reloc_shuffle(view, r_type, false); | |
4163 | - return (Bits<16>::has_overflow32(x) | |
4164 | - ? This::STATUS_OVERFLOW | |
4165 | - : This::STATUS_OKAY); | |
4306 | + | |
4307 | + if (calculate_only) | |
4308 | + { | |
4309 | + *calculated_value = x; | |
4310 | + return This::STATUS_OKAY; | |
4311 | + } | |
4312 | + else | |
4313 | + elfcpp::Swap<16, big_endian>::writeval(wv, val); | |
4314 | + | |
4315 | + return check_overflow<16>(x); | |
4166 | 4316 | } |
4167 | 4317 | |
4168 | 4318 | // R_MIPS_32: S + A |
4169 | 4319 | static inline typename This::Status |
4170 | 4320 | rel32(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4171 | 4321 | const Symbol_value<size>* psymval, Mips_address addend_a, |
4172 | - bool extract_addend, unsigned int r_type) | |
4322 | + bool extract_addend, bool calculate_only, Valtype* calculated_value) | |
4173 | 4323 | { |
4174 | - mips_reloc_unshuffle(view, r_type, false); | |
4175 | 4324 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4176 | - Valtype32 addend = (extract_addend | |
4325 | + Valtype addend = (extract_addend | |
4177 | 4326 | ? elfcpp::Swap<32, big_endian>::readval(wv) |
4178 | - : Bits<32>::sign_extend32(addend_a)); | |
4179 | - Valtype32 x = psymval->value(object, addend); | |
4180 | - elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4181 | - mips_reloc_shuffle(view, r_type, false); | |
4327 | + : addend_a); | |
4328 | + Valtype x = psymval->value(object, addend); | |
4329 | + | |
4330 | + if (calculate_only) | |
4331 | + *calculated_value = x; | |
4332 | + else | |
4333 | + elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4334 | + | |
4182 | 4335 | return This::STATUS_OKAY; |
4183 | 4336 | } |
4184 | 4337 |
@@ -4187,11 +4340,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4187 | 4340 | reljalr(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4188 | 4341 | const Symbol_value<size>* psymval, Mips_address address, |
4189 | 4342 | Mips_address addend_a, bool extract_addend, bool cross_mode_jump, |
4190 | - unsigned int r_type, bool jalr_to_bal, bool jr_to_b) | |
4343 | + unsigned int r_type, bool jalr_to_bal, bool jr_to_b, | |
4344 | + bool calculate_only, Valtype* calculated_value) | |
4191 | 4345 | { |
4192 | - mips_reloc_unshuffle(view, r_type, false); | |
4193 | 4346 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4194 | - Valtype32 addend = extract_addend ? 0 : addend_a; | |
4347 | + Valtype addend = extract_addend ? 0 : addend_a; | |
4195 | 4348 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4196 | 4349 | |
4197 | 4350 | // Try converting J(AL)R to B(AL), if the target is in range. |
@@ -4211,8 +4364,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4211 | 4364 | } |
4212 | 4365 | } |
4213 | 4366 | |
4214 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4215 | - mips_reloc_shuffle(view, r_type, false); | |
4367 | + if (calculate_only) | |
4368 | + *calculated_value = val; | |
4369 | + else | |
4370 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4371 | + | |
4216 | 4372 | return This::STATUS_OKAY; |
4217 | 4373 | } |
4218 | 4374 |
@@ -4220,16 +4376,20 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4220 | 4376 | static inline typename This::Status |
4221 | 4377 | relpc32(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4222 | 4378 | const Symbol_value<size>* psymval, Mips_address address, |
4223 | - Mips_address addend_a, bool extract_addend, unsigned int r_type) | |
4379 | + Mips_address addend_a, bool extract_addend, bool calculate_only, | |
4380 | + Valtype* calculated_value) | |
4224 | 4381 | { |
4225 | - mips_reloc_unshuffle(view, r_type, false); | |
4226 | 4382 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4227 | - Valtype32 addend = (extract_addend | |
4383 | + Valtype addend = (extract_addend | |
4228 | 4384 | ? elfcpp::Swap<32, big_endian>::readval(wv) |
4229 | - : Bits<32>::sign_extend32(addend_a)); | |
4230 | - Valtype32 x = psymval->value(object, addend) - address; | |
4231 | - elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4232 | - mips_reloc_shuffle(view, r_type, false); | |
4385 | + : addend_a); | |
4386 | + Valtype x = psymval->value(object, addend) - address; | |
4387 | + | |
4388 | + if (calculate_only) | |
4389 | + *calculated_value = x; | |
4390 | + else | |
4391 | + elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4392 | + | |
4233 | 4393 | return This::STATUS_OKAY; |
4234 | 4394 | } |
4235 | 4395 |
@@ -4239,13 +4399,12 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4239 | 4399 | const Symbol_value<size>* psymval, Mips_address address, |
4240 | 4400 | bool local, Mips_address addend_a, bool extract_addend, |
4241 | 4401 | const Symbol* gsym, bool cross_mode_jump, unsigned int r_type, |
4242 | - bool jal_to_bal) | |
4402 | + bool jal_to_bal, bool calculate_only, Valtype* calculated_value) | |
4243 | 4403 | { |
4244 | - mips_reloc_unshuffle(view, r_type, false); | |
4245 | 4404 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4246 | 4405 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4247 | 4406 | |
4248 | - Valtype32 addend; | |
4407 | + Valtype addend; | |
4249 | 4408 | if (extract_addend) |
4250 | 4409 | { |
4251 | 4410 | if (r_type == elfcpp::R_MICROMIPS_26_S1) |
@@ -4258,11 +4417,10 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4258 | 4417 | |
4259 | 4418 | // Make sure the target of JALX is word-aligned. Bit 0 must be |
4260 | 4419 | // the correct ISA mode selector and bit 1 must be 0. |
4261 | - if (cross_mode_jump | |
4420 | + if (!calculate_only && cross_mode_jump | |
4262 | 4421 | && (psymval->value(object, 0) & 3) != (r_type == elfcpp::R_MIPS_26)) |
4263 | 4422 | { |
4264 | 4423 | gold_warning(_("JALX to a non-word-aligned address")); |
4265 | - mips_reloc_shuffle(view, r_type, !parameters->options().relocatable()); | |
4266 | 4424 | return This::STATUS_BAD_RELOC; |
4267 | 4425 | } |
4268 | 4426 |
@@ -4270,7 +4428,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4270 | 4428 | unsigned int shift = |
4271 | 4429 | (!cross_mode_jump && r_type == elfcpp::R_MICROMIPS_26_S1) ? 1 : 2; |
4272 | 4430 | |
4273 | - Valtype32 x; | |
4431 | + Valtype x; | |
4274 | 4432 | if (local) |
4275 | 4433 | x = addend | ((address + 4) & (0xfc000000 << shift)); |
4276 | 4434 | else |
@@ -4282,7 +4440,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4282 | 4440 | } |
4283 | 4441 | x = psymval->value(object, x) >> shift; |
4284 | 4442 | |
4285 | - if (!local && !gsym->is_weak_undefined()) | |
4443 | + if (!calculate_only && !local && !gsym->is_weak_undefined()) | |
4286 | 4444 | { |
4287 | 4445 | if ((x >> 26) != ((address + 4) >> (26 + shift))) |
4288 | 4446 | { |
@@ -4320,7 +4478,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4320 | 4478 | |
4321 | 4479 | // If the opcode is not JAL or JALX, there's a problem. We cannot |
4322 | 4480 | // convert J or JALS to JALX. |
4323 | - if (!ok) | |
4481 | + if (!calculate_only && !ok) | |
4324 | 4482 | { |
4325 | 4483 | gold_error(_("Unsupported jump between ISA modes; consider " |
4326 | 4484 | "recompiling with interlinking enabled.")); |
@@ -4349,8 +4507,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4349 | 4507 | } |
4350 | 4508 | } |
4351 | 4509 | |
4352 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4353 | - mips_reloc_shuffle(view, r_type, !parameters->options().relocatable()); | |
4510 | + if (calculate_only) | |
4511 | + *calculated_value = val; | |
4512 | + else | |
4513 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4514 | + | |
4354 | 4515 | return This::STATUS_OKAY; |
4355 | 4516 | } |
4356 | 4517 |
@@ -4358,22 +4519,28 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4358 | 4519 | static inline typename This::Status |
4359 | 4520 | relpc16(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4360 | 4521 | const Symbol_value<size>* psymval, Mips_address address, |
4361 | - Mips_address addend_a, bool extract_addend, unsigned int r_type) | |
4522 | + Mips_address addend_a, bool extract_addend, bool calculate_only, | |
4523 | + Valtype* calculated_value) | |
4362 | 4524 | { |
4363 | - mips_reloc_unshuffle(view, r_type, false); | |
4364 | 4525 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4365 | 4526 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4366 | 4527 | |
4367 | - Valtype32 addend = extract_addend ? (val & 0xffff) << 2 : addend_a; | |
4368 | - addend = Bits<18>::sign_extend32(addend); | |
4528 | + Valtype addend = (extract_addend | |
4529 | + ? Bits<18>::sign_extend32((val & 0xffff) << 2) | |
4530 | + : addend_a); | |
4369 | 4531 | |
4370 | - Valtype32 x = psymval->value(object, addend) - address; | |
4532 | + Valtype x = psymval->value(object, addend) - address; | |
4371 | 4533 | val = Bits<16>::bit_select32(val, x >> 2, 0xffff); |
4372 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4373 | - mips_reloc_shuffle(view, r_type, false); | |
4374 | - return (Bits<18>::has_overflow32(x) | |
4375 | - ? This::STATUS_OVERFLOW | |
4376 | - : This::STATUS_OKAY); | |
4534 | + | |
4535 | + if (calculate_only) | |
4536 | + { | |
4537 | + *calculated_value = x >> 2; | |
4538 | + return This::STATUS_OKAY; | |
4539 | + } | |
4540 | + else | |
4541 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4542 | + | |
4543 | + return check_overflow<18>(x); | |
4377 | 4544 | } |
4378 | 4545 | |
4379 | 4546 | // R_MICROMIPS_PC7_S1 |
@@ -4382,22 +4549,26 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4382 | 4549 | const Mips_relobj<size, big_endian>* object, |
4383 | 4550 | const Symbol_value<size>* psymval, Mips_address address, |
4384 | 4551 | Mips_address addend_a, bool extract_addend, |
4385 | - unsigned int r_type) | |
4552 | + bool calculate_only, Valtype* calculated_value) | |
4386 | 4553 | { |
4387 | - mips_reloc_unshuffle(view, r_type, false); | |
4388 | 4554 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4389 | 4555 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4390 | 4556 | |
4391 | - Valtype32 addend = extract_addend ? (val & 0x7f) << 1 : addend_a; | |
4392 | - addend = Bits<8>::sign_extend32(addend); | |
4557 | + Valtype addend = extract_addend ? Bits<8>::sign_extend32((val & 0x7f) << 1) | |
4558 | + : addend_a; | |
4393 | 4559 | |
4394 | - Valtype32 x = psymval->value(object, addend) - address; | |
4560 | + Valtype x = psymval->value(object, addend) - address; | |
4395 | 4561 | val = Bits<16>::bit_select32(val, x >> 1, 0x7f); |
4396 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4397 | - mips_reloc_shuffle(view, r_type, false); | |
4398 | - return (Bits<8>::has_overflow32(x) | |
4399 | - ? This::STATUS_OVERFLOW | |
4400 | - : This::STATUS_OKAY); | |
4562 | + | |
4563 | + if (calculate_only) | |
4564 | + { | |
4565 | + *calculated_value = x >> 1; | |
4566 | + return This::STATUS_OKAY; | |
4567 | + } | |
4568 | + else | |
4569 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4570 | + | |
4571 | + return check_overflow<8>(x); | |
4401 | 4572 | } |
4402 | 4573 | |
4403 | 4574 | // R_MICROMIPS_PC10_S1 |
@@ -4406,22 +4577,27 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4406 | 4577 | const Mips_relobj<size, big_endian>* object, |
4407 | 4578 | const Symbol_value<size>* psymval, Mips_address address, |
4408 | 4579 | Mips_address addend_a, bool extract_addend, |
4409 | - unsigned int r_type) | |
4580 | + bool calculate_only, Valtype* calculated_value) | |
4410 | 4581 | { |
4411 | - mips_reloc_unshuffle(view, r_type, false); | |
4412 | 4582 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4413 | 4583 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4414 | 4584 | |
4415 | - Valtype32 addend = extract_addend ? (val & 0x3ff) << 1 : addend_a; | |
4416 | - addend = Bits<11>::sign_extend32(addend); | |
4585 | + Valtype addend = (extract_addend | |
4586 | + ? Bits<11>::sign_extend32((val & 0x3ff) << 1) | |
4587 | + : addend_a); | |
4417 | 4588 | |
4418 | - Valtype32 x = psymval->value(object, addend) - address; | |
4589 | + Valtype x = psymval->value(object, addend) - address; | |
4419 | 4590 | val = Bits<16>::bit_select32(val, x >> 1, 0x3ff); |
4420 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4421 | - mips_reloc_shuffle(view, r_type, false); | |
4422 | - return (Bits<11>::has_overflow32(x) | |
4423 | - ? This::STATUS_OVERFLOW | |
4424 | - : This::STATUS_OKAY); | |
4591 | + | |
4592 | + if (calculate_only) | |
4593 | + { | |
4594 | + *calculated_value = x >> 1; | |
4595 | + return This::STATUS_OKAY; | |
4596 | + } | |
4597 | + else | |
4598 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4599 | + | |
4600 | + return check_overflow<11>(x); | |
4425 | 4601 | } |
4426 | 4602 | |
4427 | 4603 | // R_MICROMIPS_PC16_S1 |
@@ -4430,22 +4606,27 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4430 | 4606 | const Mips_relobj<size, big_endian>* object, |
4431 | 4607 | const Symbol_value<size>* psymval, Mips_address address, |
4432 | 4608 | Mips_address addend_a, bool extract_addend, |
4433 | - unsigned int r_type) | |
4609 | + bool calculate_only, Valtype* calculated_value) | |
4434 | 4610 | { |
4435 | - mips_reloc_unshuffle(view, r_type, false); | |
4436 | 4611 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4437 | 4612 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4438 | 4613 | |
4439 | - Valtype32 addend = extract_addend ? (val & 0xffff) << 1 : addend_a; | |
4440 | - addend = Bits<17>::sign_extend32(addend); | |
4614 | + Valtype addend = (extract_addend | |
4615 | + ? Bits<17>::sign_extend32((val & 0xffff) << 1) | |
4616 | + : addend_a); | |
4441 | 4617 | |
4442 | - Valtype32 x = psymval->value(object, addend) - address; | |
4618 | + Valtype x = psymval->value(object, addend) - address; | |
4443 | 4619 | val = Bits<16>::bit_select32(val, x >> 1, 0xffff); |
4444 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4445 | - mips_reloc_shuffle(view, r_type, false); | |
4446 | - return (Bits<17>::has_overflow32(x) | |
4447 | - ? This::STATUS_OVERFLOW | |
4448 | - : This::STATUS_OKAY); | |
4620 | + | |
4621 | + if (calculate_only) | |
4622 | + { | |
4623 | + *calculated_value = x >> 1; | |
4624 | + return This::STATUS_OKAY; | |
4625 | + } | |
4626 | + else | |
4627 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4628 | + | |
4629 | + return check_overflow<17>(x); | |
4449 | 4630 | } |
4450 | 4631 | |
4451 | 4632 | // R_MIPS_HI16, R_MIPS16_HI16, R_MICROMIPS_HI16, |
@@ -4468,13 +4649,13 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4468 | 4649 | const Symbol_value<size>* psymval, Mips_address addend_hi, |
4469 | 4650 | Mips_address address, bool is_gp_disp, unsigned int r_type, |
4470 | 4651 | bool extract_addend, Valtype32 addend_lo, |
4471 | - Target_mips<size, big_endian>* target) | |
4652 | + Target_mips<size, big_endian>* target, bool calculate_only, | |
4653 | + Valtype* calculated_value) | |
4472 | 4654 | { |
4473 | - mips_reloc_unshuffle(view, r_type, false); | |
4474 | 4655 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4475 | 4656 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4476 | 4657 | |
4477 | - Valtype32 addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo | |
4658 | + Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo | |
4478 | 4659 | : addend_hi); |
4479 | 4660 | |
4480 | 4661 | Valtype32 value; |
@@ -4505,13 +4686,19 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4505 | 4686 | gp_disp = target->adjusted_gp_value(object) - address; |
4506 | 4687 | value = gp_disp + addend; |
4507 | 4688 | } |
4508 | - Valtype32 x = ((value + 0x8000) >> 16) & 0xffff; | |
4689 | + Valtype x = ((value + 0x8000) >> 16) & 0xffff; | |
4509 | 4690 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4510 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4511 | - mips_reloc_shuffle(view, r_type, false); | |
4512 | - return (is_gp_disp && Bits<16>::has_overflow32(x) | |
4513 | - ? This::STATUS_OVERFLOW | |
4514 | - : This::STATUS_OKAY); | |
4691 | + | |
4692 | + if (calculate_only) | |
4693 | + { | |
4694 | + *calculated_value = x; | |
4695 | + return This::STATUS_OKAY; | |
4696 | + } | |
4697 | + else | |
4698 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4699 | + | |
4700 | + return (is_gp_disp ? check_overflow<16>(x) | |
4701 | + : This::STATUS_OKAY); | |
4515 | 4702 | } |
4516 | 4703 | |
4517 | 4704 | // R_MIPS_GOT16, R_MIPS16_GOT16, R_MICROMIPS_GOT16 |
@@ -4532,14 +4719,14 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4532 | 4719 | do_relgot16_local(unsigned char* view, |
4533 | 4720 | const Mips_relobj<size, big_endian>* object, |
4534 | 4721 | const Symbol_value<size>* psymval, Mips_address addend_hi, |
4535 | - unsigned int r_type, bool extract_addend, | |
4536 | - Valtype32 addend_lo, Target_mips<size, big_endian>* target) | |
4722 | + bool extract_addend, Valtype32 addend_lo, | |
4723 | + Target_mips<size, big_endian>* target, bool calculate_only, | |
4724 | + Valtype* calculated_value) | |
4537 | 4725 | { |
4538 | - mips_reloc_unshuffle(view, r_type, false); | |
4539 | 4726 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4540 | 4727 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4541 | 4728 | |
4542 | - Valtype32 addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo | |
4729 | + Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo | |
4543 | 4730 | : addend_hi); |
4544 | 4731 | |
4545 | 4732 | // Find GOT page entry. |
@@ -4550,13 +4737,18 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4550 | 4737 | target->got_section()->get_got_page_offset(value, object); |
4551 | 4738 | |
4552 | 4739 | // Resolve the relocation. |
4553 | - Valtype32 x = target->got_section()->gp_offset(got_offset, object); | |
4740 | + Valtype x = target->got_section()->gp_offset(got_offset, object); | |
4554 | 4741 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4555 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4556 | - mips_reloc_shuffle(view, r_type, false); | |
4557 | - return (Bits<16>::has_overflow32(x) | |
4558 | - ? This::STATUS_OVERFLOW | |
4559 | - : This::STATUS_OKAY); | |
4742 | + | |
4743 | + if (calculate_only) | |
4744 | + { | |
4745 | + *calculated_value = x; | |
4746 | + return This::STATUS_OKAY; | |
4747 | + } | |
4748 | + else | |
4749 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4750 | + | |
4751 | + return check_overflow<16>(x); | |
4560 | 4752 | } |
4561 | 4753 | |
4562 | 4754 | // R_MIPS_LO16, R_MIPS16_LO16, R_MICROMIPS_LO16, R_MICROMIPS_HI0_LO16 |
@@ -4565,57 +4757,69 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4565 | 4757 | const Mips_relobj<size, big_endian>* object, |
4566 | 4758 | const Symbol_value<size>* psymval, Mips_address addend_a, |
4567 | 4759 | bool extract_addend, Mips_address address, bool is_gp_disp, |
4568 | - unsigned int r_type, unsigned int r_sym) | |
4760 | + unsigned int r_type, unsigned int r_sym, unsigned int rel_type, | |
4761 | + bool calculate_only, Valtype* calculated_value) | |
4569 | 4762 | { |
4570 | - mips_reloc_unshuffle(view, r_type, false); | |
4571 | 4763 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4572 | 4764 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4573 | 4765 | |
4574 | - Valtype32 addend = (extract_addend ? Bits<16>::sign_extend32(val & 0xffff) | |
4575 | - : addend_a); | |
4766 | + Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val & 0xffff) | |
4767 | + : addend_a); | |
4576 | 4768 | |
4577 | - // Resolve pending R_MIPS_HI16 relocations. | |
4578 | - typename std::list<reloc_high<size, big_endian> >::iterator it = | |
4579 | - hi16_relocs.begin(); | |
4580 | - while (it != hi16_relocs.end()) | |
4769 | + if (rel_type == elfcpp::SHT_REL) | |
4581 | 4770 | { |
4582 | - reloc_high<size, big_endian> hi16 = *it; | |
4583 | - if (hi16.r_sym == r_sym | |
4584 | - && is_matching_lo16_reloc(hi16.r_type, r_type)) | |
4771 | + typename This::Status reloc_status = This::STATUS_OKAY; | |
4772 | + // Resolve pending R_MIPS_HI16 relocations. | |
4773 | + typename std::list<reloc_high<size, big_endian> >::iterator it = | |
4774 | + hi16_relocs.begin(); | |
4775 | + while (it != hi16_relocs.end()) | |
4585 | 4776 | { |
4586 | - if (do_relhi16(hi16.view, hi16.object, hi16.psymval, hi16.addend, | |
4587 | - hi16.address, hi16.gp_disp, hi16.r_type, | |
4588 | - hi16.extract_addend, addend, target) | |
4589 | - == This::STATUS_OVERFLOW) | |
4590 | - return This::STATUS_OVERFLOW; | |
4591 | - it = hi16_relocs.erase(it); | |
4777 | + reloc_high<size, big_endian> hi16 = *it; | |
4778 | + if (hi16.r_sym == r_sym | |
4779 | + && is_matching_lo16_reloc(hi16.r_type, r_type)) | |
4780 | + { | |
4781 | + mips_reloc_unshuffle(hi16.view, hi16.r_type, false); | |
4782 | + reloc_status = do_relhi16(hi16.view, hi16.object, hi16.psymval, | |
4783 | + hi16.addend, hi16.address, hi16.gp_disp, | |
4784 | + hi16.r_type, hi16.extract_addend, addend, | |
4785 | + target, calculate_only, calculated_value); | |
4786 | + mips_reloc_shuffle(hi16.view, hi16.r_type, false); | |
4787 | + if (reloc_status == This::STATUS_OVERFLOW) | |
4788 | + return This::STATUS_OVERFLOW; | |
4789 | + it = hi16_relocs.erase(it); | |
4790 | + } | |
4791 | + else | |
4792 | + ++it; | |
4592 | 4793 | } |
4593 | - else | |
4594 | - ++it; | |
4595 | - } | |
4596 | 4794 | |
4597 | - // Resolve pending local R_MIPS_GOT16 relocations. | |
4598 | - typename std::list<reloc_high<size, big_endian> >::iterator it2 = | |
4599 | - got16_relocs.begin(); | |
4600 | - while (it2 != got16_relocs.end()) | |
4601 | - { | |
4602 | - reloc_high<size, big_endian> got16 = *it2; | |
4603 | - if (got16.r_sym == r_sym | |
4604 | - && is_matching_lo16_reloc(got16.r_type, r_type)) | |
4795 | + // Resolve pending local R_MIPS_GOT16 relocations. | |
4796 | + typename std::list<reloc_high<size, big_endian> >::iterator it2 = | |
4797 | + got16_relocs.begin(); | |
4798 | + while (it2 != got16_relocs.end()) | |
4605 | 4799 | { |
4606 | - if (do_relgot16_local(got16.view, got16.object, got16.psymval, | |
4607 | - got16.addend, got16.r_type, | |
4608 | - got16.extract_addend, addend, | |
4609 | - target) == This::STATUS_OVERFLOW) | |
4610 | - return This::STATUS_OVERFLOW; | |
4611 | - it2 = got16_relocs.erase(it2); | |
4800 | + reloc_high<size, big_endian> got16 = *it2; | |
4801 | + if (got16.r_sym == r_sym | |
4802 | + && is_matching_lo16_reloc(got16.r_type, r_type)) | |
4803 | + { | |
4804 | + mips_reloc_unshuffle(got16.view, got16.r_type, false); | |
4805 | + | |
4806 | + reloc_status = do_relgot16_local(got16.view, got16.object, | |
4807 | + got16.psymval, got16.addend, | |
4808 | + got16.extract_addend, addend, target, | |
4809 | + calculate_only, calculated_value); | |
4810 | + | |
4811 | + mips_reloc_shuffle(got16.view, got16.r_type, false); | |
4812 | + if (reloc_status == This::STATUS_OVERFLOW) | |
4813 | + return This::STATUS_OVERFLOW; | |
4814 | + it2 = got16_relocs.erase(it2); | |
4815 | + } | |
4816 | + else | |
4817 | + ++it2; | |
4612 | 4818 | } |
4613 | - else | |
4614 | - ++it2; | |
4615 | 4819 | } |
4616 | 4820 | |
4617 | 4821 | // Resolve R_MIPS_LO16 relocation. |
4618 | - Valtype32 x; | |
4822 | + Valtype x; | |
4619 | 4823 | if (!is_gp_disp) |
4620 | 4824 | x = psymval->value(object, addend); |
4621 | 4825 | else |
@@ -4648,8 +4852,12 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4648 | 4852 | x = gp_disp + addend; |
4649 | 4853 | } |
4650 | 4854 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4651 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4652 | - mips_reloc_shuffle(view, r_type, false); | |
4855 | + | |
4856 | + if (calculate_only) | |
4857 | + *calculated_value = x; | |
4858 | + else | |
4859 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4860 | + | |
4653 | 4861 | return This::STATUS_OKAY; |
4654 | 4862 | } |
4655 | 4863 |
@@ -4660,18 +4868,42 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4660 | 4868 | // R_MIPS_TLS_LDM, R_MIPS16_TLS_LDM, R_MICROMIPS_TLS_LDM |
4661 | 4869 | // R_MIPS_GOT_DISP, R_MICROMIPS_GOT_DISP |
4662 | 4870 | static inline typename This::Status |
4663 | - relgot(unsigned char* view, int gp_offset, unsigned int r_type) | |
4871 | + relgot(unsigned char* view, int gp_offset, bool calculate_only, | |
4872 | + Valtype* calculated_value) | |
4664 | 4873 | { |
4665 | - mips_reloc_unshuffle(view, r_type, false); | |
4666 | 4874 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4667 | 4875 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4668 | - Valtype32 x = gp_offset; | |
4876 | + Valtype x = gp_offset; | |
4669 | 4877 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4670 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4671 | - mips_reloc_shuffle(view, r_type, false); | |
4672 | - return (Bits<16>::has_overflow32(x) | |
4673 | - ? This::STATUS_OVERFLOW | |
4674 | - : This::STATUS_OKAY); | |
4878 | + | |
4879 | + if (calculate_only) | |
4880 | + { | |
4881 | + *calculated_value = x; | |
4882 | + return This::STATUS_OKAY; | |
4883 | + } | |
4884 | + else | |
4885 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4886 | + | |
4887 | + return check_overflow<16>(x); | |
4888 | + } | |
4889 | + | |
4890 | + // R_MIPS_EH | |
4891 | + static inline typename This::Status | |
4892 | + releh(unsigned char* view, int gp_offset, bool calculate_only, | |
4893 | + Valtype* calculated_value) | |
4894 | + { | |
4895 | + Valtype32* wv = reinterpret_cast<Valtype32*>(view); | |
4896 | + Valtype x = gp_offset; | |
4897 | + | |
4898 | + if (calculate_only) | |
4899 | + { | |
4900 | + *calculated_value = x; | |
4901 | + return This::STATUS_OKAY; | |
4902 | + } | |
4903 | + else | |
4904 | + elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4905 | + | |
4906 | + return check_overflow<32>(x); | |
4675 | 4907 | } |
4676 | 4908 | |
4677 | 4909 | // R_MIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE |
@@ -4679,25 +4911,30 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4679 | 4911 | relgotpage(Target_mips<size, big_endian>* target, unsigned char* view, |
4680 | 4912 | const Mips_relobj<size, big_endian>* object, |
4681 | 4913 | const Symbol_value<size>* psymval, Mips_address addend_a, |
4682 | - bool extract_addend, unsigned int r_type) | |
4914 | + bool extract_addend, bool calculate_only, | |
4915 | + Valtype* calculated_value) | |
4683 | 4916 | { |
4684 | - mips_reloc_unshuffle(view, r_type, false); | |
4685 | 4917 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4686 | 4918 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view); |
4687 | - Valtype32 addend = extract_addend ? val & 0xffff : addend_a; | |
4919 | + Valtype addend = extract_addend ? val & 0xffff : addend_a; | |
4688 | 4920 | |
4689 | 4921 | // Find a GOT page entry that points to within 32KB of symbol + addend. |
4690 | 4922 | Mips_address value = (psymval->value(object, addend) + 0x8000) & ~0xffff; |
4691 | 4923 | unsigned int got_offset = |
4692 | 4924 | target->got_section()->get_got_page_offset(value, object); |
4693 | 4925 | |
4694 | - Valtype32 x = target->got_section()->gp_offset(got_offset, object); | |
4926 | + Valtype x = target->got_section()->gp_offset(got_offset, object); | |
4695 | 4927 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4696 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4697 | - mips_reloc_shuffle(view, r_type, false); | |
4698 | - return (Bits<16>::has_overflow32(x) | |
4699 | - ? This::STATUS_OVERFLOW | |
4700 | - : This::STATUS_OKAY); | |
4928 | + | |
4929 | + if (calculate_only) | |
4930 | + { | |
4931 | + *calculated_value = x; | |
4932 | + return This::STATUS_OKAY; | |
4933 | + } | |
4934 | + else | |
4935 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4936 | + | |
4937 | + return check_overflow<16>(x); | |
4701 | 4938 | } |
4702 | 4939 | |
4703 | 4940 | // R_MIPS_GOT_OFST, R_MICROMIPS_GOT_OFST |
@@ -4705,18 +4942,18 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4705 | 4942 | relgotofst(Target_mips<size, big_endian>* target, unsigned char* view, |
4706 | 4943 | const Mips_relobj<size, big_endian>* object, |
4707 | 4944 | const Symbol_value<size>* psymval, Mips_address addend_a, |
4708 | - bool extract_addend, bool local, unsigned int r_type) | |
4945 | + bool extract_addend, bool local, bool calculate_only, | |
4946 | + Valtype* calculated_value) | |
4709 | 4947 | { |
4710 | - mips_reloc_unshuffle(view, r_type, false); | |
4711 | 4948 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4712 | 4949 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view); |
4713 | - Valtype32 addend = extract_addend ? val & 0xffff : addend_a; | |
4950 | + Valtype addend = extract_addend ? val & 0xffff : addend_a; | |
4714 | 4951 | |
4715 | 4952 | // For a local symbol, find a GOT page entry that points to within 32KB of |
4716 | 4953 | // symbol + addend. Relocation value is the offset of the GOT page entry's |
4717 | 4954 | // value from symbol + addend. |
4718 | 4955 | // For a global symbol, relocation value is addend. |
4719 | - Valtype32 x; | |
4956 | + Valtype x; | |
4720 | 4957 | if (local) |
4721 | 4958 | { |
4722 | 4959 | // Find GOT page entry. |
@@ -4729,41 +4966,54 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4729 | 4966 | else |
4730 | 4967 | x = addend; |
4731 | 4968 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4732 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4733 | - mips_reloc_shuffle(view, r_type, false); | |
4734 | - return (Bits<16>::has_overflow32(x) | |
4735 | - ? This::STATUS_OVERFLOW | |
4736 | - : This::STATUS_OKAY); | |
4969 | + | |
4970 | + if (calculate_only) | |
4971 | + { | |
4972 | + *calculated_value = x; | |
4973 | + return This::STATUS_OKAY; | |
4974 | + } | |
4975 | + else | |
4976 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4977 | + | |
4978 | + return check_overflow<16>(x); | |
4737 | 4979 | } |
4738 | 4980 | |
4739 | 4981 | // R_MIPS_GOT_HI16, R_MIPS_CALL_HI16, |
4740 | 4982 | // R_MICROMIPS_GOT_HI16, R_MICROMIPS_CALL_HI16 |
4741 | 4983 | static inline typename This::Status |
4742 | - relgot_hi16(unsigned char* view, int gp_offset, unsigned int r_type) | |
4984 | + relgot_hi16(unsigned char* view, int gp_offset, bool calculate_only, | |
4985 | + Valtype* calculated_value) | |
4743 | 4986 | { |
4744 | - mips_reloc_unshuffle(view, r_type, false); | |
4745 | 4987 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4746 | 4988 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4747 | - Valtype32 x = gp_offset; | |
4989 | + Valtype x = gp_offset; | |
4748 | 4990 | x = ((x + 0x8000) >> 16) & 0xffff; |
4749 | 4991 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4750 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4751 | - mips_reloc_shuffle(view, r_type, false); | |
4992 | + | |
4993 | + if (calculate_only) | |
4994 | + *calculated_value = x; | |
4995 | + else | |
4996 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4997 | + | |
4752 | 4998 | return This::STATUS_OKAY; |
4753 | 4999 | } |
4754 | 5000 | |
4755 | 5001 | // R_MIPS_GOT_LO16, R_MIPS_CALL_LO16, |
4756 | 5002 | // R_MICROMIPS_GOT_LO16, R_MICROMIPS_CALL_LO16 |
4757 | 5003 | static inline typename This::Status |
4758 | - relgot_lo16(unsigned char* view, int gp_offset, unsigned int r_type) | |
5004 | + relgot_lo16(unsigned char* view, int gp_offset, bool calculate_only, | |
5005 | + Valtype* calculated_value) | |
4759 | 5006 | { |
4760 | - mips_reloc_unshuffle(view, r_type, false); | |
4761 | 5007 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4762 | 5008 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4763 | - Valtype32 x = gp_offset; | |
5009 | + Valtype x = gp_offset; | |
4764 | 5010 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4765 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4766 | - mips_reloc_shuffle(view, r_type, false); | |
5011 | + | |
5012 | + if (calculate_only) | |
5013 | + *calculated_value = x; | |
5014 | + else | |
5015 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
5016 | + | |
4767 | 5017 | return This::STATUS_OKAY; |
4768 | 5018 | } |
4769 | 5019 |
@@ -4773,13 +5023,13 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4773 | 5023 | relgprel(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4774 | 5024 | const Symbol_value<size>* psymval, Mips_address gp, |
4775 | 5025 | Mips_address addend_a, bool extract_addend, bool local, |
4776 | - unsigned int r_type) | |
5026 | + unsigned int r_type, bool calculate_only, | |
5027 | + Valtype* calculated_value) | |
4777 | 5028 | { |
4778 | - mips_reloc_unshuffle(view, r_type, false); | |
4779 | 5029 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4780 | 5030 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4781 | 5031 | |
4782 | - Valtype32 addend; | |
5032 | + Valtype addend; | |
4783 | 5033 | if (extract_addend) |
4784 | 5034 | { |
4785 | 5035 | if (r_type == elfcpp::R_MICROMIPS_GPREL7_S2) |
@@ -4794,7 +5044,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4794 | 5044 | else |
4795 | 5045 | addend = addend_a; |
4796 | 5046 | |
4797 | - Valtype32 x = psymval->value(object, addend) - gp; | |
5047 | + Valtype x = psymval->value(object, addend) - gp; | |
4798 | 5048 | |
4799 | 5049 | // If the symbol was local, any earlier relocatable links will |
4800 | 5050 | // have adjusted its addend with the gp offset, so compensate |
@@ -4808,9 +5058,16 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4808 | 5058 | val = Bits<32>::bit_select32(val, x, 0x7f); |
4809 | 5059 | else |
4810 | 5060 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4811 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4812 | - mips_reloc_shuffle(view, r_type, false); | |
4813 | - if (Bits<16>::has_overflow32(x)) | |
5061 | + | |
5062 | + if (calculate_only) | |
5063 | + { | |
5064 | + *calculated_value = x; | |
5065 | + return This::STATUS_OKAY; | |
5066 | + } | |
5067 | + else | |
5068 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
5069 | + | |
5070 | + if (check_overflow<16>(x) == This::STATUS_OVERFLOW) | |
4814 | 5071 | { |
4815 | 5072 | gold_error(_("small-data section exceeds 64KB; lower small-data size " |
4816 | 5073 | "limit (see option -G)")); |
@@ -4823,17 +5080,21 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4823 | 5080 | static inline typename This::Status |
4824 | 5081 | relgprel32(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4825 | 5082 | const Symbol_value<size>* psymval, Mips_address gp, |
4826 | - Mips_address addend_a, bool extract_addend, unsigned int r_type) | |
5083 | + Mips_address addend_a, bool extract_addend, bool calculate_only, | |
5084 | + Valtype* calculated_value) | |
4827 | 5085 | { |
4828 | - mips_reloc_unshuffle(view, r_type, false); | |
4829 | 5086 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4830 | 5087 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4831 | - Valtype32 addend = extract_addend ? val : addend_a; | |
5088 | + Valtype addend = extract_addend ? val : addend_a; | |
4832 | 5089 | |
4833 | 5090 | // R_MIPS_GPREL32 relocations are defined for local symbols only. |
4834 | - Valtype32 x = psymval->value(object, addend) + object->gp_value() - gp; | |
4835 | - elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4836 | - mips_reloc_shuffle(view, r_type, false); | |
5091 | + Valtype x = psymval->value(object, addend) + object->gp_value() - gp; | |
5092 | + | |
5093 | + if (calculate_only) | |
5094 | + *calculated_value = x; | |
5095 | + else | |
5096 | + elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
5097 | + | |
4837 | 5098 | return This::STATUS_OKAY; |
4838 | 5099 | } |
4839 | 5100 |
@@ -4843,18 +5104,22 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4843 | 5104 | static inline typename This::Status |
4844 | 5105 | tlsrelhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4845 | 5106 | const Symbol_value<size>* psymval, Valtype32 tp_offset, |
4846 | - Mips_address addend_a, bool extract_addend, unsigned int r_type) | |
5107 | + Mips_address addend_a, bool extract_addend, bool calculate_only, | |
5108 | + Valtype* calculated_value) | |
4847 | 5109 | { |
4848 | - mips_reloc_unshuffle(view, r_type, false); | |
4849 | 5110 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4850 | 5111 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4851 | - Valtype32 addend = extract_addend ? val & 0xffff : addend_a; | |
5112 | + Valtype addend = extract_addend ? val & 0xffff : addend_a; | |
4852 | 5113 | |
4853 | 5114 | // tls symbol values are relative to tls_segment()->vaddr() |
4854 | - Valtype32 x = ((psymval->value(object, addend) - tp_offset) + 0x8000) >> 16; | |
5115 | + Valtype x = ((psymval->value(object, addend) - tp_offset) + 0x8000) >> 16; | |
4855 | 5116 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4856 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4857 | - mips_reloc_shuffle(view, r_type, false); | |
5117 | + | |
5118 | + if (calculate_only) | |
5119 | + *calculated_value = x; | |
5120 | + else | |
5121 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
5122 | + | |
4858 | 5123 | return This::STATUS_OKAY; |
4859 | 5124 | } |
4860 | 5125 |
@@ -4864,18 +5129,22 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4864 | 5129 | static inline typename This::Status |
4865 | 5130 | tlsrello16(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4866 | 5131 | const Symbol_value<size>* psymval, Valtype32 tp_offset, |
4867 | - Mips_address addend_a, bool extract_addend, unsigned int r_type) | |
5132 | + Mips_address addend_a, bool extract_addend, bool calculate_only, | |
5133 | + Valtype* calculated_value) | |
4868 | 5134 | { |
4869 | - mips_reloc_unshuffle(view, r_type, false); | |
4870 | 5135 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4871 | 5136 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4872 | - Valtype32 addend = extract_addend ? val & 0xffff : addend_a; | |
5137 | + Valtype addend = extract_addend ? val & 0xffff : addend_a; | |
4873 | 5138 | |
4874 | 5139 | // tls symbol values are relative to tls_segment()->vaddr() |
4875 | - Valtype32 x = psymval->value(object, addend) - tp_offset; | |
5140 | + Valtype x = psymval->value(object, addend) - tp_offset; | |
4876 | 5141 | val = Bits<32>::bit_select32(val, x, 0xffff); |
4877 | - elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
4878 | - mips_reloc_shuffle(view, r_type, false); | |
5142 | + | |
5143 | + if (calculate_only) | |
5144 | + *calculated_value = x; | |
5145 | + else | |
5146 | + elfcpp::Swap<32, big_endian>::writeval(wv, val); | |
5147 | + | |
4879 | 5148 | return This::STATUS_OKAY; |
4880 | 5149 | } |
4881 | 5150 |
@@ -4884,17 +5153,21 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4884 | 5153 | static inline typename This::Status |
4885 | 5154 | tlsrel32(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4886 | 5155 | const Symbol_value<size>* psymval, Valtype32 tp_offset, |
4887 | - Mips_address addend_a, bool extract_addend, unsigned int r_type) | |
5156 | + Mips_address addend_a, bool extract_addend, bool calculate_only, | |
5157 | + Valtype* calculated_value) | |
4888 | 5158 | { |
4889 | - mips_reloc_unshuffle(view, r_type, false); | |
4890 | 5159 | Valtype32* wv = reinterpret_cast<Valtype32*>(view); |
4891 | 5160 | Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); |
4892 | - Valtype32 addend = extract_addend ? val : addend_a; | |
5161 | + Valtype addend = extract_addend ? val : addend_a; | |
4893 | 5162 | |
4894 | 5163 | // tls symbol values are relative to tls_segment()->vaddr() |
4895 | - Valtype32 x = psymval->value(object, addend) - tp_offset; | |
4896 | - elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4897 | - mips_reloc_shuffle(view, r_type, false); | |
5164 | + Valtype x = psymval->value(object, addend) - tp_offset; | |
5165 | + | |
5166 | + if (calculate_only) | |
5167 | + *calculated_value = x; | |
5168 | + else | |
5169 | + elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
5170 | + | |
4898 | 5171 | return This::STATUS_OKAY; |
4899 | 5172 | } |
4900 | 5173 |
@@ -4902,18 +5175,47 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian> | ||
4902 | 5175 | static inline typename This::Status |
4903 | 5176 | relsub(unsigned char* view, const Mips_relobj<size, big_endian>* object, |
4904 | 5177 | const Symbol_value<size>* psymval, Mips_address addend_a, |
4905 | - bool extract_addend, unsigned int r_type) | |
5178 | + bool extract_addend, bool calculate_only, Valtype* calculated_value) | |
4906 | 5179 | { |
4907 | - mips_reloc_unshuffle(view, r_type, false); | |
4908 | - Valtype32* wv = reinterpret_cast<Valtype32*>(view); | |
4909 | - Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv); | |
4910 | - Valtype32 addend = extract_addend ? val : addend_a; | |
5180 | + Valtype64* wv = reinterpret_cast<Valtype64*>(view); | |
5181 | + Valtype64 addend = (extract_addend | |
5182 | + ? elfcpp::Swap<64, big_endian>::readval(wv) | |
5183 | + : addend_a); | |
5184 | + | |
5185 | + Valtype64 x = psymval->value(object, -addend); | |
5186 | + if (calculate_only) | |
5187 | + *calculated_value = x; | |
5188 | + else | |
5189 | + elfcpp::Swap<64, big_endian>::writeval(wv, x); | |
4911 | 5190 | |
4912 | - Valtype32 x = psymval->value(object, -addend); | |
4913 | - elfcpp::Swap<32, big_endian>::writeval(wv, x); | |
4914 | - mips_reloc_shuffle(view, r_type, false); | |
4915 | 5191 | return This::STATUS_OKAY; |
4916 | - } | |
5192 | + } | |
5193 | + | |
5194 | + // R_MIPS_64: S + A | |
5195 | + static inline typename This::Status | |
5196 | + rel64(unsigned char* view, const Mips_relobj<size, big_endian>* object, | |
5197 | + const Symbol_value<size>* psymval, Mips_address addend_a, | |
5198 | + bool extract_addend, bool calculate_only, Valtype* calculated_value, | |
5199 | + bool apply_addend_only) | |
5200 | + { | |
5201 | + Valtype64* wv = reinterpret_cast<Valtype64*>(view); | |
5202 | + Valtype64 addend = (extract_addend | |
5203 | + ? elfcpp::Swap<64, big_endian>::readval(wv) | |
5204 | + : addend_a); | |
5205 | + | |
5206 | + Valtype64 x = psymval->value(object, addend); | |
5207 | + if (calculate_only) | |
5208 | + *calculated_value = x; | |
5209 | + else | |
5210 | + { | |
5211 | + if (apply_addend_only) | |
5212 | + x = addend; | |
5213 | + elfcpp::Swap<64, big_endian>::writeval(wv, x); | |
5214 | + } | |
5215 | + | |
5216 | + return This::STATUS_OKAY; | |
5217 | + } | |
5218 | + | |
4917 | 5219 | }; |
4918 | 5220 | |
4919 | 5221 | template<int size, bool big_endian> |
@@ -4933,12 +5235,13 @@ template<int size, bool big_endian> | ||
4933 | 5235 | void |
4934 | 5236 | Mips_got_info<size, big_endian>::record_local_got_symbol( |
4935 | 5237 | Mips_relobj<size, big_endian>* object, unsigned int symndx, |
4936 | - Mips_address addend, unsigned int r_type, unsigned int shndx) | |
5238 | + Mips_address addend, unsigned int r_type, unsigned int shndx, | |
5239 | + bool is_section_symbol) | |
4937 | 5240 | { |
4938 | 5241 | Mips_got_entry<size, big_endian>* entry = |
4939 | 5242 | new Mips_got_entry<size, big_endian>(object, symndx, addend, |
4940 | 5243 | mips_elf_reloc_tls_type(r_type), |
4941 | - shndx); | |
5244 | + shndx, is_section_symbol); | |
4942 | 5245 | this->record_got_entry(entry, object); |
4943 | 5246 | } |
4944 | 5247 |
@@ -5118,13 +5421,20 @@ Mips_got_info<size, big_endian>::add_local_entries( | ||
5118 | 5421 | if (entry->is_for_local_symbol() && !entry->is_tls_entry()) |
5119 | 5422 | { |
5120 | 5423 | got->add_local(entry->object(), entry->symndx(), |
5121 | - GOT_TYPE_STANDARD); | |
5424 | + GOT_TYPE_STANDARD, entry->addend()); | |
5122 | 5425 | unsigned int got_offset = entry->object()->local_got_offset( |
5123 | - entry->symndx(), GOT_TYPE_STANDARD); | |
5426 | + entry->symndx(), GOT_TYPE_STANDARD, entry->addend()); | |
5124 | 5427 | if (got->multi_got() && this->index_ > 0 |
5125 | 5428 | && parameters->options().output_is_position_independent()) |
5126 | - target->rel_dyn_section(layout)->add_local(entry->object(), | |
5127 | - entry->symndx(), elfcpp::R_MIPS_REL32, got, got_offset); | |
5429 | + { | |
5430 | + if (!entry->is_section_symbol()) | |
5431 | + target->rel_dyn_section(layout)->add_local(entry->object(), | |
5432 | + entry->symndx(), elfcpp::R_MIPS_REL32, got, got_offset); | |
5433 | + else | |
5434 | + target->rel_dyn_section(layout)->add_symbolless_local_addend( | |
5435 | + entry->object(), entry->symndx(), elfcpp::R_MIPS_REL32, | |
5436 | + got, got_offset); | |
5437 | + } | |
5128 | 5438 | } |
5129 | 5439 | } |
5130 | 5440 |
@@ -5322,9 +5632,10 @@ Mips_got_info<size, big_endian>::add_tls_entries( | ||
5322 | 5632 | got->add_local_pair_with_rel(entry->object(), entry->symndx(), |
5323 | 5633 | entry->shndx(), got_type, |
5324 | 5634 | target->rel_dyn_section(layout), |
5325 | - r_type1); | |
5635 | + r_type1, entry->addend()); | |
5326 | 5636 | unsigned int got_offset = |
5327 | - entry->object()->local_got_offset(entry->symndx(), got_type); | |
5637 | + entry->object()->local_got_offset(entry->symndx(), got_type, | |
5638 | + entry->addend()); | |
5328 | 5639 | got->add_static_reloc(got_offset + size/8, r_type2, |
5329 | 5640 | entry->object(), entry->symndx()); |
5330 | 5641 | } |
@@ -5334,7 +5645,8 @@ Mips_got_info<size, big_endian>::add_tls_entries( | ||
5334 | 5645 | // the executable. |
5335 | 5646 | unsigned int got_offset = got->add_constant(1); |
5336 | 5647 | entry->object()->set_local_got_offset(entry->symndx(), got_type, |
5337 | - got_offset); | |
5648 | + got_offset, | |
5649 | + entry->addend()); | |
5338 | 5650 | got->add_constant(0); |
5339 | 5651 | got->add_static_reloc(got_offset + size/8, r_type2, |
5340 | 5652 | entry->object(), entry->symndx()); |
@@ -5347,12 +5659,15 @@ Mips_got_info<size, big_endian>::add_tls_entries( | ||
5347 | 5659 | : elfcpp::R_MIPS_TLS_TPREL64); |
5348 | 5660 | if (!parameters->doing_static_link()) |
5349 | 5661 | got->add_local_with_rel(entry->object(), entry->symndx(), got_type, |
5350 | - target->rel_dyn_section(layout), r_type); | |
5662 | + target->rel_dyn_section(layout), r_type, | |
5663 | + entry->addend()); | |
5351 | 5664 | else |
5352 | 5665 | { |
5353 | - got->add_local(entry->object(), entry->symndx(), got_type); | |
5666 | + got->add_local(entry->object(), entry->symndx(), got_type, | |
5667 | + entry->addend()); | |
5354 | 5668 | unsigned int got_offset = |
5355 | - entry->object()->local_got_offset(entry->symndx(), got_type); | |
5669 | + entry->object()->local_got_offset(entry->symndx(), got_type, | |
5670 | + entry->addend()); | |
5356 | 5671 | got->add_static_reloc(got_offset, r_type, entry->object(), |
5357 | 5672 | entry->symndx()); |
5358 | 5673 | } |
@@ -6094,21 +6409,104 @@ Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd) | ||
6094 | 6409 | this->cprmask4_ = elfcpp::Swap<size, big_endian>::readval(view + 16); |
6095 | 6410 | } |
6096 | 6411 | |
6097 | - const char* name = pnames + shdr.get_sh_name(); | |
6098 | - this->section_is_mips16_fn_stub_[i] = is_prefix_of(".mips16.fn", name); | |
6099 | - this->section_is_mips16_call_stub_[i] = | |
6100 | - is_prefix_of(".mips16.call.", name); | |
6101 | - this->section_is_mips16_call_fp_stub_[i] = | |
6102 | - is_prefix_of(".mips16.call.fp.", name); | |
6412 | + // In the 64-bit ABI, .MIPS.options section holds register information. | |
6413 | + // A SHT_MIPS_OPTIONS section contains a series of options, each of which | |
6414 | + // starts with this header: | |
6415 | + // | |
6416 | + // typedef struct | |
6417 | + // { | |
6418 | + // // Type of option. | |
6419 | + // unsigned char kind[1]; | |
6420 | + // // Size of option descriptor, including header. | |
6421 | + // unsigned char size[1]; | |
6422 | + // // Section index of affected section, or 0 for global option. | |
6423 | + // unsigned char section[2]; | |
6424 | + // // Information specific to this kind of option. | |
6425 | + // unsigned char info[4]; | |
6426 | + // }; | |
6427 | + // | |
6428 | + // For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and set | |
6429 | + // the gp value based on what we find. We may see both SHT_MIPS_REGINFO | |
6430 | + // and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case, they should agree. | |
6103 | 6431 | |
6104 | - if (strcmp(name, ".pdr") == 0) | |
6432 | + if (shdr.get_sh_type() == elfcpp::SHT_MIPS_OPTIONS) | |
6105 | 6433 | { |
6106 | - gold_assert(this->pdr_shndx_ == -1U); | |
6107 | - this->pdr_shndx_ = i; | |
6108 | - } | |
6109 | - } | |
6110 | -} | |
6111 | - | |
6434 | + section_offset_type section_offset = shdr.get_sh_offset(); | |
6435 | + section_size_type section_size = | |
6436 | + convert_to_section_size_type(shdr.get_sh_size()); | |
6437 | + const unsigned char* view = | |
6438 | + this->get_view(section_offset, section_size, true, false); | |
6439 | + const unsigned char* end = view + section_size; | |
6440 | + | |
6441 | + while (view + 8 <= end) | |
6442 | + { | |
6443 | + unsigned char kind = elfcpp::Swap<8, big_endian>::readval(view); | |
6444 | + unsigned char sz = elfcpp::Swap<8, big_endian>::readval(view + 1); | |
6445 | + if (sz < 8) | |
6446 | + { | |
6447 | + gold_error(_("%s: Warning: bad `%s' option size %u smaller " | |
6448 | + "than its header"), | |
6449 | + this->name().c_str(), | |
6450 | + this->mips_elf_options_section_name(), sz); | |
6451 | + break; | |
6452 | + } | |
6453 | + | |
6454 | + if (this->is_n64() && kind == elfcpp::ODK_REGINFO) | |
6455 | + { | |
6456 | + // In the 64 bit ABI, an ODK_REGINFO option is the following | |
6457 | + // structure. The info field of the options header is not | |
6458 | + // used. | |
6459 | + // | |
6460 | + // typedef struct | |
6461 | + // { | |
6462 | + // // Mask of general purpose registers used. | |
6463 | + // unsigned char ri_gprmask[4]; | |
6464 | + // // Padding. | |
6465 | + // unsigned char ri_pad[4]; | |
6466 | + // // Mask of co-processor registers used. | |
6467 | + // unsigned char ri_cprmask[4][4]; | |
6468 | + // // GP register value for this object file. | |
6469 | + // unsigned char ri_gp_value[8]; | |
6470 | + // }; | |
6471 | + | |
6472 | + this->gp_ = elfcpp::Swap<size, big_endian>::readval(view | |
6473 | + + 32); | |
6474 | + } | |
6475 | + else if (kind == elfcpp::ODK_REGINFO) | |
6476 | + { | |
6477 | + // In the 32 bit ABI, an ODK_REGINFO option is the following | |
6478 | + // structure. The info field of the options header is not | |
6479 | + // used. The same structure is used in .reginfo section. | |
6480 | + // | |
6481 | + // typedef struct | |
6482 | + // { | |
6483 | + // unsigned char ri_gprmask[4]; | |
6484 | + // unsigned char ri_cprmask[4][4]; | |
6485 | + // unsigned char ri_gp_value[4]; | |
6486 | + // }; | |
6487 | + | |
6488 | + this->gp_ = elfcpp::Swap<size, big_endian>::readval(view | |
6489 | + + 28); | |
6490 | + } | |
6491 | + view += sz; | |
6492 | + } | |
6493 | + } | |
6494 | + | |
6495 | + const char* name = pnames + shdr.get_sh_name(); | |
6496 | + this->section_is_mips16_fn_stub_[i] = is_prefix_of(".mips16.fn", name); | |
6497 | + this->section_is_mips16_call_stub_[i] = | |
6498 | + is_prefix_of(".mips16.call.", name); | |
6499 | + this->section_is_mips16_call_fp_stub_[i] = | |
6500 | + is_prefix_of(".mips16.call.fp.", name); | |
6501 | + | |
6502 | + if (strcmp(name, ".pdr") == 0) | |
6503 | + { | |
6504 | + gold_assert(this->pdr_shndx_ == -1U); | |
6505 | + this->pdr_shndx_ = i; | |
6506 | + } | |
6507 | + } | |
6508 | +} | |
6509 | + | |
6112 | 6510 | // Discard MIPS16 stub secions that are not needed. |
6113 | 6511 | |
6114 | 6512 | template<int size, bool big_endian> |
@@ -6426,7 +6824,7 @@ template<int size, bool big_endian> | ||
6426 | 6824 | const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry[] = |
6427 | 6825 | { |
6428 | 6826 | 0x3c0f0000, // lui $15, %hi(.got.plt entry) |
6429 | - 0x8df90000, // l[wd] $25, %lo(.got.plt entry)($15) | |
6827 | + 0x01f90000, // l[wd] $25, %lo(.got.plt entry)($15) | |
6430 | 6828 | 0x03200008, // jr $25 |
6431 | 6829 | 0x25f80000 // addiu $24, $15, %lo(.got.plt entry) |
6432 | 6830 | }; |
@@ -7712,7 +8110,7 @@ Target_mips<size, big_endian>::gc_process_relocs( | ||
7712 | 8110 | Layout* layout, |
7713 | 8111 | Sized_relobj_file<size, big_endian>* object, |
7714 | 8112 | unsigned int data_shndx, |
7715 | - unsigned int, | |
8113 | + unsigned int sh_type, | |
7716 | 8114 | const unsigned char* prelocs, |
7717 | 8115 | size_t reloc_count, |
7718 | 8116 | Output_section* output_section, |
@@ -7721,21 +8119,45 @@ Target_mips<size, big_endian>::gc_process_relocs( | ||
7721 | 8119 | const unsigned char* plocal_symbols) |
7722 | 8120 | { |
7723 | 8121 | typedef Target_mips<size, big_endian> Mips; |
7724 | - typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
7725 | - Classify_reloc; | |
7726 | 8122 | |
7727 | - gold::gc_process_relocs<size, big_endian, Mips, Scan, Classify_reloc>( | |
7728 | - symtab, | |
7729 | - layout, | |
7730 | - this, | |
7731 | - object, | |
7732 | - data_shndx, | |
7733 | - prelocs, | |
7734 | - reloc_count, | |
7735 | - output_section, | |
7736 | - needs_special_offset_handling, | |
7737 | - local_symbol_count, | |
7738 | - plocal_symbols); | |
8123 | + if (sh_type == elfcpp::SHT_REL) | |
8124 | + { | |
8125 | + typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
8126 | + Classify_reloc; | |
8127 | + | |
8128 | + gold::gc_process_relocs<size, big_endian, Mips, Scan, Classify_reloc>( | |
8129 | + symtab, | |
8130 | + layout, | |
8131 | + this, | |
8132 | + object, | |
8133 | + data_shndx, | |
8134 | + prelocs, | |
8135 | + reloc_count, | |
8136 | + output_section, | |
8137 | + needs_special_offset_handling, | |
8138 | + local_symbol_count, | |
8139 | + plocal_symbols); | |
8140 | + } | |
8141 | + else if (sh_type == elfcpp::SHT_RELA) | |
8142 | + { | |
8143 | + typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian> | |
8144 | + Classify_reloc; | |
8145 | + | |
8146 | + gold::gc_process_relocs<size, big_endian, Mips, Scan, Classify_reloc>( | |
8147 | + symtab, | |
8148 | + layout, | |
8149 | + this, | |
8150 | + object, | |
8151 | + data_shndx, | |
8152 | + prelocs, | |
8153 | + reloc_count, | |
8154 | + output_section, | |
8155 | + needs_special_offset_handling, | |
8156 | + local_symbol_count, | |
8157 | + plocal_symbols); | |
8158 | + } | |
8159 | + else | |
8160 | + gold_unreachable(); | |
7739 | 8161 | } |
7740 | 8162 | |
7741 | 8163 | // Scan relocations for a section. |
@@ -8204,9 +8626,20 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout, | ||
8204 | 8626 | elfcpp::Ehdr<size, big_endian> ehdr(pehdr); |
8205 | 8627 | elfcpp::Elf_Word in_flags = ehdr.get_e_flags(); |
8206 | 8628 | unsigned char ei_class = ehdr.get_e_ident()[elfcpp::EI_CLASS]; |
8629 | + // If all input sections will be discarded, don't use this object | |
8630 | + // file for merging processor specific flags. | |
8631 | + bool should_merge_processor_specific_flags = false; | |
8632 | + | |
8633 | + for (unsigned int i = 1; i < relobj->shnum(); ++i) | |
8634 | + if (relobj->output_section(i) != NULL) | |
8635 | + { | |
8636 | + should_merge_processor_specific_flags = true; | |
8637 | + break; | |
8638 | + } | |
8207 | 8639 | |
8208 | - this->merge_processor_specific_flags(relobj->name(), in_flags, | |
8209 | - ei_class, false); | |
8640 | + if (should_merge_processor_specific_flags) | |
8641 | + this->merge_processor_specific_flags(relobj->name(), in_flags, | |
8642 | + ei_class, false); | |
8210 | 8643 | } |
8211 | 8644 | } |
8212 | 8645 |
@@ -8506,6 +8939,7 @@ mips_get_size_for_reloc(unsigned int r_type, Relobj* object) | ||
8506 | 8939 | case elfcpp::R_MIPS_PC32: |
8507 | 8940 | case elfcpp::R_MIPS_GPREL32: |
8508 | 8941 | case elfcpp::R_MIPS_JALR: |
8942 | + case elfcpp::R_MIPS_EH: | |
8509 | 8943 | return 4; |
8510 | 8944 | |
8511 | 8945 | case elfcpp::R_MIPS_16: |
@@ -8571,25 +9005,48 @@ Target_mips<size, big_endian>::scan_relocatable_relocs( | ||
8571 | 9005 | const unsigned char* plocal_symbols, |
8572 | 9006 | Relocatable_relocs* rr) |
8573 | 9007 | { |
8574 | - typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
8575 | - Classify_reloc; | |
8576 | - typedef Mips_scan_relocatable_relocs<big_endian, Classify_reloc> | |
8577 | - Scan_relocatable_relocs; | |
8578 | - | |
8579 | - gold_assert(sh_type == elfcpp::SHT_REL); | |
8580 | - | |
8581 | - gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>( | |
8582 | - symtab, | |
8583 | - layout, | |
8584 | - object, | |
8585 | - data_shndx, | |
8586 | - prelocs, | |
8587 | - reloc_count, | |
8588 | - output_section, | |
8589 | - needs_special_offset_handling, | |
8590 | - local_symbol_count, | |
8591 | - plocal_symbols, | |
8592 | - rr); | |
9008 | + if (sh_type == elfcpp::SHT_REL) | |
9009 | + { | |
9010 | + typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
9011 | + Classify_reloc; | |
9012 | + typedef Mips_scan_relocatable_relocs<big_endian, Classify_reloc> | |
9013 | + Scan_relocatable_relocs; | |
9014 | + | |
9015 | + gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>( | |
9016 | + symtab, | |
9017 | + layout, | |
9018 | + object, | |
9019 | + data_shndx, | |
9020 | + prelocs, | |
9021 | + reloc_count, | |
9022 | + output_section, | |
9023 | + needs_special_offset_handling, | |
9024 | + local_symbol_count, | |
9025 | + plocal_symbols, | |
9026 | + rr); | |
9027 | + } | |
9028 | + else if (sh_type == elfcpp::SHT_RELA) | |
9029 | + { | |
9030 | + typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian> | |
9031 | + Classify_reloc; | |
9032 | + typedef Mips_scan_relocatable_relocs<big_endian, Classify_reloc> | |
9033 | + Scan_relocatable_relocs; | |
9034 | + | |
9035 | + gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>( | |
9036 | + symtab, | |
9037 | + layout, | |
9038 | + object, | |
9039 | + data_shndx, | |
9040 | + prelocs, | |
9041 | + reloc_count, | |
9042 | + output_section, | |
9043 | + needs_special_offset_handling, | |
9044 | + local_symbol_count, | |
9045 | + plocal_symbols, | |
9046 | + rr); | |
9047 | + } | |
9048 | + else | |
9049 | + gold_unreachable(); | |
8593 | 9050 | } |
8594 | 9051 | |
8595 | 9052 | // Scan the relocs for --emit-relocs. |
@@ -8610,25 +9067,48 @@ Target_mips<size, big_endian>::emit_relocs_scan( | ||
8610 | 9067 | const unsigned char* plocal_syms, |
8611 | 9068 | Relocatable_relocs* rr) |
8612 | 9069 | { |
8613 | - typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
8614 | - Classify_reloc; | |
8615 | - typedef gold::Default_emit_relocs_strategy<Classify_reloc> | |
8616 | - Emit_relocs_strategy; | |
8617 | - | |
8618 | - gold_assert(sh_type == elfcpp::SHT_REL); | |
8619 | - | |
8620 | - gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>( | |
8621 | - symtab, | |
8622 | - layout, | |
8623 | - object, | |
8624 | - data_shndx, | |
8625 | - prelocs, | |
8626 | - reloc_count, | |
8627 | - output_section, | |
8628 | - needs_special_offset_handling, | |
8629 | - local_symbol_count, | |
8630 | - plocal_syms, | |
8631 | - rr); | |
9070 | + if (sh_type == elfcpp::SHT_REL) | |
9071 | + { | |
9072 | + typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
9073 | + Classify_reloc; | |
9074 | + typedef gold::Default_emit_relocs_strategy<Classify_reloc> | |
9075 | + Emit_relocs_strategy; | |
9076 | + | |
9077 | + gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>( | |
9078 | + symtab, | |
9079 | + layout, | |
9080 | + object, | |
9081 | + data_shndx, | |
9082 | + prelocs, | |
9083 | + reloc_count, | |
9084 | + output_section, | |
9085 | + needs_special_offset_handling, | |
9086 | + local_symbol_count, | |
9087 | + plocal_syms, | |
9088 | + rr); | |
9089 | + } | |
9090 | + else if (sh_type == elfcpp::SHT_RELA) | |
9091 | + { | |
9092 | + typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian> | |
9093 | + Classify_reloc; | |
9094 | + typedef gold::Default_emit_relocs_strategy<Classify_reloc> | |
9095 | + Emit_relocs_strategy; | |
9096 | + | |
9097 | + gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>( | |
9098 | + symtab, | |
9099 | + layout, | |
9100 | + object, | |
9101 | + data_shndx, | |
9102 | + prelocs, | |
9103 | + reloc_count, | |
9104 | + output_section, | |
9105 | + needs_special_offset_handling, | |
9106 | + local_symbol_count, | |
9107 | + plocal_syms, | |
9108 | + rr); | |
9109 | + } | |
9110 | + else | |
9111 | + gold_unreachable(); | |
8632 | 9112 | } |
8633 | 9113 | |
8634 | 9114 | // Emit relocations for a section. |
@@ -8649,22 +9129,42 @@ Target_mips<size, big_endian>::relocate_relocs( | ||
8649 | 9129 | unsigned char* reloc_view, |
8650 | 9130 | section_size_type reloc_view_size) |
8651 | 9131 | { |
8652 | - typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
8653 | - Classify_reloc; | |
8654 | - | |
8655 | - gold_assert(sh_type == elfcpp::SHT_REL); | |
8656 | - | |
8657 | - gold::relocate_relocs<size, big_endian, Classify_reloc>( | |
8658 | - relinfo, | |
8659 | - prelocs, | |
8660 | - reloc_count, | |
8661 | - output_section, | |
8662 | - offset_in_output_section, | |
8663 | - view, | |
8664 | - view_address, | |
8665 | - view_size, | |
8666 | - reloc_view, | |
8667 | - reloc_view_size); | |
9132 | + if (sh_type == elfcpp::SHT_REL) | |
9133 | + { | |
9134 | + typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian> | |
9135 | + Classify_reloc; | |
9136 | + | |
9137 | + gold::relocate_relocs<size, big_endian, Classify_reloc>( | |
9138 | + relinfo, | |
9139 | + prelocs, | |
9140 | + reloc_count, | |
9141 | + output_section, | |
9142 | + offset_in_output_section, | |
9143 | + view, | |
9144 | + view_address, | |
9145 | + view_size, | |
9146 | + reloc_view, | |
9147 | + reloc_view_size); | |
9148 | + } | |
9149 | + else if (sh_type == elfcpp::SHT_RELA) | |
9150 | + { | |
9151 | + typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian> | |
9152 | + Classify_reloc; | |
9153 | + | |
9154 | + gold::relocate_relocs<size, big_endian, Classify_reloc>( | |
9155 | + relinfo, | |
9156 | + prelocs, | |
9157 | + reloc_count, | |
9158 | + output_section, | |
9159 | + offset_in_output_section, | |
9160 | + view, | |
9161 | + view_address, | |
9162 | + view_size, | |
9163 | + reloc_view, | |
9164 | + reloc_view_size); | |
9165 | + } | |
9166 | + else | |
9167 | + gold_unreachable(); | |
8668 | 9168 | } |
8669 | 9169 | |
8670 | 9170 | // Perform target-specific processing in a relocatable link. This is |
@@ -8762,7 +9262,7 @@ Target_mips<size, big_endian>::relocate_special_relocatable( | ||
8762 | 9262 | // file to refer to that same address. This adjustment to |
8763 | 9263 | // the addend is the same calculation we use for a simple |
8764 | 9264 | // absolute relocation for the input section symbol. |
8765 | - | |
9265 | + Valtype calculated_value = 0; | |
8766 | 9266 | const Symbol_value<size>* psymval = object->local_symbol(r_sym); |
8767 | 9267 | |
8768 | 9268 | unsigned char* paddend = view + offset; |
@@ -8772,7 +9272,8 @@ Target_mips<size, big_endian>::relocate_special_relocatable( | ||
8772 | 9272 | case elfcpp::R_MIPS_26: |
8773 | 9273 | reloc_status = Reloc_funcs::rel26(paddend, object, psymval, |
8774 | 9274 | offset_in_output_section, true, 0, sh_type == elfcpp::SHT_REL, NULL, |
8775 | - false /*TODO(sasa): cross mode jump*/, r_type, this->jal_to_bal()); | |
9275 | + false /*TODO(sasa): cross mode jump*/, r_type, this->jal_to_bal(), | |
9276 | + false, &calculated_value); | |
8776 | 9277 | break; |
8777 | 9278 | |
8778 | 9279 | default: |
@@ -8905,6 +9406,7 @@ Target_mips<size, big_endian>::Scan::local( | ||
8905 | 9406 | case elfcpp::R_MICROMIPS_TLS_GOTTPREL: |
8906 | 9407 | case elfcpp::R_MICROMIPS_TLS_GD: |
8907 | 9408 | case elfcpp::R_MICROMIPS_TLS_LDM: |
9409 | + case elfcpp::R_MIPS_EH: | |
8908 | 9410 | // We need a GOT section. |
8909 | 9411 | target->got_section(symtab, layout); |
8910 | 9412 | break; |
@@ -8915,7 +9417,8 @@ Target_mips<size, big_endian>::Scan::local( | ||
8915 | 9417 | |
8916 | 9418 | if (call_lo16_reloc(r_type) |
8917 | 9419 | || got_lo16_reloc(r_type) |
8918 | - || got_disp_reloc(r_type)) | |
9420 | + || got_disp_reloc(r_type) | |
9421 | + || eh_reloc(r_type)) | |
8919 | 9422 | { |
8920 | 9423 | // We may need a local GOT entry for this relocation. We |
8921 | 9424 | // don't count R_MIPS_GOT_PAGE because we can estimate the |
@@ -8926,7 +9429,9 @@ Target_mips<size, big_endian>::Scan::local( | ||
8926 | 9429 | // R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16. |
8927 | 9430 | Mips_output_data_got<size, big_endian>* got = |
8928 | 9431 | target->got_section(symtab, layout); |
8929 | - got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type, -1U); | |
9432 | + bool is_section_symbol = lsym.get_st_type() == elfcpp::STT_SECTION; | |
9433 | + got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type, -1U, | |
9434 | + is_section_symbol); | |
8930 | 9435 | } |
8931 | 9436 | |
8932 | 9437 | switch (r_type) |
@@ -9059,6 +9564,8 @@ Target_mips<size, big_endian>::Scan::local( | ||
9059 | 9564 | // If building a shared library (or a position-independent |
9060 | 9565 | // executable), we need to create a dynamic relocation for |
9061 | 9566 | // this location. |
9567 | + if (is_readonly_section(output_section)) | |
9568 | + break; | |
9062 | 9569 | Reloc_section* rel_dyn = target->rel_dyn_section(layout); |
9063 | 9570 | rel_dyn->add_symbolless_local_addend(object, r_sym, |
9064 | 9571 | elfcpp::R_MIPS_REL32, |
@@ -9103,7 +9610,7 @@ Target_mips<size, big_endian>::Scan::local( | ||
9103 | 9610 | break; |
9104 | 9611 | } |
9105 | 9612 | got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type, |
9106 | - shndx); | |
9613 | + shndx, false); | |
9107 | 9614 | } |
9108 | 9615 | else |
9109 | 9616 | { |
@@ -9120,7 +9627,7 @@ Target_mips<size, big_endian>::Scan::local( | ||
9120 | 9627 | // We always record LDM symbols as local with index 0. |
9121 | 9628 | target->got_section()->record_local_got_symbol(mips_obj, 0, |
9122 | 9629 | r_addend, r_type, |
9123 | - -1U); | |
9630 | + -1U, false); | |
9124 | 9631 | } |
9125 | 9632 | else |
9126 | 9633 | { |
@@ -9138,7 +9645,7 @@ Target_mips<size, big_endian>::Scan::local( | ||
9138 | 9645 | Mips_output_data_got<size, big_endian>* got = |
9139 | 9646 | target->got_section(symtab, layout); |
9140 | 9647 | got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type, |
9141 | - -1U); | |
9648 | + -1U, false); | |
9142 | 9649 | } |
9143 | 9650 | else |
9144 | 9651 | { |
@@ -9359,6 +9866,7 @@ Target_mips<size, big_endian>::Scan::global( | ||
9359 | 9866 | case elfcpp::R_MICROMIPS_TLS_GOTTPREL: |
9360 | 9867 | case elfcpp::R_MICROMIPS_TLS_GD: |
9361 | 9868 | case elfcpp::R_MICROMIPS_TLS_LDM: |
9869 | + case elfcpp::R_MIPS_EH: | |
9362 | 9870 | // We need a GOT section. |
9363 | 9871 | target->got_section(symtab, layout); |
9364 | 9872 | break; |
@@ -9385,14 +9893,14 @@ Target_mips<size, big_endian>::Scan::global( | ||
9385 | 9893 | case elfcpp::R_MIPS_32: |
9386 | 9894 | case elfcpp::R_MIPS_REL32: |
9387 | 9895 | case elfcpp::R_MIPS_64: |
9388 | - if (parameters->options().shared() | |
9389 | - || strcmp(gsym->name(), "__gnu_local_gp") != 0) | |
9896 | + if ((parameters->options().shared() | |
9897 | + || (strcmp(gsym->name(), "__gnu_local_gp") != 0 | |
9898 | + && (!is_readonly_section(output_section) | |
9899 | + || mips_obj->is_pic()))) | |
9900 | + && (output_section->flags() & elfcpp::SHF_ALLOC) != 0) | |
9390 | 9901 | { |
9391 | 9902 | if (r_type != elfcpp::R_MIPS_REL32) |
9392 | - { | |
9393 | - static_reloc = true; | |
9394 | - mips_sym->set_pointer_equality_needed(); | |
9395 | - } | |
9903 | + mips_sym->set_pointer_equality_needed(); | |
9396 | 9904 | can_make_dynamic = true; |
9397 | 9905 | break; |
9398 | 9906 | } |
@@ -9489,8 +9997,8 @@ Target_mips<size, big_endian>::Scan::global( | ||
9489 | 9997 | { |
9490 | 9998 | if (gsym->may_need_copy_reloc()) |
9491 | 9999 | { |
9492 | - target->copy_reloc(symtab, layout, object, | |
9493 | - data_shndx, output_section, gsym, *rel); | |
10000 | + target->copy_reloc(symtab, layout, object, data_shndx, | |
10001 | + output_section, gsym, r_type, r_offset); | |
9494 | 10002 | } |
9495 | 10003 | else if (can_make_dynamic) |
9496 | 10004 | { |
@@ -9527,6 +10035,7 @@ Target_mips<size, big_endian>::Scan::global( | ||
9527 | 10035 | case elfcpp::R_MICROMIPS_GOT_LO16: |
9528 | 10036 | case elfcpp::R_MIPS_GOT_DISP: |
9529 | 10037 | case elfcpp::R_MICROMIPS_GOT_DISP: |
10038 | + case elfcpp::R_MIPS_EH: | |
9530 | 10039 | { |
9531 | 10040 | // The symbol requires a GOT entry. |
9532 | 10041 | Mips_output_data_got<size, big_endian>* got = |
@@ -9614,7 +10123,7 @@ Target_mips<size, big_endian>::Scan::global( | ||
9614 | 10123 | // We always record LDM symbols as local with index 0. |
9615 | 10124 | target->got_section()->record_local_got_symbol(mips_obj, 0, |
9616 | 10125 | r_addend, r_type, |
9617 | - -1U); | |
10126 | + -1U, false); | |
9618 | 10127 | } |
9619 | 10128 | else |
9620 | 10129 | { |
@@ -9748,11 +10257,14 @@ Target_mips<size, big_endian>::Scan::global( | ||
9748 | 10257 | gsym); |
9749 | 10258 | } |
9750 | 10259 | |
9751 | -// Return whether a R_MIPS_32 relocation needs to be applied. | |
10260 | +// Return whether a R_MIPS_32/R_MIPS64 relocation needs to be applied. | |
10261 | +// In cases where Scan::local() or Scan::global() has created | |
10262 | +// a dynamic relocation, the addend of the relocation is carried | |
10263 | +// in the data, and we must not apply the static relocation. | |
9752 | 10264 | |
9753 | 10265 | template<int size, bool big_endian> |
9754 | 10266 | inline bool |
9755 | -Target_mips<size, big_endian>::Relocate::should_apply_r_mips_32_reloc( | |
10267 | +Target_mips<size, big_endian>::Relocate::should_apply_static_reloc( | |
9756 | 10268 | const Mips_symbol<size>* gsym, |
9757 | 10269 | unsigned int r_type, |
9758 | 10270 | Output_section* output_section, |
@@ -9817,6 +10329,9 @@ Target_mips<size, big_endian>::Relocate::relocate( | ||
9817 | 10329 | Mips_address r_offset; |
9818 | 10330 | unsigned int r_sym; |
9819 | 10331 | unsigned int r_type; |
10332 | + unsigned int r_type2; | |
10333 | + unsigned int r_type3; | |
10334 | + unsigned char r_ssym; | |
9820 | 10335 | typename elfcpp::Elf_types<size>::Elf_Swxword r_addend; |
9821 | 10336 | |
9822 | 10337 | if (rel_type == elfcpp::SHT_RELA) |
@@ -9827,17 +10342,25 @@ Target_mips<size, big_endian>::Relocate::relocate( | ||
9827 | 10342 | get_r_sym(&rela); |
9828 | 10343 | r_type = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>:: |
9829 | 10344 | get_r_type(&rela); |
10345 | + r_type2 = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>:: | |
10346 | + get_r_type2(&rela); | |
10347 | + r_type3 = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>:: | |
10348 | + get_r_type3(&rela); | |
10349 | + r_ssym = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>:: | |
10350 | + get_r_ssym(&rela); | |
9830 | 10351 | r_addend = rela.get_r_addend(); |
9831 | 10352 | } |
9832 | 10353 | else |
9833 | 10354 | { |
9834 | - | |
9835 | 10355 | const Reltype rel(preloc); |
9836 | 10356 | r_offset = rel.get_r_offset(); |
9837 | 10357 | r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>:: |
9838 | 10358 | get_r_sym(&rel); |
9839 | 10359 | r_type = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>:: |
9840 | 10360 | get_r_type(&rel); |
10361 | + r_ssym = 0; | |
10362 | + r_type2 = 0; | |
10363 | + r_type3 = 0; | |
9841 | 10364 | r_addend = 0; |
9842 | 10365 | } |
9843 | 10366 |
@@ -10101,320 +10624,479 @@ Target_mips<size, big_endian>::Relocate::relocate( | ||
10101 | 10624 | unsigned int got_offset = 0; |
10102 | 10625 | int gp_offset = 0; |
10103 | 10626 | |
10104 | - bool update_got_entry = false; | |
10627 | + bool calculate_only = false; | |
10628 | + Valtype calculated_value = 0; | |
10105 | 10629 | bool extract_addend = rel_type == elfcpp::SHT_REL; |
10106 | - switch (r_type) | |
10630 | + unsigned int r_types[3] = { r_type, r_type2, r_type3 }; | |
10631 | + | |
10632 | + Reloc_funcs::mips_reloc_unshuffle(view, r_type, false); | |
10633 | + | |
10634 | + // For Mips64 N64 ABI, there may be up to three operations specified per | |
10635 | + // record, by the fields r_type, r_type2, and r_type3. The first operation | |
10636 | + // takes its addend from the relocation record. Each subsequent operation | |
10637 | + // takes as its addend the result of the previous operation. | |
10638 | + // The first operation in a record which references a symbol uses the symbol | |
10639 | + // implied by r_sym. The next operation in a record which references a symbol | |
10640 | + // uses the special symbol value given by the r_ssym field. A third operation | |
10641 | + // in a record which references a symbol will assume a NULL symbol, | |
10642 | + // i.e. value zero. | |
10643 | + | |
10644 | + // TODO(Vladimir) | |
10645 | + // Check if a record references to a symbol. | |
10646 | + for (unsigned int i = 0; i < 3; ++i) | |
10107 | 10647 | { |
10108 | - case elfcpp::R_MIPS_NONE: | |
10109 | - break; | |
10110 | - case elfcpp::R_MIPS_16: | |
10111 | - reloc_status = Reloc_funcs::rel16(view, object, psymval, r_addend, | |
10112 | - extract_addend, r_type); | |
10113 | - break; | |
10648 | + if (r_types[i] == elfcpp::R_MIPS_NONE) | |
10649 | + break; | |
10114 | 10650 | |
10115 | - case elfcpp::R_MIPS_32: | |
10116 | - if (should_apply_r_mips_32_reloc(mips_sym, r_type, output_section, | |
10117 | - target)) | |
10118 | - reloc_status = Reloc_funcs::rel32(view, object, psymval, r_addend, | |
10119 | - extract_addend, r_type); | |
10120 | - if (mips_sym != NULL | |
10121 | - && (mips_sym->is_mips16() || mips_sym->is_micromips()) | |
10122 | - && mips_sym->global_got_area() == GGA_RELOC_ONLY) | |
10651 | + // TODO(Vladimir) | |
10652 | + // Check if the next relocation is for the same instruction. | |
10653 | + calculate_only = i == 2 ? false | |
10654 | + : r_types[i+1] != elfcpp::R_MIPS_NONE; | |
10655 | + | |
10656 | + if (object->is_n64()) | |
10123 | 10657 | { |
10124 | - // If mips_sym->has_mips16_fn_stub() is false, symbol value is | |
10125 | - // already updated by adding +1. | |
10126 | - if (mips_sym->has_mips16_fn_stub()) | |
10658 | + if (i == 1) | |
10127 | 10659 | { |
10128 | - gold_assert(mips_sym->need_fn_stub()); | |
10129 | - Mips16_stub_section<size, big_endian>* fn_stub = | |
10130 | - mips_sym->template get_mips16_fn_stub<big_endian>(); | |
10131 | - | |
10132 | - symval.set_output_value(fn_stub->output_address()); | |
10660 | + // Handle special symbol for r_type2 relocation type. | |
10661 | + switch (r_ssym) | |
10662 | + { | |
10663 | + case RSS_UNDEF: | |
10664 | + symval.set_output_value(0); | |
10665 | + break; | |
10666 | + case RSS_GP: | |
10667 | + symval.set_output_value(target->gp_value()); | |
10668 | + break; | |
10669 | + case RSS_GP0: | |
10670 | + symval.set_output_value(object->gp_value()); | |
10671 | + break; | |
10672 | + case RSS_LOC: | |
10673 | + symval.set_output_value(address); | |
10674 | + break; | |
10675 | + default: | |
10676 | + gold_unreachable(); | |
10677 | + } | |
10133 | 10678 | psymval = &symval; |
10134 | 10679 | } |
10135 | - got_offset = mips_sym->global_gotoffset(); | |
10136 | - update_got_entry = true; | |
10680 | + else if (i == 2) | |
10681 | + { | |
10682 | + // For r_type3 symbol value is 0. | |
10683 | + symval.set_output_value(0); | |
10684 | + } | |
10137 | 10685 | } |
10138 | - break; | |
10139 | 10686 | |
10140 | - case elfcpp::R_MIPS_REL32: | |
10141 | - gold_unreachable(); | |
10687 | + bool update_got_entry = false; | |
10688 | + switch (r_types[i]) | |
10689 | + { | |
10690 | + case elfcpp::R_MIPS_NONE: | |
10691 | + break; | |
10692 | + case elfcpp::R_MIPS_16: | |
10693 | + reloc_status = Reloc_funcs::rel16(view, object, psymval, r_addend, | |
10694 | + extract_addend, calculate_only, | |
10695 | + &calculated_value); | |
10696 | + break; | |
10142 | 10697 | |
10143 | - case elfcpp::R_MIPS_PC32: | |
10144 | - reloc_status = Reloc_funcs::relpc32(view, object, psymval, address, | |
10145 | - r_addend, extract_addend, r_type); | |
10146 | - break; | |
10698 | + case elfcpp::R_MIPS_32: | |
10699 | + if (should_apply_static_reloc(mips_sym, r_types[i], output_section, | |
10700 | + target)) | |
10701 | + reloc_status = Reloc_funcs::rel32(view, object, psymval, r_addend, | |
10702 | + extract_addend, calculate_only, | |
10703 | + &calculated_value); | |
10704 | + if (mips_sym != NULL | |
10705 | + && (mips_sym->is_mips16() || mips_sym->is_micromips()) | |
10706 | + && mips_sym->global_got_area() == GGA_RELOC_ONLY) | |
10707 | + { | |
10708 | + // If mips_sym->has_mips16_fn_stub() is false, symbol value is | |
10709 | + // already updated by adding +1. | |
10710 | + if (mips_sym->has_mips16_fn_stub()) | |
10711 | + { | |
10712 | + gold_assert(mips_sym->need_fn_stub()); | |
10713 | + Mips16_stub_section<size, big_endian>* fn_stub = | |
10714 | + mips_sym->template get_mips16_fn_stub<big_endian>(); | |
10147 | 10715 | |
10148 | - case elfcpp::R_MIPS16_26: | |
10149 | - // The calculation for R_MIPS16_26 is just the same as for an | |
10150 | - // R_MIPS_26. It's only the storage of the relocated field into | |
10151 | - // the output file that's different. So, we just fall through to the | |
10152 | - // R_MIPS_26 case here. | |
10153 | - case elfcpp::R_MIPS_26: | |
10154 | - case elfcpp::R_MICROMIPS_26_S1: | |
10155 | - reloc_status = Reloc_funcs::rel26(view, object, psymval, address, | |
10156 | - gsym == NULL, r_addend, extract_addend, gsym, cross_mode_jump, r_type, | |
10157 | - target->jal_to_bal()); | |
10158 | - break; | |
10716 | + symval.set_output_value(fn_stub->output_address()); | |
10717 | + psymval = &symval; | |
10718 | + } | |
10719 | + got_offset = mips_sym->global_gotoffset(); | |
10720 | + update_got_entry = true; | |
10721 | + } | |
10722 | + break; | |
10159 | 10723 | |
10160 | - case elfcpp::R_MIPS_HI16: | |
10161 | - case elfcpp::R_MIPS16_HI16: | |
10162 | - case elfcpp::R_MICROMIPS_HI16: | |
10163 | - reloc_status = Reloc_funcs::relhi16(view, object, psymval, r_addend, | |
10164 | - address, gp_disp, r_type, r_sym, | |
10165 | - extract_addend); | |
10166 | - break; | |
10724 | + case elfcpp::R_MIPS_64: | |
10725 | + if (should_apply_static_reloc(mips_sym, r_types[i], output_section, | |
10726 | + target)) | |
10727 | + reloc_status = Reloc_funcs::rel64(view, object, psymval, r_addend, | |
10728 | + extract_addend, calculate_only, | |
10729 | + &calculated_value, false); | |
10730 | + else if (target->is_output_n64() && r_addend != 0) | |
10731 | + // Only apply the addend. The static relocation was RELA, but the | |
10732 | + // dynamic relocation is REL, so we need to apply the addend. | |
10733 | + reloc_status = Reloc_funcs::rel64(view, object, psymval, r_addend, | |
10734 | + extract_addend, calculate_only, | |
10735 | + &calculated_value, true); | |
10736 | + break; | |
10737 | + case elfcpp::R_MIPS_REL32: | |
10738 | + gold_unreachable(); | |
10167 | 10739 | |
10168 | - case elfcpp::R_MIPS_LO16: | |
10169 | - case elfcpp::R_MIPS16_LO16: | |
10170 | - case elfcpp::R_MICROMIPS_LO16: | |
10171 | - case elfcpp::R_MICROMIPS_HI0_LO16: | |
10172 | - reloc_status = Reloc_funcs::rello16(target, view, object, psymval, | |
10173 | - r_addend, extract_addend, address, | |
10174 | - gp_disp, r_type, r_sym); | |
10175 | - break; | |
10740 | + case elfcpp::R_MIPS_PC32: | |
10741 | + reloc_status = Reloc_funcs::relpc32(view, object, psymval, address, | |
10742 | + r_addend, extract_addend, | |
10743 | + calculate_only, | |
10744 | + &calculated_value); | |
10745 | + break; | |
10176 | 10746 | |
10177 | - case elfcpp::R_MIPS_LITERAL: | |
10178 | - case elfcpp::R_MICROMIPS_LITERAL: | |
10179 | - // Because we don't merge literal sections, we can handle this | |
10180 | - // just like R_MIPS_GPREL16. In the long run, we should merge | |
10181 | - // shared literals, and then we will need to additional work | |
10182 | - // here. | |
10747 | + case elfcpp::R_MIPS16_26: | |
10748 | + // The calculation for R_MIPS16_26 is just the same as for an | |
10749 | + // R_MIPS_26. It's only the storage of the relocated field into | |
10750 | + // the output file that's different. So, we just fall through to the | |
10751 | + // R_MIPS_26 case here. | |
10752 | + case elfcpp::R_MIPS_26: | |
10753 | + case elfcpp::R_MICROMIPS_26_S1: | |
10754 | + reloc_status = Reloc_funcs::rel26(view, object, psymval, address, | |
10755 | + gsym == NULL, r_addend, extract_addend, gsym, cross_mode_jump, | |
10756 | + r_types[i], target->jal_to_bal(), calculate_only, | |
10757 | + &calculated_value); | |
10758 | + break; | |
10183 | 10759 | |
10184 | - // Fall through. | |
10760 | + case elfcpp::R_MIPS_HI16: | |
10761 | + case elfcpp::R_MIPS16_HI16: | |
10762 | + case elfcpp::R_MICROMIPS_HI16: | |
10763 | + if (rel_type == elfcpp::SHT_RELA) | |
10764 | + reloc_status = Reloc_funcs::do_relhi16(view, object, psymval, | |
10765 | + r_addend, address, | |
10766 | + gp_disp, r_types[i], | |
10767 | + extract_addend, 0, | |
10768 | + target, calculate_only, | |
10769 | + &calculated_value); | |
10770 | + else if (rel_type == elfcpp::SHT_REL) | |
10771 | + reloc_status = Reloc_funcs::relhi16(view, object, psymval, r_addend, | |
10772 | + address, gp_disp, r_types[i], | |
10773 | + r_sym, extract_addend); | |
10774 | + else | |
10775 | + gold_unreachable(); | |
10776 | + break; | |
10185 | 10777 | |
10186 | - case elfcpp::R_MIPS_GPREL16: | |
10187 | - case elfcpp::R_MIPS16_GPREL: | |
10188 | - case elfcpp::R_MICROMIPS_GPREL7_S2: | |
10189 | - case elfcpp::R_MICROMIPS_GPREL16: | |
10190 | - reloc_status = Reloc_funcs::relgprel(view, object, psymval, | |
10191 | - target->adjusted_gp_value(object), | |
10192 | - r_addend, extract_addend, | |
10193 | - gsym == NULL, r_type); | |
10194 | - break; | |
10778 | + case elfcpp::R_MIPS_LO16: | |
10779 | + case elfcpp::R_MIPS16_LO16: | |
10780 | + case elfcpp::R_MICROMIPS_LO16: | |
10781 | + case elfcpp::R_MICROMIPS_HI0_LO16: | |
10782 | + reloc_status = Reloc_funcs::rello16(target, view, object, psymval, | |
10783 | + r_addend, extract_addend, address, | |
10784 | + gp_disp, r_types[i], r_sym, | |
10785 | + rel_type, calculate_only, | |
10786 | + &calculated_value); | |
10787 | + break; | |
10195 | 10788 | |
10196 | - case elfcpp::R_MIPS_PC16: | |
10197 | - reloc_status = Reloc_funcs::relpc16(view, object, psymval, address, | |
10198 | - r_addend, extract_addend, r_type); | |
10199 | - break; | |
10200 | - case elfcpp::R_MICROMIPS_PC7_S1: | |
10201 | - reloc_status = Reloc_funcs::relmicromips_pc7_s1(view, object, psymval, | |
10202 | - address, r_addend, | |
10203 | - extract_addend, r_type); | |
10204 | - break; | |
10205 | - case elfcpp::R_MICROMIPS_PC10_S1: | |
10206 | - reloc_status = Reloc_funcs::relmicromips_pc10_s1(view, object, psymval, | |
10207 | - address, r_addend, | |
10208 | - extract_addend, r_type); | |
10209 | - break; | |
10210 | - case elfcpp::R_MICROMIPS_PC16_S1: | |
10211 | - reloc_status = Reloc_funcs::relmicromips_pc16_s1(view, object, psymval, | |
10212 | - address, r_addend, | |
10213 | - extract_addend, r_type); | |
10214 | - break; | |
10215 | - case elfcpp::R_MIPS_GPREL32: | |
10216 | - reloc_status = Reloc_funcs::relgprel32(view, object, psymval, | |
10217 | - target->adjusted_gp_value(object), | |
10218 | - r_addend, extract_addend, r_type); | |
10219 | - break; | |
10220 | - case elfcpp::R_MIPS_GOT_HI16: | |
10221 | - case elfcpp::R_MIPS_CALL_HI16: | |
10222 | - case elfcpp::R_MICROMIPS_GOT_HI16: | |
10223 | - case elfcpp::R_MICROMIPS_CALL_HI16: | |
10224 | - if (gsym != NULL) | |
10225 | - got_offset = target->got_section()->got_offset(gsym, GOT_TYPE_STANDARD, | |
10226 | - object); | |
10227 | - else | |
10228 | - got_offset = target->got_section()->got_offset(r_sym, GOT_TYPE_STANDARD, | |
10229 | - object); | |
10230 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10231 | - reloc_status = Reloc_funcs::relgot_hi16(view, gp_offset, r_type); | |
10232 | - update_got_entry = changed_symbol_value; | |
10233 | - break; | |
10789 | + case elfcpp::R_MIPS_LITERAL: | |
10790 | + case elfcpp::R_MICROMIPS_LITERAL: | |
10791 | + // Because we don't merge literal sections, we can handle this | |
10792 | + // just like R_MIPS_GPREL16. In the long run, we should merge | |
10793 | + // shared literals, and then we will need to additional work | |
10794 | + // here. | |
10234 | 10795 | |
10235 | - case elfcpp::R_MIPS_GOT_LO16: | |
10236 | - case elfcpp::R_MIPS_CALL_LO16: | |
10237 | - case elfcpp::R_MICROMIPS_GOT_LO16: | |
10238 | - case elfcpp::R_MICROMIPS_CALL_LO16: | |
10239 | - if (gsym != NULL) | |
10240 | - got_offset = target->got_section()->got_offset(gsym, GOT_TYPE_STANDARD, | |
10241 | - object); | |
10242 | - else | |
10243 | - got_offset = target->got_section()->got_offset(r_sym, GOT_TYPE_STANDARD, | |
10244 | - object); | |
10245 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10246 | - reloc_status = Reloc_funcs::relgot_lo16(view, gp_offset, r_type); | |
10247 | - update_got_entry = changed_symbol_value; | |
10248 | - break; | |
10796 | + // Fall through. | |
10249 | 10797 | |
10250 | - case elfcpp::R_MIPS_GOT_DISP: | |
10251 | - case elfcpp::R_MICROMIPS_GOT_DISP: | |
10252 | - if (gsym != NULL) | |
10253 | - got_offset = target->got_section()->got_offset(gsym, GOT_TYPE_STANDARD, | |
10254 | - object); | |
10255 | - else | |
10256 | - got_offset = target->got_section()->got_offset(r_sym, GOT_TYPE_STANDARD, | |
10257 | - object); | |
10258 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10259 | - reloc_status = Reloc_funcs::relgot(view, gp_offset, r_type); | |
10260 | - break; | |
10798 | + case elfcpp::R_MIPS_GPREL16: | |
10799 | + case elfcpp::R_MIPS16_GPREL: | |
10800 | + case elfcpp::R_MICROMIPS_GPREL7_S2: | |
10801 | + case elfcpp::R_MICROMIPS_GPREL16: | |
10802 | + reloc_status = Reloc_funcs::relgprel(view, object, psymval, | |
10803 | + target->adjusted_gp_value(object), | |
10804 | + r_addend, extract_addend, | |
10805 | + gsym == NULL, r_types[i], | |
10806 | + calculate_only, &calculated_value); | |
10807 | + break; | |
10261 | 10808 | |
10262 | - case elfcpp::R_MIPS_CALL16: | |
10263 | - case elfcpp::R_MIPS16_CALL16: | |
10264 | - case elfcpp::R_MICROMIPS_CALL16: | |
10265 | - gold_assert(gsym != NULL); | |
10266 | - got_offset = target->got_section()->got_offset(gsym, GOT_TYPE_STANDARD, | |
10267 | - object); | |
10268 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10269 | - reloc_status = Reloc_funcs::relgot(view, gp_offset, r_type); | |
10270 | - // TODO(sasa): We should also initialize update_got_entry in other places | |
10271 | - // where relgot is called. | |
10272 | - update_got_entry = changed_symbol_value; | |
10273 | - break; | |
10809 | + case elfcpp::R_MIPS_PC16: | |
10810 | + reloc_status = Reloc_funcs::relpc16(view, object, psymval, address, | |
10811 | + r_addend, extract_addend, | |
10812 | + calculate_only, | |
10813 | + &calculated_value); | |
10814 | + break; | |
10815 | + case elfcpp::R_MICROMIPS_PC7_S1: | |
10816 | + reloc_status = Reloc_funcs::relmicromips_pc7_s1(view, object, psymval, | |
10817 | + address, r_addend, | |
10818 | + extract_addend, | |
10819 | + calculate_only, | |
10820 | + &calculated_value); | |
10821 | + break; | |
10822 | + case elfcpp::R_MICROMIPS_PC10_S1: | |
10823 | + reloc_status = Reloc_funcs::relmicromips_pc10_s1(view, object, | |
10824 | + psymval, address, | |
10825 | + r_addend, extract_addend, | |
10826 | + calculate_only, | |
10827 | + &calculated_value); | |
10828 | + break; | |
10829 | + case elfcpp::R_MICROMIPS_PC16_S1: | |
10830 | + reloc_status = Reloc_funcs::relmicromips_pc16_s1(view, object, | |
10831 | + psymval, address, | |
10832 | + r_addend, extract_addend, | |
10833 | + calculate_only, | |
10834 | + &calculated_value); | |
10835 | + break; | |
10836 | + case elfcpp::R_MIPS_GPREL32: | |
10837 | + reloc_status = Reloc_funcs::relgprel32(view, object, psymval, | |
10838 | + target->adjusted_gp_value(object), | |
10839 | + r_addend, extract_addend, | |
10840 | + calculate_only, | |
10841 | + &calculated_value); | |
10842 | + break; | |
10843 | + case elfcpp::R_MIPS_GOT_HI16: | |
10844 | + case elfcpp::R_MIPS_CALL_HI16: | |
10845 | + case elfcpp::R_MICROMIPS_GOT_HI16: | |
10846 | + case elfcpp::R_MICROMIPS_CALL_HI16: | |
10847 | + if (gsym != NULL) | |
10848 | + got_offset = target->got_section()->got_offset(gsym, | |
10849 | + GOT_TYPE_STANDARD, | |
10850 | + object); | |
10851 | + else | |
10852 | + got_offset = target->got_section()->got_offset(r_sym, | |
10853 | + GOT_TYPE_STANDARD, | |
10854 | + object, r_addend); | |
10855 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10856 | + reloc_status = Reloc_funcs::relgot_hi16(view, gp_offset, | |
10857 | + calculate_only, | |
10858 | + &calculated_value); | |
10859 | + update_got_entry = changed_symbol_value; | |
10860 | + break; | |
10274 | 10861 | |
10275 | - case elfcpp::R_MIPS_GOT16: | |
10276 | - case elfcpp::R_MIPS16_GOT16: | |
10277 | - case elfcpp::R_MICROMIPS_GOT16: | |
10278 | - if (gsym != NULL) | |
10279 | - { | |
10862 | + case elfcpp::R_MIPS_GOT_LO16: | |
10863 | + case elfcpp::R_MIPS_CALL_LO16: | |
10864 | + case elfcpp::R_MICROMIPS_GOT_LO16: | |
10865 | + case elfcpp::R_MICROMIPS_CALL_LO16: | |
10866 | + if (gsym != NULL) | |
10867 | + got_offset = target->got_section()->got_offset(gsym, | |
10868 | + GOT_TYPE_STANDARD, | |
10869 | + object); | |
10870 | + else | |
10871 | + got_offset = target->got_section()->got_offset(r_sym, | |
10872 | + GOT_TYPE_STANDARD, | |
10873 | + object, r_addend); | |
10874 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10875 | + reloc_status = Reloc_funcs::relgot_lo16(view, gp_offset, | |
10876 | + calculate_only, | |
10877 | + &calculated_value); | |
10878 | + update_got_entry = changed_symbol_value; | |
10879 | + break; | |
10880 | + | |
10881 | + case elfcpp::R_MIPS_GOT_DISP: | |
10882 | + case elfcpp::R_MICROMIPS_GOT_DISP: | |
10883 | + case elfcpp::R_MIPS_EH: | |
10884 | + if (gsym != NULL) | |
10885 | + got_offset = target->got_section()->got_offset(gsym, | |
10886 | + GOT_TYPE_STANDARD, | |
10887 | + object); | |
10888 | + else | |
10889 | + got_offset = target->got_section()->got_offset(r_sym, | |
10890 | + GOT_TYPE_STANDARD, | |
10891 | + object, r_addend); | |
10892 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10893 | + if (eh_reloc(r_types[i])) | |
10894 | + reloc_status = Reloc_funcs::releh(view, gp_offset, | |
10895 | + calculate_only, | |
10896 | + &calculated_value); | |
10897 | + else | |
10898 | + reloc_status = Reloc_funcs::relgot(view, gp_offset, | |
10899 | + calculate_only, | |
10900 | + &calculated_value); | |
10901 | + break; | |
10902 | + case elfcpp::R_MIPS_CALL16: | |
10903 | + case elfcpp::R_MIPS16_CALL16: | |
10904 | + case elfcpp::R_MICROMIPS_CALL16: | |
10905 | + gold_assert(gsym != NULL); | |
10280 | 10906 | got_offset = target->got_section()->got_offset(gsym, |
10281 | 10907 | GOT_TYPE_STANDARD, |
10282 | 10908 | object); |
10283 | 10909 | gp_offset = target->got_section()->gp_offset(got_offset, object); |
10284 | - reloc_status = Reloc_funcs::relgot(view, gp_offset, r_type); | |
10285 | - } | |
10286 | - else | |
10287 | - reloc_status = Reloc_funcs::relgot16_local(view, object, psymval, | |
10288 | - r_addend, extract_addend, | |
10289 | - r_type, r_sym); | |
10290 | - update_got_entry = changed_symbol_value; | |
10291 | - break; | |
10910 | + reloc_status = Reloc_funcs::relgot(view, gp_offset, | |
10911 | + calculate_only, &calculated_value); | |
10912 | + // TODO(sasa): We should also initialize update_got_entry | |
10913 | + // in other place swhere relgot is called. | |
10914 | + update_got_entry = changed_symbol_value; | |
10915 | + break; | |
10292 | 10916 | |
10293 | - case elfcpp::R_MIPS_TLS_GD: | |
10294 | - case elfcpp::R_MIPS16_TLS_GD: | |
10295 | - case elfcpp::R_MICROMIPS_TLS_GD: | |
10296 | - if (gsym != NULL) | |
10297 | - got_offset = target->got_section()->got_offset(gsym, GOT_TYPE_TLS_PAIR, | |
10298 | - object); | |
10299 | - else | |
10300 | - got_offset = target->got_section()->got_offset(r_sym, GOT_TYPE_TLS_PAIR, | |
10301 | - object); | |
10302 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10303 | - reloc_status = Reloc_funcs::relgot(view, gp_offset, r_type); | |
10304 | - break; | |
10917 | + case elfcpp::R_MIPS_GOT16: | |
10918 | + case elfcpp::R_MIPS16_GOT16: | |
10919 | + case elfcpp::R_MICROMIPS_GOT16: | |
10920 | + if (gsym != NULL) | |
10921 | + { | |
10922 | + got_offset = target->got_section()->got_offset(gsym, | |
10923 | + GOT_TYPE_STANDARD, | |
10924 | + object); | |
10925 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10926 | + reloc_status = Reloc_funcs::relgot(view, gp_offset, | |
10927 | + calculate_only, | |
10928 | + &calculated_value); | |
10929 | + } | |
10930 | + else | |
10931 | + { | |
10932 | + if (rel_type == elfcpp::SHT_RELA) | |
10933 | + reloc_status = Reloc_funcs::do_relgot16_local(view, object, | |
10934 | + psymval, r_addend, | |
10935 | + extract_addend, 0, | |
10936 | + target, | |
10937 | + calculate_only, | |
10938 | + &calculated_value); | |
10939 | + else if (rel_type == elfcpp::SHT_REL) | |
10940 | + reloc_status = Reloc_funcs::relgot16_local(view, object, | |
10941 | + psymval, r_addend, | |
10942 | + extract_addend, | |
10943 | + r_types[i], r_sym); | |
10944 | + else | |
10945 | + gold_unreachable(); | |
10946 | + } | |
10947 | + update_got_entry = changed_symbol_value; | |
10948 | + break; | |
10305 | 10949 | |
10306 | - case elfcpp::R_MIPS_TLS_GOTTPREL: | |
10307 | - case elfcpp::R_MIPS16_TLS_GOTTPREL: | |
10308 | - case elfcpp::R_MICROMIPS_TLS_GOTTPREL: | |
10309 | - if (gsym != NULL) | |
10310 | - got_offset = target->got_section()->got_offset(gsym, | |
10311 | - GOT_TYPE_TLS_OFFSET, | |
10312 | - object); | |
10313 | - else | |
10314 | - got_offset = target->got_section()->got_offset(r_sym, | |
10315 | - GOT_TYPE_TLS_OFFSET, | |
10316 | - object); | |
10317 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10318 | - reloc_status = Reloc_funcs::relgot(view, gp_offset, r_type); | |
10319 | - break; | |
10950 | + case elfcpp::R_MIPS_TLS_GD: | |
10951 | + case elfcpp::R_MIPS16_TLS_GD: | |
10952 | + case elfcpp::R_MICROMIPS_TLS_GD: | |
10953 | + if (gsym != NULL) | |
10954 | + got_offset = target->got_section()->got_offset(gsym, | |
10955 | + GOT_TYPE_TLS_PAIR, | |
10956 | + object); | |
10957 | + else | |
10958 | + got_offset = target->got_section()->got_offset(r_sym, | |
10959 | + GOT_TYPE_TLS_PAIR, | |
10960 | + object, r_addend); | |
10961 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10962 | + reloc_status = Reloc_funcs::relgot(view, gp_offset, calculate_only, | |
10963 | + &calculated_value); | |
10964 | + break; | |
10320 | 10965 | |
10321 | - case elfcpp::R_MIPS_TLS_LDM: | |
10322 | - case elfcpp::R_MIPS16_TLS_LDM: | |
10323 | - case elfcpp::R_MICROMIPS_TLS_LDM: | |
10324 | - // Relocate the field with the offset of the GOT entry for | |
10325 | - // the module index. | |
10326 | - got_offset = target->got_section()->tls_ldm_offset(object); | |
10327 | - gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10328 | - reloc_status = Reloc_funcs::relgot(view, gp_offset, r_type); | |
10329 | - break; | |
10966 | + case elfcpp::R_MIPS_TLS_GOTTPREL: | |
10967 | + case elfcpp::R_MIPS16_TLS_GOTTPREL: | |
10968 | + case elfcpp::R_MICROMIPS_TLS_GOTTPREL: | |
10969 | + if (gsym != NULL) | |
10970 | + got_offset = target->got_section()->got_offset(gsym, | |
10971 | + GOT_TYPE_TLS_OFFSET, | |
10972 | + object); | |
10973 | + else | |
10974 | + got_offset = target->got_section()->got_offset(r_sym, | |
10975 | + GOT_TYPE_TLS_OFFSET, | |
10976 | + object, r_addend); | |
10977 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10978 | + reloc_status = Reloc_funcs::relgot(view, gp_offset, calculate_only, | |
10979 | + &calculated_value); | |
10980 | + break; | |
10330 | 10981 | |
10331 | - case elfcpp::R_MIPS_GOT_PAGE: | |
10332 | - case elfcpp::R_MICROMIPS_GOT_PAGE: | |
10333 | - reloc_status = Reloc_funcs::relgotpage(target, view, object, psymval, | |
10334 | - r_addend, extract_addend, r_type); | |
10335 | - break; | |
10982 | + case elfcpp::R_MIPS_TLS_LDM: | |
10983 | + case elfcpp::R_MIPS16_TLS_LDM: | |
10984 | + case elfcpp::R_MICROMIPS_TLS_LDM: | |
10985 | + // Relocate the field with the offset of the GOT entry for | |
10986 | + // the module index. | |
10987 | + got_offset = target->got_section()->tls_ldm_offset(object); | |
10988 | + gp_offset = target->got_section()->gp_offset(got_offset, object); | |
10989 | + reloc_status = Reloc_funcs::relgot(view, gp_offset, calculate_only, | |
10990 | + &calculated_value); | |
10991 | + break; | |
10336 | 10992 | |
10337 | - case elfcpp::R_MIPS_GOT_OFST: | |
10338 | - case elfcpp::R_MICROMIPS_GOT_OFST: | |
10339 | - reloc_status = Reloc_funcs::relgotofst(target, view, object, psymval, | |
10340 | - r_addend, extract_addend, local, | |
10341 | - r_type); | |
10342 | - break; | |
10993 | + case elfcpp::R_MIPS_GOT_PAGE: | |
10994 | + case elfcpp::R_MICROMIPS_GOT_PAGE: | |
10995 | + reloc_status = Reloc_funcs::relgotpage(target, view, object, psymval, | |
10996 | + r_addend, extract_addend, | |
10997 | + calculate_only, | |
10998 | + &calculated_value); | |
10999 | + break; | |
10343 | 11000 | |
10344 | - case elfcpp::R_MIPS_JALR: | |
10345 | - case elfcpp::R_MICROMIPS_JALR: | |
10346 | - // This relocation is only a hint. In some cases, we optimize | |
10347 | - // it into a bal instruction. But we don't try to optimize | |
10348 | - // when the symbol does not resolve locally. | |
10349 | - if (gsym == NULL || symbol_calls_local(gsym, gsym->has_dynsym_index())) | |
10350 | - reloc_status = Reloc_funcs::reljalr(view, object, psymval, address, | |
10351 | - r_addend, extract_addend, | |
10352 | - cross_mode_jump, r_type, | |
10353 | - target->jalr_to_bal(), | |
10354 | - target->jr_to_b()); | |
10355 | - break; | |
11001 | + case elfcpp::R_MIPS_GOT_OFST: | |
11002 | + case elfcpp::R_MICROMIPS_GOT_OFST: | |
11003 | + reloc_status = Reloc_funcs::relgotofst(target, view, object, psymval, | |
11004 | + r_addend, extract_addend, | |
11005 | + local, calculate_only, | |
11006 | + &calculated_value); | |
11007 | + break; | |
10356 | 11008 | |
10357 | - case elfcpp::R_MIPS_TLS_DTPREL_HI16: | |
10358 | - case elfcpp::R_MIPS16_TLS_DTPREL_HI16: | |
10359 | - case elfcpp::R_MICROMIPS_TLS_DTPREL_HI16: | |
10360 | - reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval, | |
10361 | - elfcpp::DTP_OFFSET, r_addend, | |
10362 | - extract_addend, r_type); | |
10363 | - break; | |
10364 | - case elfcpp::R_MIPS_TLS_DTPREL_LO16: | |
10365 | - case elfcpp::R_MIPS16_TLS_DTPREL_LO16: | |
10366 | - case elfcpp::R_MICROMIPS_TLS_DTPREL_LO16: | |
10367 | - reloc_status = Reloc_funcs::tlsrello16(view, object, psymval, | |
10368 | - elfcpp::DTP_OFFSET, r_addend, | |
10369 | - extract_addend, r_type); | |
10370 | - break; | |
10371 | - case elfcpp::R_MIPS_TLS_DTPREL32: | |
10372 | - case elfcpp::R_MIPS_TLS_DTPREL64: | |
10373 | - reloc_status = Reloc_funcs::tlsrel32(view, object, psymval, | |
10374 | - elfcpp::DTP_OFFSET, r_addend, | |
10375 | - extract_addend, r_type); | |
10376 | - break; | |
10377 | - case elfcpp::R_MIPS_TLS_TPREL_HI16: | |
10378 | - case elfcpp::R_MIPS16_TLS_TPREL_HI16: | |
10379 | - case elfcpp::R_MICROMIPS_TLS_TPREL_HI16: | |
10380 | - reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval, | |
10381 | - elfcpp::TP_OFFSET, r_addend, | |
10382 | - extract_addend, r_type); | |
10383 | - break; | |
10384 | - case elfcpp::R_MIPS_TLS_TPREL_LO16: | |
10385 | - case elfcpp::R_MIPS16_TLS_TPREL_LO16: | |
10386 | - case elfcpp::R_MICROMIPS_TLS_TPREL_LO16: | |
10387 | - reloc_status = Reloc_funcs::tlsrello16(view, object, psymval, | |
10388 | - elfcpp::TP_OFFSET, r_addend, | |
10389 | - extract_addend, r_type); | |
10390 | - break; | |
10391 | - case elfcpp::R_MIPS_TLS_TPREL32: | |
10392 | - case elfcpp::R_MIPS_TLS_TPREL64: | |
10393 | - reloc_status = Reloc_funcs::tlsrel32(view, object, psymval, | |
10394 | - elfcpp::TP_OFFSET, r_addend, | |
10395 | - extract_addend, r_type); | |
10396 | - break; | |
10397 | - case elfcpp::R_MIPS_SUB: | |
10398 | - case elfcpp::R_MICROMIPS_SUB: | |
10399 | - reloc_status = Reloc_funcs::relsub(view, object, psymval, r_addend, | |
10400 | - extract_addend, r_type); | |
10401 | - break; | |
10402 | - default: | |
10403 | - gold_error_at_location(relinfo, relnum, r_offset, | |
10404 | - _("unsupported reloc %u"), r_type); | |
10405 | - break; | |
10406 | - } | |
11009 | + case elfcpp::R_MIPS_JALR: | |
11010 | + case elfcpp::R_MICROMIPS_JALR: | |
11011 | + // This relocation is only a hint. In some cases, we optimize | |
11012 | + // it into a bal instruction. But we don't try to optimize | |
11013 | + // when the symbol does not resolve locally. | |
11014 | + if (gsym == NULL | |
11015 | + || symbol_calls_local(gsym, gsym->has_dynsym_index())) | |
11016 | + reloc_status = Reloc_funcs::reljalr(view, object, psymval, address, | |
11017 | + r_addend, extract_addend, | |
11018 | + cross_mode_jump, r_types[i], | |
11019 | + target->jalr_to_bal(), | |
11020 | + target->jr_to_b(), | |
11021 | + calculate_only, | |
11022 | + &calculated_value); | |
11023 | + break; | |
10407 | 11024 | |
10408 | - if (update_got_entry) | |
10409 | - { | |
10410 | - Mips_output_data_got<size, big_endian>* got = target->got_section(); | |
10411 | - if (mips_sym != NULL && mips_sym->get_applied_secondary_got_fixup()) | |
10412 | - got->update_got_entry(got->get_primary_got_offset(mips_sym), | |
10413 | - psymval->value(object, 0)); | |
10414 | - else | |
10415 | - got->update_got_entry(got_offset, psymval->value(object, 0)); | |
11025 | + case elfcpp::R_MIPS_TLS_DTPREL_HI16: | |
11026 | + case elfcpp::R_MIPS16_TLS_DTPREL_HI16: | |
11027 | + case elfcpp::R_MICROMIPS_TLS_DTPREL_HI16: | |
11028 | + reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval, | |
11029 | + elfcpp::DTP_OFFSET, r_addend, | |
11030 | + extract_addend, calculate_only, | |
11031 | + &calculated_value); | |
11032 | + break; | |
11033 | + case elfcpp::R_MIPS_TLS_DTPREL_LO16: | |
11034 | + case elfcpp::R_MIPS16_TLS_DTPREL_LO16: | |
11035 | + case elfcpp::R_MICROMIPS_TLS_DTPREL_LO16: | |
11036 | + reloc_status = Reloc_funcs::tlsrello16(view, object, psymval, | |
11037 | + elfcpp::DTP_OFFSET, r_addend, | |
11038 | + extract_addend, calculate_only, | |
11039 | + &calculated_value); | |
11040 | + break; | |
11041 | + case elfcpp::R_MIPS_TLS_DTPREL32: | |
11042 | + case elfcpp::R_MIPS_TLS_DTPREL64: | |
11043 | + reloc_status = Reloc_funcs::tlsrel32(view, object, psymval, | |
11044 | + elfcpp::DTP_OFFSET, r_addend, | |
11045 | + extract_addend, calculate_only, | |
11046 | + &calculated_value); | |
11047 | + break; | |
11048 | + case elfcpp::R_MIPS_TLS_TPREL_HI16: | |
11049 | + case elfcpp::R_MIPS16_TLS_TPREL_HI16: | |
11050 | + case elfcpp::R_MICROMIPS_TLS_TPREL_HI16: | |
11051 | + reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval, | |
11052 | + elfcpp::TP_OFFSET, r_addend, | |
11053 | + extract_addend, calculate_only, | |
11054 | + &calculated_value); | |
11055 | + break; | |
11056 | + case elfcpp::R_MIPS_TLS_TPREL_LO16: | |
11057 | + case elfcpp::R_MIPS16_TLS_TPREL_LO16: | |
11058 | + case elfcpp::R_MICROMIPS_TLS_TPREL_LO16: | |
11059 | + reloc_status = Reloc_funcs::tlsrello16(view, object, psymval, | |
11060 | + elfcpp::TP_OFFSET, r_addend, | |
11061 | + extract_addend, calculate_only, | |
11062 | + &calculated_value); | |
11063 | + break; | |
11064 | + case elfcpp::R_MIPS_TLS_TPREL32: | |
11065 | + case elfcpp::R_MIPS_TLS_TPREL64: | |
11066 | + reloc_status = Reloc_funcs::tlsrel32(view, object, psymval, | |
11067 | + elfcpp::TP_OFFSET, r_addend, | |
11068 | + extract_addend, calculate_only, | |
11069 | + &calculated_value); | |
11070 | + break; | |
11071 | + case elfcpp::R_MIPS_SUB: | |
11072 | + case elfcpp::R_MICROMIPS_SUB: | |
11073 | + reloc_status = Reloc_funcs::relsub(view, object, psymval, r_addend, | |
11074 | + extract_addend, | |
11075 | + calculate_only, &calculated_value); | |
11076 | + break; | |
11077 | + default: | |
11078 | + gold_error_at_location(relinfo, relnum, r_offset, | |
11079 | + _("unsupported reloc %u"), r_types[i]); | |
11080 | + break; | |
11081 | + } | |
11082 | + | |
11083 | + if (update_got_entry) | |
11084 | + { | |
11085 | + Mips_output_data_got<size, big_endian>* got = target->got_section(); | |
11086 | + if (mips_sym != NULL && mips_sym->get_applied_secondary_got_fixup()) | |
11087 | + got->update_got_entry(got->get_primary_got_offset(mips_sym), | |
11088 | + psymval->value(object, 0)); | |
11089 | + else | |
11090 | + got->update_got_entry(got_offset, psymval->value(object, 0)); | |
11091 | + } | |
11092 | + | |
11093 | + r_addend = calculated_value; | |
10416 | 11094 | } |
10417 | 11095 | |
11096 | + bool jal_shuffle = jal_reloc(r_type) ? !parameters->options().relocatable() | |
11097 | + : false; | |
11098 | + Reloc_funcs::mips_reloc_shuffle(view, r_type, jal_shuffle); | |
11099 | + | |
10418 | 11100 | // Report any errors. |
10419 | 11101 | switch (reloc_status) |
10420 | 11102 | { |
@@ -10494,6 +11176,7 @@ Target_mips<size, big_endian>::Scan::get_reference_flags( | ||
10494 | 11176 | case elfcpp::R_MICROMIPS_GOT_LO16: |
10495 | 11177 | case elfcpp::R_MICROMIPS_CALL_HI16: |
10496 | 11178 | case elfcpp::R_MICROMIPS_CALL_LO16: |
11179 | + case elfcpp::R_MIPS_EH: | |
10497 | 11180 | // Absolute in GOT. |
10498 | 11181 | return Symbol::RELATIVE_REF; |
10499 | 11182 |
@@ -10665,7 +11348,7 @@ const Target::Target_info Target_mips<size, big_endian>::mips_info = | ||
10665 | 11348 | true, // is_default_stack_executable |
10666 | 11349 | false, // can_icf_inline_merge_sections |
10667 | 11350 | '\0', // wrap_char |
10668 | - "/lib/ld.so.1", // dynamic_linker | |
11351 | + size == 32 ? "/lib/ld.so.1" : "/lib64/ld.so.1", // dynamic_linker | |
10669 | 11352 | 0x400000, // default_text_segment_address |
10670 | 11353 | 64 * 1024, // abi_pagesize (overridable by -z max-page-size) |
10671 | 11354 | 4 * 1024, // common_pagesize (overridable by -z common-page-size) |
@@ -10734,8 +11417,8 @@ public: | ||
10734 | 11417 | (big_endian ? "elf64-tradbigmips" : "elf64-tradlittlemips") : |
10735 | 11418 | (big_endian ? "elf32-tradbigmips" : "elf32-tradlittlemips")), |
10736 | 11419 | (size == 64 ? |
10737 | - (big_endian ? "elf64-tradbigmips" : "elf64-tradlittlemips") : | |
10738 | - (big_endian ? "elf32-tradbigmips" : "elf32-tradlittlemips"))) | |
11420 | + (big_endian ? "elf64btsmip" : "elf64ltsmip") : | |
11421 | + (big_endian ? "elf32btsmip" : "elf32ltsmip"))) | |
10739 | 11422 | { } |
10740 | 11423 | |
10741 | 11424 | Target* do_instantiate_target() |