New gold linker option -z,text-unlikely-segment.

2017-10-04  Sriraman Tallam  <tmsriram@google.com>

	* options.h (-z,text_unlikely_segment): New option.
	* layout.cc (Layout::layout): Create new output section
	for .text.unlikely sections with the new option.
	(Layout::segment_precedes): Check for the new option
	when segment flags match.
	* testsuite/text_unlikely_segment.cc: New test source.
	* testsuite/text_unlikely_segment.sh: New test script.
	* testsuite/Makefile.am (text_unlikely_segment): New test.
	* testsuite/Makefile.in: Regenerate.
This commit is contained in:
Sriraman Tallam 2017-10-20 11:00:28 -07:00
parent f3012016f0
commit 3b4190ccb3
7 changed files with 178 additions and 25 deletions

View File

@ -1,3 +1,15 @@
2017-10-04 Sriraman Tallam <tmsriram@google.com>
* options.h (-z,text_unlikely_segment): New option.
* layout.cc (Layout::layout): Create new output section
for .text.unlikely sections with the new option.
(Layout::segment_precedes): Check for the new option
when segment flags match.
* testsuite/text_unlikely_segment.cc: New test source.
* testsuite/text_unlikely_segment.sh: New test script.
* testsuite/Makefile.am (text_unlikely_segment): New test.
* testsuite/Makefile.in: Regenerate.
2017-10-19 Umesh Kalappa <ukalappa@cisco.com>
* arm.cc (Stub::do_fixed_endian_write):Far call stubs support for arm

View File

@ -1178,38 +1178,62 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
}
else
{
// Plugins can choose to place one or more subsets of sections in
// unique segments and this is done by mapping these section subsets
// to unique output sections. Check if this section needs to be
// remapped to a unique output section.
Section_segment_map::iterator it
= this->section_segment_map_.find(Const_section_id(object, shndx));
if (it == this->section_segment_map_.end())
{
os = this->choose_output_section(object, name, sh_type,
shdr.get_sh_flags(), true,
ORDER_INVALID, false, false,
true);
}
else
{
// We know the name of the output section, directly call
// get_output_section here by-passing choose_output_section.
// All ".text.unlikely.*" sections can be moved to a unique
// segment with --text-unlikely-segment option.
bool text_unlikely_segment
= (parameters->options().text_unlikely_segment()
&& is_prefix_of(".text.unlikely",
object->section_name(shndx).c_str()));
if (text_unlikely_segment)
{
elfcpp::Elf_Xword flags
= this->get_output_section_flags(shdr.get_sh_flags());
const char* os_name = it->second->name;
Stringpool::Key name_key;
os_name = this->namepool_.add(os_name, true, &name_key);
const char* os_name = this->namepool_.add(".text.unlikely", true,
&name_key);
os = this->get_output_section(os_name, name_key, sh_type, flags,
ORDER_INVALID, false);
if (!os->is_unique_segment())
// Map this output section to a unique segment. This is done to
// separate "text" that is not likely to be executed from "text"
// that is likely executed.
os->set_is_unique_segment();
}
else
{
// Plugins can choose to place one or more subsets of sections in
// unique segments and this is done by mapping these section subsets
// to unique output sections. Check if this section needs to be
// remapped to a unique output section.
Section_segment_map::iterator it
= this->section_segment_map_.find(Const_section_id(object, shndx));
if (it == this->section_segment_map_.end())
{
os->set_is_unique_segment();
os->set_extra_segment_flags(it->second->flags);
os->set_segment_alignment(it->second->align);
os = this->choose_output_section(object, name, sh_type,
shdr.get_sh_flags(), true,
ORDER_INVALID, false, false,
true);
}
}
else
{
// We know the name of the output section, directly call
// get_output_section here by-passing choose_output_section.
elfcpp::Elf_Xword flags
= this->get_output_section_flags(shdr.get_sh_flags());
const char* os_name = it->second->name;
Stringpool::Key name_key;
os_name = this->namepool_.add(os_name, true, &name_key);
os = this->get_output_section(os_name, name_key, sh_type, flags,
ORDER_INVALID, false);
if (!os->is_unique_segment())
{
os->set_is_unique_segment();
os->set_extra_segment_flags(it->second->flags);
os->set_segment_alignment(it->second->align);
}
}
}
if (os == NULL)
return NULL;
}
@ -3449,7 +3473,8 @@ Layout::segment_precedes(const Output_segment* seg1,
// here if plugins want unique segments for subsets of sections.
gold_assert(this->script_options_->saw_phdrs_clause()
|| parameters->options().any_section_start()
|| this->is_unique_segment_for_sections_specified());
|| this->is_unique_segment_for_sections_specified()
|| parameters->options().text_unlikely_segment());
return false;
}

