This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: Define __rel_iplt symbols if needed
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 05 Jul 2011 22:13:30 -0700
- Subject: gold patch committed: Define __rel_iplt symbols if needed
PR 12392 points out that gold fails to define the __rel_iplt symbols
when linking statically if there are no STT_GNU_IFUNC symbols. This
fails when using a libc which supports STT_GNU_IFUNC symbols but does
not actually use any. This patch fixes the problem. Committed to
mainline.
Ian
2011-07-05 Ian Lance Taylor <iant@google.com>
PR gold/12392
* i386.cc (Target_i386::do_finalize_sections): Define __rel_iplt
symbols if necessary.
* x86_64.cc (Target_x86_64::do_finalize_sections): Likewise.
Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.134
diff -u -p -r1.134 i386.cc
--- i386.cc 2 Jul 2011 00:03:25 -0000 1.134
+++ i386.cc 6 Jul 2011 05:10:39 -0000
@@ -2181,6 +2181,46 @@ Target_i386::do_finalize_sections(
uint32_t data_size = this->got_plt_->current_data_size();
symtab->get_sized_symbol<32>(sym)->set_symsize(data_size);
}
+
+ if (parameters->doing_static_link() && this->plt_ == NULL)
+ {
+ // If linking statically, make sure that the __rel_iplt symbols
+ // were defined if necessary, even if we didn't create a PLT.
+ static const Define_symbol_in_segment syms[] =
+ {
+ {
+ "__rel_iplt_start", // name
+ elfcpp::PT_LOAD, // segment_type
+ elfcpp::PF_W, // segment_flags_set
+ elfcpp::PF(0), // segment_flags_clear
+ 0, // value
+ 0, // size
+ elfcpp::STT_NOTYPE, // type
+ elfcpp::STB_GLOBAL, // binding
+ elfcpp::STV_HIDDEN, // visibility
+ 0, // nonvis
+ Symbol::SEGMENT_START, // offset_from_base
+ true // only_if_ref
+ },
+ {
+ "__rel_iplt_end", // name
+ elfcpp::PT_LOAD, // segment_type
+ elfcpp::PF_W, // segment_flags_set
+ elfcpp::PF(0), // segment_flags_clear
+ 0, // value
+ 0, // size
+ elfcpp::STT_NOTYPE, // type
+ elfcpp::STB_GLOBAL, // binding
+ elfcpp::STV_HIDDEN, // visibility
+ 0, // nonvis
+ Symbol::SEGMENT_START, // offset_from_base
+ true // only_if_ref
+ }
+ };
+
+ symtab->define_symbols(layout, 2, syms,
+ layout->script_options()->saw_sections_clause());
+ }
}
// Return whether a direct absolute static relocation needs to be applied.
Index: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.132
diff -u -p -r1.132 x86_64.cc
--- x86_64.cc 2 Jul 2011 00:03:25 -0000 1.132
+++ x86_64.cc 6 Jul 2011 05:10:40 -0000
@@ -2599,6 +2599,46 @@ Target_x86_64::do_finalize_sections(
uint64_t data_size = this->got_plt_->current_data_size();
symtab->get_sized_symbol<64>(sym)->set_symsize(data_size);
}
+
+ if (parameters->doing_static_link() && this->plt_ == NULL)
+ {
+ // If linking statically, make sure that the __rela_iplt symbols
+ // were defined if necessary, even if we didn't create a PLT.
+ static const Define_symbol_in_segment syms[] =
+ {
+ {
+ "__rela_iplt_start", // name
+ elfcpp::PT_LOAD, // segment_type
+ elfcpp::PF_W, // segment_flags_set
+ elfcpp::PF(0), // segment_flags_clear
+ 0, // value
+ 0, // size
+ elfcpp::STT_NOTYPE, // type
+ elfcpp::STB_GLOBAL, // binding
+ elfcpp::STV_HIDDEN, // visibility
+ 0, // nonvis
+ Symbol::SEGMENT_START, // offset_from_base
+ true // only_if_ref
+ },
+ {
+ "__rela_iplt_end", // name
+ elfcpp::PT_LOAD, // segment_type
+ elfcpp::PF_W, // segment_flags_set
+ elfcpp::PF(0), // segment_flags_clear
+ 0, // value
+ 0, // size
+ elfcpp::STT_NOTYPE, // type
+ elfcpp::STB_GLOBAL, // binding
+ elfcpp::STV_HIDDEN, // visibility
+ 0, // nonvis
+ Symbol::SEGMENT_START, // offset_from_base
+ true // only_if_ref
+ }
+ };
+
+ symtab->define_symbols(layout, 2, syms,
+ layout->script_options()->saw_sections_clause());
+ }
}
// Perform a relocation.