• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

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

Revisión8c13bcd2209cb776aa2cf7e5016b7884b0aecbf6 (tree)
Tiempo2017-04-26 12:07:52
AutorCary Coutant <ccoutant@gmai...>
CommiterCary Coutant

Log Message

Experimental implementation of RELR-style relocations.

For x86-64 only. Instead of R_X86_64_RELATIVE relocations, we
write the offsets of the relocation targets to a new section,
.relr.dyn, with section type SHT_RELR.

Cambiar Resumen

Diferencia incremental

--- a/elfcpp/elfcpp.h
+++ b/elfcpp/elfcpp.h
@@ -358,6 +358,7 @@ enum SHT
358358 SHT_PREINIT_ARRAY = 16,
359359 SHT_GROUP = 17,
360360 SHT_SYMTAB_SHNDX = 18,
361+ SHT_RELR = 19, // Experimental
361362 SHT_LOOS = 0x60000000,
362363 SHT_HIOS = 0x6fffffff,
363364 SHT_LOPROC = 0x70000000,
@@ -719,6 +720,11 @@ enum DT
719720
720721 DT_PREINIT_ARRAY = 32,
721722 DT_PREINIT_ARRAYSZ = 33,
723+ DT_SYMTAB_SHNDX = 34,
724+ DT_RELRSZ = 35, // Experimental
725+ DT_RELR = 36, // Experimental
726+ DT_RELRENT = 37, // Experimental
727+
722728 DT_LOOS = 0x6000000d,
723729 DT_HIOS = 0x6ffff000,
724730 DT_LOPROC = 0x70000000,
@@ -1021,6 +1027,7 @@ struct Elf_sizes
10211027 // Sizes of ELF reloc entries.
10221028 static const int rel_size = sizeof(internal::Rel_data<size>);
10231029 static const int rela_size = sizeof(internal::Rela_data<size>);
1030+ static const int relr_size = sizeof(internal::Relr_data<size>);
10241031 // Size of ELF dynamic entry.
10251032 static const int dyn_size = sizeof(internal::Dyn_data<size>);
10261033 // Size of ELF version structures.
@@ -1666,6 +1673,48 @@ class Rela_write
16661673 internal::Rela_data<size>* p_;
16671674 };
16681675
1676+// Accessor class for an ELF Relr relocation.
1677+
1678+template<int size, bool big_endian>
1679+class Relr
1680+{
1681+ public:
1682+ Relr(const unsigned char* p)
1683+ : p_(reinterpret_cast<const internal::Relr_data<size>*>(p))
1684+ { }
1685+
1686+ template<typename File>
1687+ Relr(File* file, typename File::Location loc)
1688+ : p_(reinterpret_cast<const internal::Relr_data<size>*>(
1689+ file->view(loc.file_offset, loc.data_size).data()))
1690+ { }
1691+
1692+ typename Elf_types<size>::Elf_Addr
1693+ get_r_offset() const
1694+ { return Convert<size, big_endian>::convert_host(this->p_->r_offset); }
1695+
1696+ private:
1697+ const internal::Relr_data<size>* p_;
1698+};
1699+
1700+// Writer class for an ELF Relr relocation.
1701+
1702+template<int size, bool big_endian>
1703+class Relr_write
1704+{
1705+ public:
1706+ Relr_write(unsigned char* p)
1707+ : p_(reinterpret_cast<internal::Relr_data<size>*>(p))
1708+ { }
1709+
1710+ void
1711+ put_r_offset(typename Elf_types<size>::Elf_Addr v)
1712+ { this->p_->r_offset = Convert<size, big_endian>::convert_host(v); }
1713+
1714+ private:
1715+ internal::Relr_data<size>* p_;
1716+};
1717+
16691718 // MIPS-64 has a non-standard relocation layout.
16701719
16711720 template<bool big_endian>
--- a/elfcpp/elfcpp_internal.h
+++ b/elfcpp/elfcpp_internal.h
@@ -180,6 +180,12 @@ struct Rela_data
180180 typename Elf_types<size>::Elf_Swxword r_addend;
181181 };
182182
183+template<int size>
184+struct Relr_data
185+{
186+ typename Elf_types<size>::Elf_Addr r_offset;
187+};
188+
183189 // MIPS-64 has a non-standard layout for relocations.
184190
185191 struct Mips64_rel_data
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -4710,7 +4710,8 @@ void
47104710 Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
47114711 const Output_data* plt_rel,
47124712 const Output_data_reloc_generic* dyn_rel,
4713- bool add_debug, bool dynrel_includes_plt)
4713+ bool add_debug, bool dynrel_includes_plt,
4714+ const Output_data_reloc_generic* dyn_relr)
47144715 {
47154716 Output_data_dynamic* odyn = this->dynamic_data_;
47164717 if (odyn == NULL)
@@ -4783,6 +4784,14 @@ Layout::add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
47834784 }
47844785 }
47854786
4787+ if (dyn_relr != NULL && dyn_relr->output_section() != NULL)
4788+ {
4789+ const int size = parameters->target().get_size();
4790+ odyn->add_section_address(elfcpp::DT_RELR, dyn_relr->output_section());
4791+ odyn->add_section_size(elfcpp::DT_RELRSZ, dyn_relr->output_section());
4792+ odyn->add_constant(elfcpp::DT_RELRENT, size / 8);
4793+ }
4794+
47864795 if (add_debug && !parameters->options().shared())
47874796 {
47884797 // The value of the DT_DEBUG tag is filled in by the dynamic
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -900,7 +900,8 @@ class Layout
900900 add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
901901 const Output_data* plt_rel,
902902 const Output_data_reloc_generic* dyn_rel,
903- bool add_debug, bool dynrel_includes_plt);
903+ bool add_debug, bool dynrel_includes_plt,
904+ const Output_data_reloc_generic* dyn_relr = NULL);
904905
905906 // Add a target-specific dynamic tag with constant value.
906907 void
--- a/gold/options.h
+++ b/gold/options.h
@@ -834,6 +834,10 @@ class General_options
834834 N_("Exclude libraries from automatic export"),
835835 N_(("lib,lib ...")));
836836
837+ DEFINE_bool(experimental_use_relr, options::TWO_DASHES, '\0', false,
838+ N_("(x86-64 only) Generate RELR dynamic relocations"),
839+ N_("Do not generate RELR dynamic relocations"));
840+
837841 DEFINE_bool(export_dynamic, options::TWO_DASHES, 'E', false,
838842 N_("Export all dynamic symbols"),
839843 N_("Do not export all dynamic symbols"));
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1224,6 +1224,17 @@ Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>::write(
12241224 orel.put_r_addend(addend);
12251225 }
12261226
1227+// Write out a Relr relocation.
1228+
1229+template<bool dynamic, int size, bool big_endian>
1230+void
1231+Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>::write(
1232+ unsigned char* pov) const
1233+{
1234+ elfcpp::Relr_write<size, big_endian> orel(pov);
1235+ orel.put_r_offset(this->rel_.get_address());
1236+}
1237+
12271238 // Output_data_reloc_base methods.
12281239
12291240 // Adjust the output section.
@@ -1237,6 +1248,8 @@ Output_data_reloc_base<sh_type, dynamic, size, big_endian>
12371248 os->set_entsize(elfcpp::Elf_sizes<size>::rel_size);
12381249 else if (sh_type == elfcpp::SHT_RELA)
12391250 os->set_entsize(elfcpp::Elf_sizes<size>::rela_size);
1251+ else if (sh_type == elfcpp::SHT_RELR)
1252+ os->set_entsize(elfcpp::Elf_sizes<size>::relr_size);
12401253 else
12411254 gold_unreachable();
12421255
@@ -5528,6 +5541,26 @@ class Output_data_reloc<elfcpp::SHT_RELA, true, 64, true>;
55285541
55295542 #ifdef HAVE_TARGET_32_LITTLE
55305543 template
5544+class Output_data_reloc<elfcpp::SHT_RELR, true, 32, false>;
5545+#endif
5546+
5547+#ifdef HAVE_TARGET_32_BIG
5548+template
5549+class Output_data_reloc<elfcpp::SHT_RELR, true, 32, true>;
5550+#endif
5551+
5552+#ifdef HAVE_TARGET_64_LITTLE
5553+template
5554+class Output_data_reloc<elfcpp::SHT_RELR, true, 64, false>;
5555+#endif
5556+
5557+#ifdef HAVE_TARGET_64_BIG
5558+template
5559+class Output_data_reloc<elfcpp::SHT_RELR, true, 64, true>;
5560+#endif
5561+
5562+#ifdef HAVE_TARGET_32_LITTLE
5563+template
55315564 class Output_relocatable_relocs<elfcpp::SHT_REL, 32, false>;
55325565 #endif
55335566
--- a/gold/output.h
+++ b/gold/output.h
@@ -1500,6 +1500,104 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
15001500 Addend addend_;
15011501 };
15021502
1503+// The SHT_RELR version of Output_reloc<>. This is a relative reloc,
1504+// and holds nothing but an offset. Rather than duplicate all the fields
1505+// of the SHT_REL version except for the symbol and relocation type, we
1506+// simply use an SHT_REL as a proxy.
1507+
1508+template<bool dynamic, int size, bool big_endian>
1509+class Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>
1510+{
1511+ public:
1512+ typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
1513+
1514+ // An uninitialized entry.
1515+ Output_reloc()
1516+ : rel_()
1517+ { }
1518+
1519+ // A reloc against a global symbol.
1520+
1521+ Output_reloc(Symbol* gsym, Output_data* od, Address address)
1522+ : rel_(gsym, 0, od, address, true, true, false)
1523+ { }
1524+
1525+ Output_reloc(Symbol* gsym, Sized_relobj<size, big_endian>* relobj,
1526+ unsigned int shndx, Address address)
1527+ : rel_(gsym, 0, relobj, shndx, address, true, true, false)
1528+ { }
1529+
1530+ // A reloc against a local symbol.
1531+
1532+ Output_reloc(Sized_relobj<size, big_endian>* relobj,
1533+ unsigned int local_sym_index, Output_data* od, Address address,
1534+ bool is_section_symbol)
1535+ : rel_(relobj, local_sym_index, 0, od, address, true,
1536+ true, is_section_symbol, false)
1537+ { }
1538+
1539+ Output_reloc(Sized_relobj<size, big_endian>* relobj,
1540+ unsigned int local_sym_index, unsigned int shndx,
1541+ Address address, bool is_section_symbol)
1542+ : rel_(relobj, local_sym_index, 0, shndx, address, true,
1543+ true, is_section_symbol, false)
1544+ { }
1545+
1546+ // A reloc against the STT_SECTION symbol of an output section.
1547+
1548+ Output_reloc(Output_section* os, Output_data* od, Address address)
1549+ : rel_(os, 0, od, address, true)
1550+ { }
1551+
1552+ Output_reloc(Output_section* os, Sized_relobj<size, big_endian>* relobj,
1553+ unsigned int shndx, Address address)
1554+ : rel_(os, 0, relobj, shndx, address, true)
1555+ { }
1556+
1557+ // A relative relocation with no symbol.
1558+
1559+ Output_reloc(Output_data* od, Address address)
1560+ : rel_(0, od, address, true)
1561+ { }
1562+
1563+ Output_reloc(Sized_relobj<size, big_endian>* relobj,
1564+ unsigned int shndx, Address address)
1565+ : rel_(0, relobj, shndx, address, true)
1566+ { }
1567+
1568+ // Return whether this is a RELATIVE relocation.
1569+ bool
1570+ is_relative() const
1571+ { return true; }
1572+
1573+ // Return whether this is a relocation which should not use
1574+ // a symbol, but which obtains its addend from a symbol.
1575+ bool
1576+ is_symbolless() const
1577+ { return true; }
1578+
1579+ // If this relocation is against an input section, return the
1580+ // relocatable object containing the input section.
1581+ Sized_relobj<size, big_endian>*
1582+ get_relobj() const
1583+ { return this->rel_.get_relobj(); }
1584+
1585+ // Write the reloc entry to an output view.
1586+ void
1587+ write(unsigned char* pov) const;
1588+
1589+ // Return whether this reloc should be sorted before the argument
1590+ // when sorting dynamic relocs.
1591+ bool
1592+ sort_before(const Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>&
1593+ r2) const
1594+ { return this->rel_.compare(r2.rel_) < 0; }
1595+
1596+ private:
1597+ // The basic reloc.
1598+ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_;
1599+};
1600+
15031601 // Output_data_reloc_generic is a non-template base class for
15041602 // Output_data_reloc_base. This gives the generic code a way to hold
15051603 // a pointer to a reloc section.
@@ -2344,6 +2442,127 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
23442442 }
23452443 };
23462444
2445+// The SHT_RELR version of Output_data_reloc.
2446+
2447+template<bool dynamic, int size, bool big_endian>
2448+class Output_data_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>
2449+ : public Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size, big_endian>
2450+{
2451+ private:
2452+ typedef Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size,
2453+ big_endian> Base;
2454+
2455+ public:
2456+ typedef typename Base::Output_reloc_type Output_reloc_type;
2457+ typedef typename Output_reloc_type::Address Address;
2458+
2459+ Output_data_reloc()
2460+ : Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size, big_endian>(false)
2461+ { }
2462+
2463+ void
2464+ add_global_generic(Symbol*, unsigned int, Output_data*, uint64_t, uint64_t)
2465+ {
2466+ gold_unreachable();
2467+ }
2468+
2469+ void
2470+ add_global_generic(Symbol*, unsigned int, Output_data*, Relobj*,
2471+ unsigned int, uint64_t, uint64_t)
2472+ {
2473+ gold_unreachable();
2474+ }
2475+
2476+ // Add a RELATIVE reloc against a global symbol. The final relocation
2477+ // will not reference the symbol.
2478+
2479+ void
2480+ add_global_relative(Symbol* gsym, Output_data* od, Address address)
2481+ {
2482+ this->add(od, Output_reloc_type(gsym, od, address));
2483+ }
2484+
2485+ void
2486+ add_global_relative(Symbol* gsym, Output_data* od,
2487+ Sized_relobj<size, big_endian>* relobj,
2488+ unsigned int shndx, Address address)
2489+ {
2490+ this->add(od, Output_reloc_type(gsym, relobj, shndx, address));
2491+ }
2492+
2493+ void
2494+ add_local_generic(Relobj*, unsigned int, unsigned int, Output_data*, uint64_t,
2495+ uint64_t)
2496+ {
2497+ gold_unreachable();
2498+ }
2499+
2500+ void
2501+ add_local_generic(Relobj*, unsigned int, unsigned int, Output_data*,
2502+ unsigned int, uint64_t, uint64_t)
2503+ {
2504+ gold_unreachable();
2505+ }
2506+
2507+ // Add a RELATIVE reloc against a local symbol.
2508+
2509+ void
2510+ add_local_relative(Sized_relobj<size, big_endian>* relobj,
2511+ unsigned int local_sym_index, Output_data* od,
2512+ Address address)
2513+ {
2514+ this->add(od, Output_reloc_type(relobj, local_sym_index, od, address,
2515+ false));
2516+ }
2517+
2518+ void
2519+ add_local_relative(Sized_relobj<size, big_endian>* relobj,
2520+ unsigned int local_sym_index, Output_data* od,
2521+ unsigned int shndx, Address address)
2522+ {
2523+ this->add(od, Output_reloc_type(relobj, local_sym_index, shndx, address,
2524+ false));
2525+ }
2526+
2527+ void
2528+ add_output_section_generic(Output_section*, unsigned int, Output_data*,
2529+ uint64_t, uint64_t)
2530+ {
2531+ gold_unreachable();
2532+ }
2533+
2534+ void
2535+ add_output_section_generic(Output_section*, unsigned int, Output_data*,
2536+ Relobj*, unsigned int, uint64_t, uint64_t)
2537+ {
2538+ gold_unreachable();
2539+ }
2540+
2541+ // Add a RELATIVE reloc against an output section symbol.
2542+
2543+ void
2544+ add_output_section_relative(Output_section* os, Output_data* od,
2545+ Address address)
2546+ { this->add(od, Output_reloc_type(os, od, address)); }
2547+
2548+ void
2549+ add_output_section_relative(Output_section* os, Output_data* od,
2550+ Sized_relobj<size, big_endian>* relobj,
2551+ unsigned int shndx, Address address)
2552+ { this->add(od, Output_reloc_type(os, relobj, shndx, address)); }
2553+
2554+ // Add a relative relocation
2555+
2556+ void
2557+ add_relative(Output_data* od, Address address)
2558+ { this->add(od, Output_reloc_type(od, address)); }
2559+
2560+ void
2561+ add_relative(Output_data* od, Sized_relobj<size, big_endian>* relobj,
2562+ unsigned int shndx, Address address)
2563+ { this->add(od, Output_reloc_type(relobj, shndx, address)); }
2564+};
2565+
23472566 // Output_relocatable_relocs represents a relocation section in a
23482567 // relocatable link. The actual data is written out in the target
23492568 // hook relocate_relocs. This just saves space for it.
--- a/gold/reloc-types.h
+++ b/gold/reloc-types.h
@@ -79,6 +79,27 @@ struct Reloc_types<elfcpp::SHT_RELA, size, big_endian>
7979 { p->put_r_addend(val); }
8080 };
8181
82+template<int size, bool big_endian>
83+struct Reloc_types<elfcpp::SHT_RELR, size, big_endian>
84+{
85+ typedef typename elfcpp::Relr<size, big_endian> Reloc;
86+ typedef typename elfcpp::Relr_write<size, big_endian> Reloc_write;
87+ static const int reloc_size = elfcpp::Elf_sizes<size>::relr_size;
88+
89+ static inline typename elfcpp::Elf_types<size>::Elf_Swxword
90+ get_reloc_addend(const Reloc*)
91+ { gold_unreachable(); }
92+
93+ static inline typename elfcpp::Elf_types<size>::Elf_Swxword
94+ get_reloc_addend_noerror(const Reloc*)
95+ { return 0; }
96+
97+ static inline void
98+ set_reloc_addend(Reloc_write*,
99+ typename elfcpp::Elf_types<size>::Elf_Swxword)
100+ { gold_unreachable(); }
101+};
102+
82103 }; // End namespace gold.
83104
84105 #endif // !defined(GOLD_RELOC_TYPE_SH)
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -584,13 +584,15 @@ class Target_x86_64 : public Sized_target<size, false>
584584 // uses only Elf64_Rela relocation entries with explicit addends."
585585 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, false> Reloc_section;
586586
587+ typedef Output_data_reloc<elfcpp::SHT_RELR, true, size, false> Relr_section;
588+
587589 Target_x86_64(const Target::Target_info* info = &x86_64_info)
588590 : Sized_target<size, false>(info),
589591 got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
590592 got_tlsdesc_(NULL), global_offset_table_(NULL), rela_dyn_(NULL),
591- rela_irelative_(NULL), copy_relocs_(elfcpp::R_X86_64_COPY),
592- got_mod_index_offset_(-1U), tlsdesc_reloc_info_(),
593- tls_base_symbol_defined_(false)
593+ rela_irelative_(NULL), relr_dyn_(NULL),
594+ copy_relocs_(elfcpp::R_X86_64_COPY), got_mod_index_offset_(-1U),
595+ tlsdesc_reloc_info_(), tls_base_symbol_defined_(false)
594596 { }
595597
596598 // Hook for a new output section.
@@ -1172,6 +1174,10 @@ class Target_x86_64 : public Sized_target<size, false>
11721174 Reloc_section*
11731175 rela_irelative_section(Layout*);
11741176
1177+ // Get the RELR dynamic reloc section, creating it if necessary.
1178+ Relr_section*
1179+ relr_dyn_section(Layout*);
1180+
11751181 // Add a potential copy relocation.
11761182 void
11771183 copy_reloc(Symbol_table* symtab, Layout* layout,
@@ -1235,6 +1241,8 @@ class Target_x86_64 : public Sized_target<size, false>
12351241 Reloc_section* rela_dyn_;
12361242 // The section to use for IRELATIVE relocs.
12371243 Reloc_section* rela_irelative_;
1244+ // The RELR dynamic reloc section.
1245+ Relr_section* relr_dyn_;
12381246 // Relocs saved to avoid a COPY reloc.
12391247 Copy_relocs<elfcpp::SHT_RELA, size, false> copy_relocs_;
12401248 // Offset of the GOT entry for the TLS module index.
@@ -1431,6 +1439,23 @@ Target_x86_64<size>::rela_irelative_section(Layout* layout)
14311439 return this->rela_irelative_;
14321440 }
14331441
1442+// Get the RELR dynamic reloc section, creating it if necessary.
1443+
1444+template<int size>
1445+typename Target_x86_64<size>::Relr_section*
1446+Target_x86_64<size>::relr_dyn_section(Layout* layout)
1447+{
1448+ if (this->relr_dyn_ == NULL)
1449+ {
1450+ gold_assert(layout != NULL);
1451+ this->relr_dyn_ = new Relr_section();
1452+ layout->add_output_section_data(".relr.dyn", elfcpp::SHT_RELR,
1453+ elfcpp::SHF_ALLOC, this->relr_dyn_,
1454+ ORDER_DYNAMIC_RELOCS, false);
1455+ }
1456+ return this->relr_dyn_;
1457+}
1458+
14341459 // Write the first three reserved words of the .got.plt section.
14351460 // The remainder of the section is written while writing the PLT
14361461 // in Output_data_plt_i386::do_write.
@@ -2966,14 +2991,25 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
29662991 if (parameters->options().output_is_position_independent())
29672992 {
29682993 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
2969- Reloc_section* rela_dyn = target->rela_dyn_section(layout);
2970- rela_dyn->add_local_relative(object, r_sym,
2971- (size == 32
2972- ? elfcpp::R_X86_64_RELATIVE64
2973- : elfcpp::R_X86_64_RELATIVE),
2974- output_section, data_shndx,
2975- reloc.get_r_offset(),
2976- reloc.get_r_addend(), is_ifunc);
2994+ if (size == 64
2995+ && !is_ifunc
2996+ && parameters->options().experimental_use_relr())
2997+ {
2998+ Relr_section* relr_dyn = target->relr_dyn_section(layout);
2999+ relr_dyn->add_local_relative(object, r_sym, output_section,
3000+ data_shndx, reloc.get_r_offset());
3001+ }
3002+ else
3003+ {
3004+ Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3005+ rela_dyn->add_local_relative(object, r_sym,
3006+ (size == 32
3007+ ? elfcpp::R_X86_64_RELATIVE64
3008+ : elfcpp::R_X86_64_RELATIVE),
3009+ output_section, data_shndx,
3010+ reloc.get_r_offset(),
3011+ reloc.get_r_addend(), is_ifunc);
3012+ }
29773013 }
29783014 break;
29793015
@@ -2991,12 +3027,22 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
29913027 if (size == 32 && r_type == elfcpp::R_X86_64_32)
29923028 {
29933029 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
2994- Reloc_section* rela_dyn = target->rela_dyn_section(layout);
2995- rela_dyn->add_local_relative(object, r_sym,
2996- elfcpp::R_X86_64_RELATIVE,
2997- output_section, data_shndx,
2998- reloc.get_r_offset(),
2999- reloc.get_r_addend(), is_ifunc);
3030+ if (!is_ifunc && parameters->options().experimental_use_relr())
3031+ {
3032+ Relr_section* relr_dyn = target->relr_dyn_section(layout);
3033+ relr_dyn->add_local_relative(object, r_sym, output_section,
3034+ data_shndx,
3035+ reloc.get_r_offset());
3036+ }
3037+ else
3038+ {
3039+ Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3040+ rela_dyn->add_local_relative(object, r_sym,
3041+ elfcpp::R_X86_64_RELATIVE,
3042+ output_section, data_shndx,
3043+ reloc.get_r_offset(),
3044+ reloc.get_r_addend(), is_ifunc);
3045+ }
30003046 break;
30013047 }
30023048
@@ -3099,15 +3145,7 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
30993145 {
31003146 Reloc_section* rela_dyn = target->rela_dyn_section(layout);
31013147 // R_X86_64_RELATIVE assumes a 64-bit relocation.
3102- if (r_type != elfcpp::R_X86_64_GOT32)
3103- {
3104- unsigned int got_offset =
3105- object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
3106- rela_dyn->add_local_relative(object, r_sym,
3107- elfcpp::R_X86_64_RELATIVE,
3108- got, got_offset, 0, is_ifunc);
3109- }
3110- else
3148+ if (r_type == elfcpp::R_X86_64_GOT32)
31113149 {
31123150 this->check_non_pic(object, r_type, NULL);
31133151
@@ -3116,6 +3154,24 @@ Target_x86_64<size>::Scan::local(Symbol_table* symtab,
31163154 object, r_sym, r_type, got,
31173155 object->local_got_offset(r_sym, GOT_TYPE_STANDARD), 0);
31183156 }
3157+ else if (size == 64
3158+ && !is_ifunc
3159+ && parameters->options().experimental_use_relr())
3160+ {
3161+ Relr_section* relr_dyn = target->relr_dyn_section(layout);
3162+ unsigned int got_offset =
3163+ object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
3164+ relr_dyn->add_local_relative(object, r_sym, got,
3165+ got_offset);
3166+ }
3167+ else
3168+ {
3169+ unsigned int got_offset =
3170+ object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
3171+ rela_dyn->add_local_relative(object, r_sym,
3172+ elfcpp::R_X86_64_RELATIVE,
3173+ got, got_offset, 0, is_ifunc);
3174+ }
31193175 }
31203176 }
31213177 // For GOTPLT64, we'd normally want a PLT section, but since
@@ -3478,12 +3534,24 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
34783534 || (size == 32 && r_type == elfcpp::R_X86_64_32))
34793535 && gsym->can_use_relative_reloc(false))
34803536 {
3481- Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3482- rela_dyn->add_global_relative(gsym, elfcpp::R_X86_64_RELATIVE,
3483- output_section, object,
3484- data_shndx,
3485- reloc.get_r_offset(),
3486- reloc.get_r_addend(), false);
3537+ if (parameters->options().experimental_use_relr())
3538+ {
3539+ Relr_section* relr_dyn = target->relr_dyn_section(layout);
3540+ relr_dyn->add_global_relative(gsym,
3541+ output_section, object,
3542+ data_shndx,
3543+ reloc.get_r_offset());
3544+ }
3545+ else
3546+ {
3547+ Reloc_section* rela_dyn = target->rela_dyn_section(layout);
3548+ rela_dyn->add_global_relative(gsym,
3549+ elfcpp::R_X86_64_RELATIVE,
3550+ output_section, object,
3551+ data_shndx,
3552+ reloc.get_r_offset(),
3553+ reloc.get_r_addend(), false);
3554+ }
34873555 }
34883556 else
34893557 {
@@ -3886,7 +3954,8 @@ Target_x86_64<size>::do_finalize_sections(
38863954 ? NULL
38873955 : this->plt_->rela_plt());
38883956 layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
3889- this->rela_dyn_, true, false);
3957+ this->rela_dyn_, true, false,
3958+ this->relr_dyn_);
38903959
38913960 // Fill in some more dynamic tags.
38923961 Output_data_dynamic* const odyn = layout->dynamic_data();