View File

@ -1492,6 +1492,11 @@ class General_options
DEFINE_bool_alias(textoff, text, options::DASH_Z, '\0',
N_("Permit relocations in read-only segments"),
NULL, true);
DEFINE_bool(text_unlikely_segment, options::DASH_Z, '\0', false,
N_("Move .text.unlikely sections to a separate segment."),
N_("Do not move .text.unlikely sections to a separate "
"segment."));
public:
typedef options::Dir_list Dir_list;

View File

@ -340,6 +340,16 @@ section_sorting_name: section_sorting_name.o gcctestdir/ld
section_sorting_name.stdout: section_sorting_name
$(TEST_NM) -n --synthetic section_sorting_name > section_sorting_name.stdout
check_SCRIPTS += text_unlikely_segment.sh
check_DATA += text_unlikely_segment_readelf.stdout
MOSTLYCLEANFILES += text_unlikely_segment
text_unlikely_segment.o: text_unlikely_segment.cc
$(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
text_unlikely_segment: text_unlikely_segment.o gcctestdir/ld
$(CXXLINK) -Bgcctestdir/ -Wl,-z,text-unlikely-segment text_unlikely_segment.o
text_unlikely_segment_readelf.stdout: text_unlikely_segment
$(TEST_READELF) -Wl $< >$@
check_PROGRAMS += icf_virtual_function_folding_test
MOSTLYCLEANFILES += icf_virtual_function_folding_test icf_virtual_function_folding_test.map
icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc

View File

@ -87,6 +87,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ section_sorting_name.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_unlikely_segment.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.sh \
@ -114,6 +115,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_no_grouping.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ section_sorting_name.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_unlikely_segment_readelf.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.stdout \
@ -139,6 +141,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_no_grouping \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ section_sorting_name \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_unlikely_segment \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test.map \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
@ -5148,6 +5151,8 @@ text_section_grouping.sh.log: text_section_grouping.sh
@p='text_section_grouping.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
section_sorting_name.sh.log: section_sorting_name.sh
@p='section_sorting_name.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
text_unlikely_segment.sh.log: text_unlikely_segment.sh
@p='text_unlikely_segment.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
icf_preemptible_functions_test.sh.log: icf_preemptible_functions_test.sh
@p='icf_preemptible_functions_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
icf_string_merge_test.sh.log: icf_string_merge_test.sh
@ -6015,6 +6020,12 @@ uninstall-am:
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--sort-section=name section_sorting_name.o
@GCC_TRUE@@NATIVE_LINKER_TRUE@section_sorting_name.stdout: section_sorting_name
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -n --synthetic section_sorting_name > section_sorting_name.stdout
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_unlikely_segment.o: text_unlikely_segment.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_unlikely_segment: text_unlikely_segment.o gcctestdir/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,-z,text-unlikely-segment text_unlikely_segment.o
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_unlikely_segment_readelf.stdout: text_unlikely_segment
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -Wl $< >$@
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fPIE -g -o $@ $<
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test: icf_virtual_function_folding_test.o gcctestdir/ld

View File

@ -0,0 +1,30 @@
/* text_unlikey_segment.cc -- a test case for gold
Copyright (C) 2017 onwards Free Software Foundation, Inc.
Written by Sriraman Tallam <tmsriram@google.com>
This file is part of gold.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
__attribute__((section(".text.unlikely")))
int foo(void) {
return 0;
}
int main(void) {
return 0;
}

View File

@ -0,0 +1,60 @@
#!/bin/sh
# plugin_final_layout.sh -- test
# Copyright (C) 2011-2017 Free Software Foundation, Inc.
# Written by Sriraman Tallam <tmsriram@google.com>.
# This file is part of gold.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
# The goal of this program is to verify if -z,text-unlikely-segment works as
# intended. File text_unlikely_segment.cc is part of this test.
set -e
# With readelf -l, an ELF Section to Segment mapping is printed as :
##############################################
# Section to Segment mapping:
# Segment Sections...
# ...
# 0x .text.unlikely
# ...
##############################################
# Check if .text.unlikely is the only section in the segment.
check_unique_segment()
{
awk "
BEGIN { saw_section = 0; saw_unique = 0; }
/$2/ { saw_section = 1; }
/[ ]*0[0-9][ ]*$2[ ]*\$/ { saw_unique = 1; }
END {
if (!saw_section)
{
printf \"Section $2 not seen in output\\n\";
exit 1;
}
else if (!saw_unique)
{
printf \"Unique segment not seen for: $2\\n\";
exit 1;
}
}" $1
}
check_unique_segment text_unlikely_segment_readelf.stdout ".text.unlikely"