• 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

修訂0757c0695b9a8c42e0405418081dce0175bee136 (tree)
時間2016-07-04 18:04:48
作者Marcin Kościelnicki <koriakin@0x04...>
CommiterMarcin Kościelnicki

Log Message

gold/s390: Support partial got relro.

Change Summary

差異

--- a/gold/s390.cc
+++ b/gold/s390.cc
@@ -78,6 +78,38 @@ class Output_data_got_plt_s390 : public Output_section_data_build
7878 Layout* layout_;
7979 };
8080
81+// A class to handle the first entry of .got when partial relro is in use.
82+
83+template<int size>
84+class Output_data_got_dynamic_s390 : public Output_section_data_build
85+{
86+ public:
87+ Output_data_got_dynamic_s390(Layout* layout)
88+ : Output_section_data_build(size/8),
89+ layout_(layout)
90+ { }
91+
92+ Output_data_got_dynamic_s390(Layout* layout, off_t data_size)
93+ : Output_section_data_build(data_size, size/8),
94+ layout_(layout)
95+ { }
96+
97+ protected:
98+ // Write out the PLT data.
99+ void
100+ do_write(Output_file*);
101+
102+ // Write to a map file.
103+ void
104+ do_print_to_mapfile(Mapfile* mapfile) const
105+ { mapfile->print_output_data(this, "** GOT DYNAMIC"); }
106+
107+ private:
108+ // A pointer to the Layout class, so that we can find the .dynamic
109+ // section when we write out the GOT section.
110+ Layout* layout_;
111+};
112+
81113 // A class to handle the PLT data.
82114
83115 template<int size>
@@ -90,10 +122,11 @@ class Output_data_plt_s390 : public Output_section_data
90122 Output_data_plt_s390(Layout* layout,
91123 Output_data_got<size, true>* got,
92124 Output_data_got_plt_s390<size>* got_plt,
93- Output_data_space* got_irelative)
125+ Output_data_space* got_irelative,
126+ Output_section_data_build* got_dynamic)
94127 : Output_section_data(4), layout_(layout),
95128 irelative_rel_(NULL), got_(got), got_plt_(got_plt),
96- got_irelative_(got_irelative), count_(0),
129+ got_irelative_(got_irelative), got_dynamic_(got_dynamic), count_(0),
97130 irelative_count_(0), free_list_()
98131 { this->init(layout); }
99132
@@ -101,11 +134,13 @@ class Output_data_plt_s390 : public Output_section_data
101134 Output_data_got<size, true>* got,
102135 Output_data_got_plt_s390<size>* got_plt,
103136 Output_data_space* got_irelative,
137+ Output_section_data_build* got_dynamic,
104138 unsigned int plt_count)
105139 : Output_section_data((plt_count + 1) * plt_entry_size,
106140 4, false),
107141 layout_(layout), irelative_rel_(NULL), got_(got),
108- got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count),
142+ got_plt_(got_plt), got_irelative_(got_irelative),
143+ got_dynamic_(got_dynamic), count_(plt_count),
109144 irelative_count_(0), free_list_()
110145 {
111146 this->init(layout);
@@ -195,7 +230,8 @@ class Output_data_plt_s390 : public Output_section_data
195230 void
196231 fill_first_plt_entry(unsigned char* pov,
197232 typename elfcpp::Elf_types<size>::Elf_Addr got_address,
198- typename elfcpp::Elf_types<size>::Elf_Addr plt_address);
233+ typename elfcpp::Elf_types<size>::Elf_Addr plt_address,
234+ unsigned int got_plt_offset);
199235
200236 // Fill in a normal PLT entry. Returns the offset into the entry that
201237 // should be the initial GOT slot value.
@@ -238,6 +274,8 @@ class Output_data_plt_s390 : public Output_section_data
238274 Output_data_got_plt_s390<size>* got_plt_;
239275 // The part of the .got.plt section used for IRELATIVE relocs.
240276 Output_data_space* got_irelative_;
277+ // The header of .got section.
278+ Output_section_data_build* got_dynamic_;
241279 // The number of PLT entries.
242280 unsigned int count_;
243281 // Number of PLT entries with R_TILEGX_IRELATIVE relocs. These
@@ -251,6 +289,7 @@ class Output_data_plt_s390 : public Output_section_data
251289 static const int plt_entry_size = 0x20;
252290 // The first entry in the PLT.
253291 static const unsigned char first_plt_entry_32_abs[plt_entry_size];
292+ static const unsigned char first_plt_entry_32_pic12[plt_entry_size];
254293 static const unsigned char first_plt_entry_32_pic[plt_entry_size];
255294 static const unsigned char first_plt_entry_64[plt_entry_size];
256295 // Other entries in the PLT for an executable.
@@ -646,7 +685,7 @@ class Target_s390 : public Sized_target<size, true>
646685 got_address() const
647686 {
648687 gold_assert(this->got_ != NULL);
649- return this->got_plt_->address();
688+ return this->got_dynamic_->address();
650689 }
651690
652691 typename elfcpp::Elf_types<size>::Elf_Addr
@@ -741,6 +780,10 @@ class Target_s390 : public Sized_target<size, true>
741780 Output_data_got_plt_s390<size>* got_plt_;
742781 // The GOT section for IRELATIVE relocations.
743782 Output_data_space* got_irelative_;
783+ // The section containing the first GOT entry (_DYNAMIC) - this is
784+ // Output_data_got_dynamic_s390 if partial relro is in use, same
785+ // as got_plt_ otherwise.
786+ Output_section_data_build* got_dynamic_;
744787 // The _GLOBAL_OFFSET_TABLE_ symbol.
745788 Symbol* global_offset_table_;
746789 // The dynamic reloc section.
@@ -1247,18 +1290,18 @@ Output_data_plt_s390<size>::first_plt_entry_32_abs[plt_entry_size] =
12471290 0x58, 0x10, 0x10, 0x08, // l %r1, 8(%r1)
12481291 0x07, 0xf1, // br %r1
12491292 0x00, 0x00, // padding
1250- 0x00, 0x00, 0x00, 0x00, // _GLOBAL_OFFSET_TABLE_ (to fill)
1293+ 0x00, 0x00, 0x00, 0x00, // DT_GOTPLT (to fill)
12511294 0x00, 0x00, 0x00, 0x00, // padding
12521295 };
12531296
12541297 template<int size>
12551298 const unsigned char
1256-Output_data_plt_s390<size>::first_plt_entry_32_pic[plt_entry_size] =
1299+Output_data_plt_s390<size>::first_plt_entry_32_pic12[plt_entry_size] =
12571300 {
12581301 0x50, 0x10, 0xf0, 0x1c, // st %r1, 28(%r15)
1259- 0x58, 0x10, 0xc0, 0x04, // l %r1, 4(%r12)
1302+ 0x58, 0x10, 0xc0, 0x00, // l %r1, DT_GOTPLT@got+4(%r12) (to fill)
12601303 0x50, 0x10, 0xf0, 0x18, // st %r1, 24(%r15)
1261- 0x58, 0x10, 0xc0, 0x08, // l %r1, 8(%r12)
1304+ 0x58, 0x10, 0xc0, 0x00, // l %r1, DT_GOTPLT@got+8(%r12) (to fill)
12621305 0x07, 0xf1, // br %r1
12631306 0x00, 0x00, // padding
12641307 0x00, 0x00, 0x00, 0x00, // padding
@@ -1268,10 +1311,25 @@ Output_data_plt_s390<size>::first_plt_entry_32_pic[plt_entry_size] =
12681311
12691312 template<int size>
12701313 const unsigned char
1314+Output_data_plt_s390<size>::first_plt_entry_32_pic[plt_entry_size] =
1315+{
1316+ 0x50, 0x10, 0xf0, 0x1c, // st %r1, 28(%r15)
1317+ 0x0d, 0x10, // basr %r1, %r0
1318+ 0x5a, 0x10, 0x10, 0x12, // a %r1, 18(%r1)
1319+ 0xd2, 0x03, 0xf0, 0x18, 0x10, 0x04, // mvc 24(4,%r15), 4(%r1)
1320+ 0x58, 0x10, 0x10, 0x08, // l %r1, 8(%r1)
1321+ 0x07, 0xf1, // br %r1
1322+ 0x00, 0x00, // padding
1323+ 0x00, 0x00, 0x00, 0x00, // DT_GOTPLT - . + 18 (to fill)
1324+ 0x00, 0x00, 0x00, 0x00, // padding
1325+};
1326+
1327+template<int size>
1328+const unsigned char
12711329 Output_data_plt_s390<size>::first_plt_entry_64[plt_entry_size] =
12721330 {
12731331 0xe3, 0x10, 0xf0, 0x38, 0x00, 0x24, // stg %r1, 56(%r15)
1274- 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, // larl %r1, _GLOBAL_OFFSET_TABLE_ (to fill)
1332+ 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, // larl %r1, DT_GOTPLT (to fill)
12751333 0xd2, 0x07, 0xf0, 0x30, 0x10, 0x08, // mvc 48(8,%r15), 8(%r1)
12761334 0xe3, 0x10, 0x10, 0x10, 0x00, 0x04, // lg %r1, 16(%r1)
12771335 0x07, 0xf1, // br %r1
@@ -1284,22 +1342,33 @@ template<int size>
12841342 void
12851343 Output_data_plt_s390<size>::fill_first_plt_entry(
12861344 unsigned char* pov,
1287- typename elfcpp::Elf_types<size>::Elf_Addr got_address,
1288- typename elfcpp::Elf_types<size>::Elf_Addr plt_address)
1345+ typename elfcpp::Elf_types<size>::Elf_Addr got_plt_address,
1346+ typename elfcpp::Elf_types<size>::Elf_Addr plt_address,
1347+ unsigned int got_plt_offset)
12891348 {
12901349 if (size == 64)
12911350 {
12921351 memcpy(pov, first_plt_entry_64, plt_entry_size);
1293- S390_relocate_functions<size>::pcrela32dbl(pov + 8, got_address, (plt_address + 6));
1352+ S390_relocate_functions<size>::pcrela32dbl(pov + 8, got_plt_address, (plt_address + 6));
12941353 }
12951354 else if (!parameters->options().output_is_position_independent())
12961355 {
12971356 memcpy(pov, first_plt_entry_32_abs, plt_entry_size);
1298- elfcpp::Swap<32, true>::writeval(pov + 24, got_address);
1357+ elfcpp::Swap<32, true>::writeval(pov + 24, got_plt_address);
12991358 }
13001359 else
13011360 {
1302- memcpy(pov, first_plt_entry_32_pic, plt_entry_size);
1361+ if (got_plt_offset < 0xff8)
1362+ {
1363+ memcpy(pov, first_plt_entry_32_pic12, plt_entry_size);
1364+ S390_relocate_functions<size>::rela12(pov + 6, got_plt_offset + 4);
1365+ S390_relocate_functions<size>::rela12(pov + 14, got_plt_offset + 8);
1366+ }
1367+ else
1368+ {
1369+ memcpy(pov, first_plt_entry_32_pic, plt_entry_size);
1370+ elfcpp::Swap<32, true>::writeval(pov + 24, got_plt_address - (plt_address + 6));
1371+ }
13031372 }
13041373 }
13051374
@@ -1536,9 +1605,12 @@ Output_data_plt_s390<size>::do_write(Output_file* of)
15361605 // which is where the GOT pointer will point, and where the
15371606 // three reserved GOT entries are located.
15381607 typename elfcpp::Elf_types<size>::Elf_Addr got_address
1539- = this->got_plt_->address();
1608+ = this->got_dynamic_->address();
15401609
1541- this->fill_first_plt_entry(pov, got_address, plt_address);
1610+ unsigned int got_plt_offset = this->got_plt_->address() - got_address;
1611+
1612+ this->fill_first_plt_entry(pov, this->got_plt_->address(), plt_address,
1613+ got_plt_offset);
15421614 pov += this->get_plt_entry_size();
15431615
15441616 unsigned char* got_pov = got_view;
@@ -1547,7 +1619,7 @@ Output_data_plt_s390<size>::do_write(Output_file* of)
15471619
15481620 unsigned int plt_offset = this->get_plt_entry_size();
15491621 unsigned int plt_rel_offset = 0;
1550- unsigned int got_offset = 3 * size / 8;
1622+ unsigned int got_offset = 3 * size / 8 + got_plt_offset;
15511623 const unsigned int count = this->count_ + this->irelative_count_;
15521624 // The first three entries in the GOT are reserved, and are written
15531625 // by Output_data_got_plt_s390::do_write.
@@ -1590,22 +1662,43 @@ Target_s390<size>::got_section(Symbol_table* symtab, Layout* layout)
15901662 {
15911663 gold_assert(symtab != NULL && layout != NULL);
15921664
1593- // When using -z now, we can treat .got as a relro section.
1594- // Without -z now, it is modified after program startup by lazy
1595- // PLT relocations.
1596- bool is_got_relro = parameters->options().now();
1597- Output_section_order got_order = (is_got_relro
1598- ? ORDER_RELRO_LAST
1599- : ORDER_DATA);
1665+ bool is_got_relro, is_got_plt_relro;
1666+ Output_section_order got_order, got_plt_order;
1667+ const char *got_plt_name;
1668+ if (parameters->options().relro())
1669+ {
1670+ // Partial GOT relro.
1671+ is_got_relro = true;
1672+ is_got_plt_relro = false;
1673+ got_order = ORDER_RELRO_LAST;
1674+ got_plt_order = ORDER_NON_RELRO_FIRST;
1675+ got_plt_name = ".got.plt";
1676+ }
1677+ else if (parameters->options().now())
1678+ {
1679+ // When using -z now, we can treat the whole .got as a relro section.
1680+ is_got_plt_relro = is_got_relro = true;
1681+ got_order = got_plt_order = ORDER_RELRO_LAST;
1682+ got_plt_name = ".got";
1683+ }
1684+ else
1685+ {
1686+ // Without -z now, it is modified after program startup by lazy
1687+ // PLT relocations.
1688+ is_got_plt_relro = is_got_relro = false;
1689+ got_order = got_plt_order = ORDER_DATA;
1690+ got_plt_name = ".got";
1691+ }
16001692
16011693 // The old GNU linker creates a .got.plt section. We just
16021694 // create another set of data in the .got section. Note that we
16031695 // always create a PLT if we create a GOT, although the PLT
16041696 // might be empty.
16051697 this->got_plt_ = new Output_data_got_plt_s390<size>(layout);
1606- layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1698+ layout->add_output_section_data(got_plt_name, elfcpp::SHT_PROGBITS,
16071699 (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
1608- this->got_plt_, got_order, is_got_relro);
1700+ this->got_plt_, got_plt_order,
1701+ is_got_plt_relro);
16091702
16101703 // The first three entries are reserved.
16111704 this->got_plt_->set_current_data_size(3 * size / 8);
@@ -1613,10 +1706,23 @@ Target_s390<size>::got_section(Symbol_table* symtab, Layout* layout)
16131706 // If there are any IRELATIVE relocations, they get GOT entries
16141707 // in .got.plt after the jump slot entries.
16151708 this->got_irelative_ = new Output_data_space(size / 8, "** GOT IRELATIVE PLT");
1616- layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1709+ layout->add_output_section_data(got_plt_name, elfcpp::SHT_PROGBITS,
16171710 (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
16181711 this->got_irelative_,
1619- got_order, is_got_relro);
1712+ got_plt_order, is_got_plt_relro);
1713+
1714+ if (parameters->options().relro())
1715+ {
1716+ // For partial relro, we need a _DYNAMIC pointer at
1717+ // _GLOBAL_OFFSET_TABLE_, not at DT_GOTPLT.
1718+ this->got_dynamic_ = new Output_data_got_dynamic_s390<size>(layout);
1719+ layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1720+ (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
1721+ this->got_dynamic_, got_order, true);
1722+ this->got_dynamic_->set_current_data_size(size / 8);
1723+ }
1724+ else
1725+ this->got_dynamic_ = this->got_plt_;
16201726
16211727 // Unlike some targets (.e.g x86), S/390 does not use separate .got and
16221728 // .got.plt sections in output. The output .got section contains both
@@ -1629,9 +1735,9 @@ Target_s390<size>::got_section(Symbol_table* symtab, Layout* layout)
16291735
16301736 // Define _GLOBAL_OFFSET_TABLE_ at the start of the GOT.
16311737 this->global_offset_table_ =
1632- symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
1738+ symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
16331739 Symbol_table::PREDEFINED,
1634- this->got_plt_,
1740+ this->got_dynamic_,
16351741 0, 0, elfcpp::STT_OBJECT,
16361742 elfcpp::STB_LOCAL,
16371743 elfcpp::STV_HIDDEN, 0,
@@ -1693,7 +1799,7 @@ Output_data_got_plt_s390<size>::do_write(Output_file* of)
16931799 // The first entry in the GOT is the address of the .dynamic section
16941800 // aka the PT_DYNAMIC segment. The next two entries are reserved.
16951801 // We saved space for them when we created the section in
1696- // Target_x86_64::got_section.
1802+ // Target_s390::got_section.
16971803 const off_t got_file_offset = this->offset();
16981804 gold_assert(this->data_size() >= 3 * size / 8);
16991805 unsigned char* const got_view =
@@ -1705,6 +1811,26 @@ Output_data_got_plt_s390<size>::do_write(Output_file* of)
17051811 of->write_output_view(got_file_offset, 3 * size / 8, got_view);
17061812 }
17071813
1814+// Write the first reserved word of the .got section.
1815+
1816+template<int size>
1817+void
1818+Output_data_got_dynamic_s390<size>::do_write(Output_file* of)
1819+{
1820+ // The first entry in the GOT is the address of the .dynamic section
1821+ // aka the PT_DYNAMIC segment. The next two entries are reserved.
1822+ // We saved space for them when we created the section in
1823+ // Target_s390::got_section.
1824+ const off_t got_file_offset = this->offset();
1825+ gold_assert(this->data_size() == size / 8);
1826+ unsigned char* const got_view =
1827+ of->get_output_view(got_file_offset, size / 8);
1828+ Output_section* dynamic = this->layout_->dynamic_section();
1829+ uint64_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
1830+ elfcpp::Swap<size, true>::writeval(got_view, dynamic_addr);
1831+ of->write_output_view(got_file_offset, size / 8, got_view);
1832+}
1833+
17081834 // Create the PLT section.
17091835
17101836 template<int size>
@@ -1722,7 +1848,8 @@ Target_s390<size>::make_plt_section(Symbol_table* symtab, Layout* layout)
17221848 this->rela_dyn_section(layout);
17231849
17241850 this->plt_ = new Output_data_plt_s390<size>(layout,
1725- this->got_, this->got_plt_, this->got_irelative_);
1851+ this->got_, this->got_plt_, this->got_irelative_,
1852+ this->got_dynamic_);
17261853
17271854 // Add unwind information if requested.
17281855 if (parameters->options().ld_generated_unwind_info())
@@ -1814,34 +1941,72 @@ Target_s390<size>::init_got_plt_for_update(Symbol_table* symtab,
18141941 {
18151942 gold_assert(this->got_ == NULL);
18161943
1944+ bool is_got_relro, is_got_plt_relro;
1945+ Output_section_order got_order, got_plt_order;
1946+ const char *got_plt_name;
1947+ if (parameters->options().relro())
1948+ {
1949+ // Partial GOT relro.
1950+ is_got_relro = true;
1951+ is_got_plt_relro = false;
1952+ got_order = ORDER_RELRO_LAST;
1953+ got_plt_order = ORDER_NON_RELRO_FIRST;
1954+ got_plt_name = ".got.plt";
1955+ }
1956+ else if (parameters->options().now())
1957+ {
1958+ // When using -z now, we can treat the whole .got as a relro section.
1959+ is_got_plt_relro = is_got_relro = true;
1960+ got_order = got_plt_order = ORDER_RELRO_LAST;
1961+ got_plt_name = ".got";
1962+ }
1963+ else
1964+ {
1965+ // Without -z now, it is modified after program startup by lazy
1966+ // PLT relocations.
1967+ is_got_plt_relro = is_got_relro = false;
1968+ got_order = got_plt_order = ORDER_DATA;
1969+ got_plt_name = ".got";
1970+ }
1971+
18171972 // Add the three reserved entries.
18181973 this->got_plt_ = new Output_data_got_plt_s390<size>(layout, (plt_count + 3) * size / 8);
1819- layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1820- (elfcpp::SHF_ALLOC
1821- | elfcpp::SHF_WRITE),
1822- this->got_plt_, ORDER_NON_RELRO_FIRST,
1823- false);
1974+ layout->add_output_section_data(got_plt_name, elfcpp::SHT_PROGBITS,
1975+ (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
1976+ this->got_plt_, got_plt_order,
1977+ is_got_plt_relro);
18241978
18251979 // If there are any IRELATIVE relocations, they get GOT entries in
18261980 // .got.plt after the jump slot entries.
18271981 this->got_irelative_ = new Output_data_space(0, size / 8, "** GOT IRELATIVE PLT");
1828- layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1982+ layout->add_output_section_data(got_plt_name, elfcpp::SHT_PROGBITS,
18291983 elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
18301984 this->got_irelative_,
1831- ORDER_NON_RELRO_FIRST, false);
1985+ got_plt_order, is_got_plt_relro);
1986+
1987+ if (parameters->options().relro())
1988+ {
1989+ // For partial relro, we need a _DYNAMIC pointer at
1990+ // _GLOBAL_OFFSET_TABLE_, not at DT_GOTPLT.
1991+ this->got_dynamic_ = new Output_data_got_dynamic_s390<size>(layout);
1992+ layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1993+ (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
1994+ this->got_dynamic_, got_order, true);
1995+ this->got_dynamic_->set_current_data_size(size / 8);
1996+ }
1997+ else
1998+ this->got_dynamic_ = this->got_plt_;
18321999
18332000 this->got_ = new Output_data_got<size, true>(got_count * size / 8);
18342001 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
1835- (elfcpp::SHF_ALLOC
1836- | elfcpp::SHF_WRITE),
1837- this->got_, ORDER_RELRO_LAST,
1838- true);
2002+ (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
2003+ this->got_, got_order, is_got_relro);
18392004
18402005 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
18412006 this->global_offset_table_ =
18422007 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
18432008 Symbol_table::PREDEFINED,
1844- this->got_plt_,
2009+ this->got_dynamic_,
18452010 0, 0, elfcpp::STT_OBJECT,
18462011 elfcpp::STB_LOCAL,
18472012 elfcpp::STV_HIDDEN, 0,
@@ -1849,7 +2014,8 @@ Target_s390<size>::init_got_plt_for_update(Symbol_table* symtab,
18492014
18502015 // Create the PLT section.
18512016 this->plt_ = new Output_data_plt_s390<size>(layout,
1852- this->got_, this->got_plt_, this->got_irelative_, plt_count);
2017+ this->got_, this->got_plt_, this->got_irelative_,
2018+ this->got_dynamic_, plt_count);
18532019
18542020 // Add unwind information if requested.
18552021 if (parameters->options().ld_generated_unwind_info())
@@ -4051,6 +4217,10 @@ Target_s390<size>::do_finalize_sections(
40514217 if (sym != NULL)
40524218 {
40534219 uint64_t data_size = this->got_->current_data_size();
4220+ data_size += this->got_plt_->current_data_size();
4221+ data_size += this->got_irelative_->current_data_size();
4222+ if (this->got_plt_ != this->got_dynamic_)
4223+ data_size += this->got_dynamic_->current_data_size();
40544224 symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
40554225 }
40564226