• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修訂47a9f4fcab30d2f9a1485a7a2634f40feb22bd60 (tree)
時間2016-03-18 07:07:49
作者Vladimir Radosavljevic <vladimir.radosavljevic@imgt...>
CommiterCary Coutant

Log Message

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.

Change Summary

差異

--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,100 @@
11 2016-03-17 Vladimir Radosavljevic <vladimir.radosavljevic@imgtec.com>
22
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+
398 * mips.cc (class Mips_output_data_la25_stub): Add
499 do_print_to_mapfile function.
5100
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -132,6 +132,31 @@ enum Got_tls_type
132132 GOT_TLS_IE = 4
133133 };
134134
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+
135160 // Return TRUE if a relocation of type R_TYPE from OBJECT might
136161 // require an la25 stub. See also local_pic_function, which determines
137162 // whether the destination function ever requires a stub.
@@ -232,6 +257,12 @@ got_lo16_reloc(unsigned int r_type)
232257 }
233258
234259 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
235266 got_disp_reloc(unsigned int r_type)
236267 {
237268 return (r_type == elfcpp::R_MIPS_GOT_DISP
@@ -401,13 +432,15 @@ class Mips_got_entry
401432 public:
402433 Mips_got_entry(Mips_relobj<size, big_endian>* object, unsigned int symndx,
403434 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)
406438 { this->d.addend = addend; }
407439
408440 Mips_got_entry(Mips_relobj<size, big_endian>* object, Mips_symbol<size>* sym,
409441 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)
411444 { this->d.sym = sym; }
412445
413446 // Return whether this entry is for a local symbol.
@@ -501,6 +534,11 @@ class Mips_got_entry
501534 shndx() const
502535 { return this->shndx_; }
503536
537+ // Return whether this is a STT_SECTION symbol.
538+ bool
539+ is_section_symbol() const
540+ { return this->is_section_symbol_; }
541+
504542 private:
505543 // The input object that needs the GOT entry.
506544 Mips_relobj<size, big_endian>* object_;
@@ -522,6 +560,9 @@ class Mips_got_entry
522560 // symbol entry with r_symndx == 0.
523561 unsigned char tls_type_;
524562
563+ // Whether this is a STT_SECTION symbol.
564+ bool is_section_symbol_;
565+
525566 // For local GOT entries, section index of the local symbol.
526567 unsigned int shndx_;
527568 };
@@ -645,7 +686,8 @@ class Mips_got_info
645686 void
646687 record_local_got_symbol(Mips_relobj<size, big_endian>* object,
647688 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);
649691
650692 // Reserve GOT entry for a GOT relocation of type R_TYPE against MIPS_SYM,
651693 // 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>
17641806 do_read_symbols(Read_symbols_data* sd);
17651807
17661808 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+
17671813 // processor-specific flags in ELF file header.
17681814 elfcpp::Elf_Word processor_specific_flags_;
17691815
@@ -1861,10 +1907,12 @@ class Mips_output_data_got : public Output_data_got<size, big_endian>
18611907 void
18621908 record_local_got_symbol(Mips_relobj<size, big_endian>* object,
18631909 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)
18651912 {
18661913 this->master_got_info_->record_local_got_symbol(object, symndx, addend,
1867- r_type, shndx);
1914+ r_type, shndx,
1915+ is_section_symbol);
18681916 }
18691917
18701918 // 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>
20022050 // SYMNDX.
20032051 unsigned int
20042052 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); }
20072056
20082057 // Return the offset of TLS LDM entry. For multi-GOT links, use OBJECT's GOT.
20092058 unsigned int
@@ -2259,14 +2308,73 @@ class Mips_output_data_la25_stub : public Output_section_data
22592308 Unordered_set<Mips_symbol<size>*> symbols_;
22602309 };
22612310
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+
22622370 // A class to handle the PLT data.
22632371
22642372 template<int size, bool big_endian>
22652373 class Mips_output_data_plt : public Output_section_data
22662374 {
22672375 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;
22702378
22712379 public:
22722380 // 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>
28772985 typedef typename elfcpp::Rel<32, big_endian> Reloc;
28782986 typedef typename elfcpp::Rel_write<32, big_endian> Reloc_write;
28792987
2880- static unsigned typename elfcpp::Elf_types<32>::Elf_Swxword
2988+ static typename elfcpp::Elf_types<32>::Elf_Swxword
28812989 get_r_addend(const Reloc*)
28822990 { return 0; }
28832991
@@ -2893,7 +3001,7 @@ struct Mips_reloc_types<elfcpp::SHT_RELA, 32, big_endian>
28933001 typedef typename elfcpp::Rela<32, big_endian> Reloc;
28943002 typedef typename elfcpp::Rela_write<32, big_endian> Reloc_write;
28953003
2896- static unsigned typename elfcpp::Elf_types<32>::Elf_Swxword
3004+ static typename elfcpp::Elf_types<32>::Elf_Swxword
28973005 get_r_addend(const Reloc* reloc)
28983006 { return reloc->get_r_addend(); }
28993007
@@ -2909,7 +3017,7 @@ struct Mips_reloc_types<elfcpp::SHT_REL, 64, big_endian>
29093017 typedef typename elfcpp::Mips64_rel<big_endian> Reloc;
29103018 typedef typename elfcpp::Mips64_rel_write<big_endian> Reloc_write;
29113019
2912- static unsigned typename elfcpp::Elf_types<64>::Elf_Swxword
3020+ static typename elfcpp::Elf_types<64>::Elf_Swxword
29133021 get_r_addend(const Reloc*)
29143022 { return 0; }
29153023
@@ -2925,7 +3033,7 @@ struct Mips_reloc_types<elfcpp::SHT_RELA, 64, big_endian>
29253033 typedef typename elfcpp::Mips64_rela<big_endian> Reloc;
29263034 typedef typename elfcpp::Mips64_rela_write<big_endian> Reloc_write;
29273035
2928- static unsigned typename elfcpp::Elf_types<64>::Elf_Swxword
3036+ static typename elfcpp::Elf_types<64>::Elf_Swxword
29293037 get_r_addend(const Reloc* reloc)
29303038 { return reloc->get_r_addend(); }
29313039
@@ -2966,6 +3074,18 @@ class Mips_classify_reloc<sh_type_, 32, big_endian> :
29663074 get_r_type(const Reltype* reloc)
29673075 { return elfcpp::elf_r_type<32>(reloc->get_r_info()); }
29683076
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+
29693089 // Return the explicit addend of the relocation (return 0 for SHT_REL).
29703090 static inline unsigned int
29713091 get_r_addend(const Reltype* reloc)
@@ -3011,11 +3131,26 @@ class Mips_classify_reloc<sh_type_, 64, big_endian> :
30113131 get_r_sym(const Reltype* reloc)
30123132 { return reloc->get_r_sym(); }
30133133
3014- // Return the type of the relocation.
3134+ // Return the r_type of the relocation.
30153135 static inline unsigned int
30163136 get_r_type(const Reltype* reloc)
30173137 { return reloc->get_r_type(); }
30183138
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+
30193154 // Return the explicit addend of the relocation (return 0 for SHT_REL).
30203155 static inline typename elfcpp::Elf_types<64>::Elf_Swxword
30213156 get_r_addend(const Reltype* reloc)
@@ -3053,10 +3188,8 @@ template<int size, bool big_endian>
30533188 class Target_mips : public Sized_target<size, big_endian>
30543189 {
30553190 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>
30573192 Reloc_section;
3058- typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
3059- Reloca_section;
30603193 typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32;
30613194 typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
30623195 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>
36003733 ~Relocate()
36013734 { }
36023735
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.
36043737 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);
36093742
36103743 // Do a relocation. Return false if the caller should not issue
36113744 // any warnings about this relocation.
@@ -3783,15 +3916,12 @@ class Target_mips : public Sized_target<size, big_endian>
37833916 copy_reloc(Symbol_table* symtab, Layout* layout,
37843917 Sized_relobj_file<size, big_endian>* object,
37853918 unsigned int shndx, Output_section* output_section,
3786- Symbol* sym, const Reltype& reloc)
3919+ Symbol* sym, unsigned int r_type, Mips_address r_offset)
37873920 {
3788- unsigned int r_type =
3789- Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
3790- get_r_type(&reloc);
37913921 this->copy_relocs_.copy_reloc(symtab, layout,
37923922 symtab->get_sized_symbol<size>(sym),
37933923 object, shndx, output_section,
3794- r_type, reloc.get_r_offset(), 0,
3924+ r_type, r_offset, 0,
37953925 this->rel_dyn_section(layout));
37963926 }
37973927
@@ -3969,8 +4099,10 @@ template<int size, bool big_endian>
39694099 class Mips_relocate_functions : public Relocate_functions<size, big_endian>
39704100 {
39714101 typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
4102+ typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
39724103 typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype16;
39734104 typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32;
4105+ typedef typename elfcpp::Swap<64, big_endian>::Valtype Valtype64;
39744106
39754107 public:
39764108 typedef enum
@@ -3987,6 +4119,29 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
39874119 static typename std::list<reloc_high<size, big_endian> > hi16_relocs;
39884120 static typename std::list<reloc_high<size, big_endian> > got16_relocs;
39894121
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:
39904145 // R_MIPS16_26 is used for the mips16 jal and jalx instructions.
39914146 // Most mips16 instructions are 16 bits, but these instructions
39924147 // are 32 bits.
@@ -4076,14 +4231,6 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
40764231 // on a little-endian system. This does not apply to R_MICROMIPS_PC7_S1
40774232 // and R_MICROMIPS_PC10_S1 relocs that apply to 16-bit instructions.
40784233
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-
40874234 static void
40884235 mips_reloc_unshuffle(unsigned char* view, unsigned int r_type,
40894236 bool jal_shuffle)
@@ -4142,43 +4289,49 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
41424289 elfcpp::Swap<16, big_endian>::writeval(view, first);
41434290 }
41444291
4145- public:
41464292 // R_MIPS_16: S + sign-extend(A)
41474293 static inline typename This::Status
41484294 rel16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
41494295 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)
41514297 {
4152- mips_reloc_unshuffle(view, r_type, false);
41534298 Valtype16* wv = reinterpret_cast<Valtype16*>(view);
41544299 Valtype16 val = elfcpp::Swap<16, big_endian>::readval(wv);
41554300
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);
41584303
4159- Valtype32 x = psymval->value(object, addend);
4304+ Valtype x = psymval->value(object, addend);
41604305 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);
41664316 }
41674317
41684318 // R_MIPS_32: S + A
41694319 static inline typename This::Status
41704320 rel32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
41714321 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)
41734323 {
4174- mips_reloc_unshuffle(view, r_type, false);
41754324 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
4176- Valtype32 addend = (extract_addend
4325+ Valtype addend = (extract_addend
41774326 ? 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+
41824335 return This::STATUS_OKAY;
41834336 }
41844337
@@ -4187,11 +4340,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
41874340 reljalr(unsigned char* view, const Mips_relobj<size, big_endian>* object,
41884341 const Symbol_value<size>* psymval, Mips_address address,
41894342 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)
41914345 {
4192- mips_reloc_unshuffle(view, r_type, false);
41934346 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
4194- Valtype32 addend = extract_addend ? 0 : addend_a;
4347+ Valtype addend = extract_addend ? 0 : addend_a;
41954348 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
41964349
41974350 // 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>
42114364 }
42124365 }
42134366
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+
42164372 return This::STATUS_OKAY;
42174373 }
42184374
@@ -4220,16 +4376,20 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
42204376 static inline typename This::Status
42214377 relpc32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
42224378 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)
42244381 {
4225- mips_reloc_unshuffle(view, r_type, false);
42264382 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
4227- Valtype32 addend = (extract_addend
4383+ Valtype addend = (extract_addend
42284384 ? 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+
42334393 return This::STATUS_OKAY;
42344394 }
42354395
@@ -4239,13 +4399,12 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
42394399 const Symbol_value<size>* psymval, Mips_address address,
42404400 bool local, Mips_address addend_a, bool extract_addend,
42414401 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)
42434403 {
4244- mips_reloc_unshuffle(view, r_type, false);
42454404 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
42464405 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
42474406
4248- Valtype32 addend;
4407+ Valtype addend;
42494408 if (extract_addend)
42504409 {
42514410 if (r_type == elfcpp::R_MICROMIPS_26_S1)
@@ -4258,11 +4417,10 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
42584417
42594418 // Make sure the target of JALX is word-aligned. Bit 0 must be
42604419 // the correct ISA mode selector and bit 1 must be 0.
4261- if (cross_mode_jump
4420+ if (!calculate_only && cross_mode_jump
42624421 && (psymval->value(object, 0) & 3) != (r_type == elfcpp::R_MIPS_26))
42634422 {
42644423 gold_warning(_("JALX to a non-word-aligned address"));
4265- mips_reloc_shuffle(view, r_type, !parameters->options().relocatable());
42664424 return This::STATUS_BAD_RELOC;
42674425 }
42684426
@@ -4270,7 +4428,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
42704428 unsigned int shift =
42714429 (!cross_mode_jump && r_type == elfcpp::R_MICROMIPS_26_S1) ? 1 : 2;
42724430
4273- Valtype32 x;
4431+ Valtype x;
42744432 if (local)
42754433 x = addend | ((address + 4) & (0xfc000000 << shift));
42764434 else
@@ -4282,7 +4440,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
42824440 }
42834441 x = psymval->value(object, x) >> shift;
42844442
4285- if (!local && !gsym->is_weak_undefined())
4443+ if (!calculate_only && !local && !gsym->is_weak_undefined())
42864444 {
42874445 if ((x >> 26) != ((address + 4) >> (26 + shift)))
42884446 {
@@ -4320,7 +4478,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
43204478
43214479 // If the opcode is not JAL or JALX, there's a problem. We cannot
43224480 // convert J or JALS to JALX.
4323- if (!ok)
4481+ if (!calculate_only && !ok)
43244482 {
43254483 gold_error(_("Unsupported jump between ISA modes; consider "
43264484 "recompiling with interlinking enabled."));
@@ -4349,8 +4507,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
43494507 }
43504508 }
43514509
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+
43544515 return This::STATUS_OKAY;
43554516 }
43564517
@@ -4358,22 +4519,28 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
43584519 static inline typename This::Status
43594520 relpc16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
43604521 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)
43624524 {
4363- mips_reloc_unshuffle(view, r_type, false);
43644525 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
43654526 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
43664527
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);
43694531
4370- Valtype32 x = psymval->value(object, addend) - address;
4532+ Valtype x = psymval->value(object, addend) - address;
43714533 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);
43774544 }
43784545
43794546 // R_MICROMIPS_PC7_S1
@@ -4382,22 +4549,26 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
43824549 const Mips_relobj<size, big_endian>* object,
43834550 const Symbol_value<size>* psymval, Mips_address address,
43844551 Mips_address addend_a, bool extract_addend,
4385- unsigned int r_type)
4552+ bool calculate_only, Valtype* calculated_value)
43864553 {
4387- mips_reloc_unshuffle(view, r_type, false);
43884554 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
43894555 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
43904556
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;
43934559
4394- Valtype32 x = psymval->value(object, addend) - address;
4560+ Valtype x = psymval->value(object, addend) - address;
43954561 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);
44014572 }
44024573
44034574 // R_MICROMIPS_PC10_S1
@@ -4406,22 +4577,27 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
44064577 const Mips_relobj<size, big_endian>* object,
44074578 const Symbol_value<size>* psymval, Mips_address address,
44084579 Mips_address addend_a, bool extract_addend,
4409- unsigned int r_type)
4580+ bool calculate_only, Valtype* calculated_value)
44104581 {
4411- mips_reloc_unshuffle(view, r_type, false);
44124582 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
44134583 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
44144584
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);
44174588
4418- Valtype32 x = psymval->value(object, addend) - address;
4589+ Valtype x = psymval->value(object, addend) - address;
44194590 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);
44254601 }
44264602
44274603 // R_MICROMIPS_PC16_S1
@@ -4430,22 +4606,27 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
44304606 const Mips_relobj<size, big_endian>* object,
44314607 const Symbol_value<size>* psymval, Mips_address address,
44324608 Mips_address addend_a, bool extract_addend,
4433- unsigned int r_type)
4609+ bool calculate_only, Valtype* calculated_value)
44344610 {
4435- mips_reloc_unshuffle(view, r_type, false);
44364611 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
44374612 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
44384613
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);
44414617
4442- Valtype32 x = psymval->value(object, addend) - address;
4618+ Valtype x = psymval->value(object, addend) - address;
44434619 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);
44494630 }
44504631
44514632 // R_MIPS_HI16, R_MIPS16_HI16, R_MICROMIPS_HI16,
@@ -4468,13 +4649,13 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
44684649 const Symbol_value<size>* psymval, Mips_address addend_hi,
44694650 Mips_address address, bool is_gp_disp, unsigned int r_type,
44704651 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)
44724654 {
4473- mips_reloc_unshuffle(view, r_type, false);
44744655 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
44754656 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
44764657
4477- Valtype32 addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
4658+ Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
44784659 : addend_hi);
44794660
44804661 Valtype32 value;
@@ -4505,13 +4686,19 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
45054686 gp_disp = target->adjusted_gp_value(object) - address;
45064687 value = gp_disp + addend;
45074688 }
4508- Valtype32 x = ((value + 0x8000) >> 16) & 0xffff;
4689+ Valtype x = ((value + 0x8000) >> 16) & 0xffff;
45094690 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);
45154702 }
45164703
45174704 // R_MIPS_GOT16, R_MIPS16_GOT16, R_MICROMIPS_GOT16
@@ -4532,14 +4719,14 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
45324719 do_relgot16_local(unsigned char* view,
45334720 const Mips_relobj<size, big_endian>* object,
45344721 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)
45374725 {
4538- mips_reloc_unshuffle(view, r_type, false);
45394726 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
45404727 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
45414728
4542- Valtype32 addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
4729+ Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
45434730 : addend_hi);
45444731
45454732 // Find GOT page entry.
@@ -4550,13 +4737,18 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
45504737 target->got_section()->get_got_page_offset(value, object);
45514738
45524739 // 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);
45544741 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);
45604752 }
45614753
45624754 // 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>
45654757 const Mips_relobj<size, big_endian>* object,
45664758 const Symbol_value<size>* psymval, Mips_address addend_a,
45674759 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)
45694762 {
4570- mips_reloc_unshuffle(view, r_type, false);
45714763 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
45724764 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
45734765
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);
45764768
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)
45814770 {
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())
45854776 {
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;
45924793 }
4593- else
4594- ++it;
4595- }
45964794
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())
46054799 {
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;
46124818 }
4613- else
4614- ++it2;
46154819 }
46164820
46174821 // Resolve R_MIPS_LO16 relocation.
4618- Valtype32 x;
4822+ Valtype x;
46194823 if (!is_gp_disp)
46204824 x = psymval->value(object, addend);
46214825 else
@@ -4648,8 +4852,12 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
46484852 x = gp_disp + addend;
46494853 }
46504854 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+
46534861 return This::STATUS_OKAY;
46544862 }
46554863
@@ -4660,18 +4868,42 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
46604868 // R_MIPS_TLS_LDM, R_MIPS16_TLS_LDM, R_MICROMIPS_TLS_LDM
46614869 // R_MIPS_GOT_DISP, R_MICROMIPS_GOT_DISP
46624870 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)
46644873 {
4665- mips_reloc_unshuffle(view, r_type, false);
46664874 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
46674875 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
4668- Valtype32 x = gp_offset;
4876+ Valtype x = gp_offset;
46694877 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);
46754907 }
46764908
46774909 // R_MIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE
@@ -4679,25 +4911,30 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
46794911 relgotpage(Target_mips<size, big_endian>* target, unsigned char* view,
46804912 const Mips_relobj<size, big_endian>* object,
46814913 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)
46834916 {
4684- mips_reloc_unshuffle(view, r_type, false);
46854917 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
46864918 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;
46884920
46894921 // Find a GOT page entry that points to within 32KB of symbol + addend.
46904922 Mips_address value = (psymval->value(object, addend) + 0x8000) & ~0xffff;
46914923 unsigned int got_offset =
46924924 target->got_section()->get_got_page_offset(value, object);
46934925
4694- Valtype32 x = target->got_section()->gp_offset(got_offset, object);
4926+ Valtype x = target->got_section()->gp_offset(got_offset, object);
46954927 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);
47014938 }
47024939
47034940 // R_MIPS_GOT_OFST, R_MICROMIPS_GOT_OFST
@@ -4705,18 +4942,18 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
47054942 relgotofst(Target_mips<size, big_endian>* target, unsigned char* view,
47064943 const Mips_relobj<size, big_endian>* object,
47074944 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)
47094947 {
4710- mips_reloc_unshuffle(view, r_type, false);
47114948 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
47124949 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;
47144951
47154952 // For a local symbol, find a GOT page entry that points to within 32KB of
47164953 // symbol + addend. Relocation value is the offset of the GOT page entry's
47174954 // value from symbol + addend.
47184955 // For a global symbol, relocation value is addend.
4719- Valtype32 x;
4956+ Valtype x;
47204957 if (local)
47214958 {
47224959 // Find GOT page entry.
@@ -4729,41 +4966,54 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
47294966 else
47304967 x = addend;
47314968 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);
47374979 }
47384980
47394981 // R_MIPS_GOT_HI16, R_MIPS_CALL_HI16,
47404982 // R_MICROMIPS_GOT_HI16, R_MICROMIPS_CALL_HI16
47414983 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)
47434986 {
4744- mips_reloc_unshuffle(view, r_type, false);
47454987 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
47464988 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
4747- Valtype32 x = gp_offset;
4989+ Valtype x = gp_offset;
47484990 x = ((x + 0x8000) >> 16) & 0xffff;
47494991 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+
47524998 return This::STATUS_OKAY;
47534999 }
47545000
47555001 // R_MIPS_GOT_LO16, R_MIPS_CALL_LO16,
47565002 // R_MICROMIPS_GOT_LO16, R_MICROMIPS_CALL_LO16
47575003 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)
47595006 {
4760- mips_reloc_unshuffle(view, r_type, false);
47615007 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
47625008 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
4763- Valtype32 x = gp_offset;
5009+ Valtype x = gp_offset;
47645010 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+
47675017 return This::STATUS_OKAY;
47685018 }
47695019
@@ -4773,13 +5023,13 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
47735023 relgprel(unsigned char* view, const Mips_relobj<size, big_endian>* object,
47745024 const Symbol_value<size>* psymval, Mips_address gp,
47755025 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)
47775028 {
4778- mips_reloc_unshuffle(view, r_type, false);
47795029 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
47805030 Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
47815031
4782- Valtype32 addend;
5032+ Valtype addend;
47835033 if (extract_addend)
47845034 {
47855035 if (r_type == elfcpp::R_MICROMIPS_GPREL7_S2)
@@ -4794,7 +5044,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
47945044 else
47955045 addend = addend_a;
47965046
4797- Valtype32 x = psymval->value(object, addend) - gp;
5047+ Valtype x = psymval->value(object, addend) - gp;
47985048
47995049 // If the symbol was local, any earlier relocatable links will
48005050 // have adjusted its addend with the gp offset, so compensate
@@ -4808,9 +5058,16 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
48085058 val = Bits<32>::bit_select32(val, x, 0x7f);
48095059 else
48105060 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)
48145071 {
48155072 gold_error(_("small-data section exceeds 64KB; lower small-data size "
48165073 "limit (see option -G)"));
@@ -4823,17 +5080,21 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
48235080 static inline typename This::Status
48245081 relgprel32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
48255082 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)
48275085 {
4828- mips_reloc_unshuffle(view, r_type, false);
48295086 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
48305087 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;
48325089
48335090 // 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+
48375098 return This::STATUS_OKAY;
48385099 }
48395100
@@ -4843,18 +5104,22 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
48435104 static inline typename This::Status
48445105 tlsrelhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
48455106 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)
48475109 {
4848- mips_reloc_unshuffle(view, r_type, false);
48495110 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
48505111 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;
48525113
48535114 // 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;
48555116 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+
48585123 return This::STATUS_OKAY;
48595124 }
48605125
@@ -4864,18 +5129,22 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
48645129 static inline typename This::Status
48655130 tlsrello16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
48665131 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)
48685134 {
4869- mips_reloc_unshuffle(view, r_type, false);
48705135 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
48715136 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;
48735138
48745139 // 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;
48765141 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+
48795148 return This::STATUS_OKAY;
48805149 }
48815150
@@ -4884,17 +5153,21 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
48845153 static inline typename This::Status
48855154 tlsrel32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
48865155 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)
48885158 {
4889- mips_reloc_unshuffle(view, r_type, false);
48905159 Valtype32* wv = reinterpret_cast<Valtype32*>(view);
48915160 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;
48935162
48945163 // 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+
48985171 return This::STATUS_OKAY;
48995172 }
49005173
@@ -4902,18 +5175,47 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
49025175 static inline typename This::Status
49035176 relsub(unsigned char* view, const Mips_relobj<size, big_endian>* object,
49045177 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)
49065179 {
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);
49115190
4912- Valtype32 x = psymval->value(object, -addend);
4913- elfcpp::Swap<32, big_endian>::writeval(wv, x);
4914- mips_reloc_shuffle(view, r_type, false);
49155191 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+
49175219 };
49185220
49195221 template<int size, bool big_endian>
@@ -4933,12 +5235,13 @@ template<int size, bool big_endian>
49335235 void
49345236 Mips_got_info<size, big_endian>::record_local_got_symbol(
49355237 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)
49375240 {
49385241 Mips_got_entry<size, big_endian>* entry =
49395242 new Mips_got_entry<size, big_endian>(object, symndx, addend,
49405243 mips_elf_reloc_tls_type(r_type),
4941- shndx);
5244+ shndx, is_section_symbol);
49425245 this->record_got_entry(entry, object);
49435246 }
49445247
@@ -5118,13 +5421,20 @@ Mips_got_info<size, big_endian>::add_local_entries(
51185421 if (entry->is_for_local_symbol() && !entry->is_tls_entry())
51195422 {
51205423 got->add_local(entry->object(), entry->symndx(),
5121- GOT_TYPE_STANDARD);
5424+ GOT_TYPE_STANDARD, entry->addend());
51225425 unsigned int got_offset = entry->object()->local_got_offset(
5123- entry->symndx(), GOT_TYPE_STANDARD);
5426+ entry->symndx(), GOT_TYPE_STANDARD, entry->addend());
51245427 if (got->multi_got() && this->index_ > 0
51255428 && 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+ }
51285438 }
51295439 }
51305440
@@ -5322,9 +5632,10 @@ Mips_got_info<size, big_endian>::add_tls_entries(
53225632 got->add_local_pair_with_rel(entry->object(), entry->symndx(),
53235633 entry->shndx(), got_type,
53245634 target->rel_dyn_section(layout),
5325- r_type1);
5635+ r_type1, entry->addend());
53265636 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());
53285639 got->add_static_reloc(got_offset + size/8, r_type2,
53295640 entry->object(), entry->symndx());
53305641 }
@@ -5334,7 +5645,8 @@ Mips_got_info<size, big_endian>::add_tls_entries(
53345645 // the executable.
53355646 unsigned int got_offset = got->add_constant(1);
53365647 entry->object()->set_local_got_offset(entry->symndx(), got_type,
5337- got_offset);
5648+ got_offset,
5649+ entry->addend());
53385650 got->add_constant(0);
53395651 got->add_static_reloc(got_offset + size/8, r_type2,
53405652 entry->object(), entry->symndx());
@@ -5347,12 +5659,15 @@ Mips_got_info<size, big_endian>::add_tls_entries(
53475659 : elfcpp::R_MIPS_TLS_TPREL64);
53485660 if (!parameters->doing_static_link())
53495661 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());
53515664 else
53525665 {
5353- got->add_local(entry->object(), entry->symndx(), got_type);
5666+ got->add_local(entry->object(), entry->symndx(), got_type,
5667+ entry->addend());
53545668 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());
53565671 got->add_static_reloc(got_offset, r_type, entry->object(),
53575672 entry->symndx());
53585673 }
@@ -6094,21 +6409,104 @@ Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
60946409 this->cprmask4_ = elfcpp::Swap<size, big_endian>::readval(view + 16);
60956410 }
60966411
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.
61036431
6104- if (strcmp(name, ".pdr") == 0)
6432+ if (shdr.get_sh_type() == elfcpp::SHT_MIPS_OPTIONS)
61056433 {
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+
61126510 // Discard MIPS16 stub secions that are not needed.
61136511
61146512 template<int size, bool big_endian>
@@ -6426,7 +6824,7 @@ template<int size, bool big_endian>
64266824 const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry[] =
64276825 {
64286826 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)
64306828 0x03200008, // jr $25
64316829 0x25f80000 // addiu $24, $15, %lo(.got.plt entry)
64326830 };
@@ -7712,7 +8110,7 @@ Target_mips<size, big_endian>::gc_process_relocs(
77128110 Layout* layout,
77138111 Sized_relobj_file<size, big_endian>* object,
77148112 unsigned int data_shndx,
7715- unsigned int,
8113+ unsigned int sh_type,
77168114 const unsigned char* prelocs,
77178115 size_t reloc_count,
77188116 Output_section* output_section,
@@ -7721,21 +8119,45 @@ Target_mips<size, big_endian>::gc_process_relocs(
77218119 const unsigned char* plocal_symbols)
77228120 {
77238121 typedef Target_mips<size, big_endian> Mips;
7724- typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
7725- Classify_reloc;
77268122
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();
77398161 }
77408162
77418163 // Scan relocations for a section.
@@ -8204,9 +8626,20 @@ Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
82048626 elfcpp::Ehdr<size, big_endian> ehdr(pehdr);
82058627 elfcpp::Elf_Word in_flags = ehdr.get_e_flags();
82068628 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+ }
82078639
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);
82108643 }
82118644 }
82128645
@@ -8506,6 +8939,7 @@ mips_get_size_for_reloc(unsigned int r_type, Relobj* object)
85068939 case elfcpp::R_MIPS_PC32:
85078940 case elfcpp::R_MIPS_GPREL32:
85088941 case elfcpp::R_MIPS_JALR:
8942+ case elfcpp::R_MIPS_EH:
85098943 return 4;
85108944
85118945 case elfcpp::R_MIPS_16:
@@ -8571,25 +9005,48 @@ Target_mips<size, big_endian>::scan_relocatable_relocs(
85719005 const unsigned char* plocal_symbols,
85729006 Relocatable_relocs* rr)
85739007 {
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();
85939050 }
85949051
85959052 // Scan the relocs for --emit-relocs.
@@ -8610,25 +9067,48 @@ Target_mips<size, big_endian>::emit_relocs_scan(
86109067 const unsigned char* plocal_syms,
86119068 Relocatable_relocs* rr)
86129069 {
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();
86329112 }
86339113
86349114 // Emit relocations for a section.
@@ -8649,22 +9129,42 @@ Target_mips<size, big_endian>::relocate_relocs(
86499129 unsigned char* reloc_view,
86509130 section_size_type reloc_view_size)
86519131 {
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();
86689168 }
86699169
86709170 // Perform target-specific processing in a relocatable link. This is
@@ -8762,7 +9262,7 @@ Target_mips<size, big_endian>::relocate_special_relocatable(
87629262 // file to refer to that same address. This adjustment to
87639263 // the addend is the same calculation we use for a simple
87649264 // absolute relocation for the input section symbol.
8765-
9265+ Valtype calculated_value = 0;
87669266 const Symbol_value<size>* psymval = object->local_symbol(r_sym);
87679267
87689268 unsigned char* paddend = view + offset;
@@ -8772,7 +9272,8 @@ Target_mips<size, big_endian>::relocate_special_relocatable(
87729272 case elfcpp::R_MIPS_26:
87739273 reloc_status = Reloc_funcs::rel26(paddend, object, psymval,
87749274 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);
87769277 break;
87779278
87789279 default:
@@ -8905,6 +9406,7 @@ Target_mips<size, big_endian>::Scan::local(
89059406 case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
89069407 case elfcpp::R_MICROMIPS_TLS_GD:
89079408 case elfcpp::R_MICROMIPS_TLS_LDM:
9409+ case elfcpp::R_MIPS_EH:
89089410 // We need a GOT section.
89099411 target->got_section(symtab, layout);
89109412 break;
@@ -8915,7 +9417,8 @@ Target_mips<size, big_endian>::Scan::local(
89159417
89169418 if (call_lo16_reloc(r_type)
89179419 || got_lo16_reloc(r_type)
8918- || got_disp_reloc(r_type))
9420+ || got_disp_reloc(r_type)
9421+ || eh_reloc(r_type))
89199422 {
89209423 // We may need a local GOT entry for this relocation. We
89219424 // don't count R_MIPS_GOT_PAGE because we can estimate the
@@ -8926,7 +9429,9 @@ Target_mips<size, big_endian>::Scan::local(
89269429 // R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
89279430 Mips_output_data_got<size, big_endian>* got =
89289431 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);
89309435 }
89319436
89329437 switch (r_type)
@@ -9059,6 +9564,8 @@ Target_mips<size, big_endian>::Scan::local(
90599564 // If building a shared library (or a position-independent
90609565 // executable), we need to create a dynamic relocation for
90619566 // this location.
9567+ if (is_readonly_section(output_section))
9568+ break;
90629569 Reloc_section* rel_dyn = target->rel_dyn_section(layout);
90639570 rel_dyn->add_symbolless_local_addend(object, r_sym,
90649571 elfcpp::R_MIPS_REL32,
@@ -9103,7 +9610,7 @@ Target_mips<size, big_endian>::Scan::local(
91039610 break;
91049611 }
91059612 got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type,
9106- shndx);
9613+ shndx, false);
91079614 }
91089615 else
91099616 {
@@ -9120,7 +9627,7 @@ Target_mips<size, big_endian>::Scan::local(
91209627 // We always record LDM symbols as local with index 0.
91219628 target->got_section()->record_local_got_symbol(mips_obj, 0,
91229629 r_addend, r_type,
9123- -1U);
9630+ -1U, false);
91249631 }
91259632 else
91269633 {
@@ -9138,7 +9645,7 @@ Target_mips<size, big_endian>::Scan::local(
91389645 Mips_output_data_got<size, big_endian>* got =
91399646 target->got_section(symtab, layout);
91409647 got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type,
9141- -1U);
9648+ -1U, false);
91429649 }
91439650 else
91449651 {
@@ -9359,6 +9866,7 @@ Target_mips<size, big_endian>::Scan::global(
93599866 case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
93609867 case elfcpp::R_MICROMIPS_TLS_GD:
93619868 case elfcpp::R_MICROMIPS_TLS_LDM:
9869+ case elfcpp::R_MIPS_EH:
93629870 // We need a GOT section.
93639871 target->got_section(symtab, layout);
93649872 break;
@@ -9385,14 +9893,14 @@ Target_mips<size, big_endian>::Scan::global(
93859893 case elfcpp::R_MIPS_32:
93869894 case elfcpp::R_MIPS_REL32:
93879895 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)
93909901 {
93919902 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();
93969904 can_make_dynamic = true;
93979905 break;
93989906 }
@@ -9489,8 +9997,8 @@ Target_mips<size, big_endian>::Scan::global(
94899997 {
94909998 if (gsym->may_need_copy_reloc())
94919999 {
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);
949410002 }
949510003 else if (can_make_dynamic)
949610004 {
@@ -9527,6 +10035,7 @@ Target_mips<size, big_endian>::Scan::global(
952710035 case elfcpp::R_MICROMIPS_GOT_LO16:
952810036 case elfcpp::R_MIPS_GOT_DISP:
952910037 case elfcpp::R_MICROMIPS_GOT_DISP:
10038+ case elfcpp::R_MIPS_EH:
953010039 {
953110040 // The symbol requires a GOT entry.
953210041 Mips_output_data_got<size, big_endian>* got =
@@ -9614,7 +10123,7 @@ Target_mips<size, big_endian>::Scan::global(
961410123 // We always record LDM symbols as local with index 0.
961510124 target->got_section()->record_local_got_symbol(mips_obj, 0,
961610125 r_addend, r_type,
9617- -1U);
10126+ -1U, false);
961810127 }
961910128 else
962010129 {
@@ -9748,11 +10257,14 @@ Target_mips<size, big_endian>::Scan::global(
974810257 gsym);
974910258 }
975010259
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.
975210264
975310265 template<int size, bool big_endian>
975410266 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(
975610268 const Mips_symbol<size>* gsym,
975710269 unsigned int r_type,
975810270 Output_section* output_section,
@@ -9817,6 +10329,9 @@ Target_mips<size, big_endian>::Relocate::relocate(
981710329 Mips_address r_offset;
981810330 unsigned int r_sym;
981910331 unsigned int r_type;
10332+ unsigned int r_type2;
10333+ unsigned int r_type3;
10334+ unsigned char r_ssym;
982010335 typename elfcpp::Elf_types<size>::Elf_Swxword r_addend;
982110336
982210337 if (rel_type == elfcpp::SHT_RELA)
@@ -9827,17 +10342,25 @@ Target_mips<size, big_endian>::Relocate::relocate(
982710342 get_r_sym(&rela);
982810343 r_type = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
982910344 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);
983010351 r_addend = rela.get_r_addend();
983110352 }
983210353 else
983310354 {
9834-
983510355 const Reltype rel(preloc);
983610356 r_offset = rel.get_r_offset();
983710357 r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
983810358 get_r_sym(&rel);
983910359 r_type = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
984010360 get_r_type(&rel);
10361+ r_ssym = 0;
10362+ r_type2 = 0;
10363+ r_type3 = 0;
984110364 r_addend = 0;
984210365 }
984310366
@@ -10101,320 +10624,479 @@ Target_mips<size, big_endian>::Relocate::relocate(
1010110624 unsigned int got_offset = 0;
1010210625 int gp_offset = 0;
1010310626
10104- bool update_got_entry = false;
10627+ bool calculate_only = false;
10628+ Valtype calculated_value = 0;
1010510629 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)
1010710647 {
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;
1011410650
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())
1012310657 {
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)
1012710659 {
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+ }
1013310678 psymval = &symval;
1013410679 }
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+ }
1013710685 }
10138- break;
1013910686
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;
1014210697
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>();
1014710715
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;
1015910723
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();
1016710739
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;
1017610746
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;
1018310759
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;
1018510777
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;
1019510788
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.
1023410795
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.
1024910797
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;
1026110808
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;
1027410861
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);
1028010906 got_offset = target->got_section()->got_offset(gsym,
1028110907 GOT_TYPE_STANDARD,
1028210908 object);
1028310909 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;
1029210916
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;
1030510949
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;
1032010965
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;
1033010981
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;
1033610992
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;
1034311000
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;
1035611008
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;
1040711024
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;
1041611094 }
1041711095
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+
1041811100 // Report any errors.
1041911101 switch (reloc_status)
1042011102 {
@@ -10494,6 +11176,7 @@ Target_mips<size, big_endian>::Scan::get_reference_flags(
1049411176 case elfcpp::R_MICROMIPS_GOT_LO16:
1049511177 case elfcpp::R_MICROMIPS_CALL_HI16:
1049611178 case elfcpp::R_MICROMIPS_CALL_LO16:
11179+ case elfcpp::R_MIPS_EH:
1049711180 // Absolute in GOT.
1049811181 return Symbol::RELATIVE_REF;
1049911182
@@ -10665,7 +11348,7 @@ const Target::Target_info Target_mips<size, big_endian>::mips_info =
1066511348 true, // is_default_stack_executable
1066611349 false, // can_icf_inline_merge_sections
1066711350 '\0', // wrap_char
10668- "/lib/ld.so.1", // dynamic_linker
11351+ size == 32 ? "/lib/ld.so.1" : "/lib64/ld.so.1", // dynamic_linker
1066911352 0x400000, // default_text_segment_address
1067011353 64 * 1024, // abi_pagesize (overridable by -z max-page-size)
1067111354 4 * 1024, // common_pagesize (overridable by -z common-page-size)
@@ -10734,8 +11417,8 @@ public:
1073411417 (big_endian ? "elf64-tradbigmips" : "elf64-tradlittlemips") :
1073511418 (big_endian ? "elf32-tradbigmips" : "elf32-tradlittlemips")),
1073611419 (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")))
1073911422 { }
1074011423
1074111424 Target* do_instantiate_target()