[gold] Implement -z stack-size option

gold/
	* options.h (General_options): Grok -z stack-size.
	* output.h (Output_segment::set_size): New method.
	* layout.cc (Layout::create_executable_stack_info): Renamed to ...
	(Layout::create_stack_segment): ... this.  Always create the
	segment if -z stack-size was used.
	(Layout::set_segment_offsets): Don't call ->set_offset on the
	PT_GNU_STACK segment.
This commit is contained in:
Roland McGrath 2016-08-23 16:43:33 -07:00
parent 4ba25152ff
commit 1130c90ed7
5 changed files with 49 additions and 19 deletions

View file

@ -1,3 +1,13 @@
2016-08-23 Roland McGrath <roland@hack.frob.com>
* options.h (General_options): Grok -z stack-size.
* output.h (Output_segment::set_size): New method.
* layout.cc (Layout::create_executable_stack_info): Renamed to ...
(Layout::create_stack_segment): ... this. Always create the
segment if -z stack-size was used.
(Layout::set_segment_offsets): Don't call ->set_offset on the
PT_GNU_STACK segment.
2016-08-15 Bharathi Seshadri <bseshadr@cisco.com> 2016-08-15 Bharathi Seshadri <bseshadr@cisco.com>
* options.h (General_options): Add --be8 option. * options.h (General_options): Add --be8 option.

View file

@ -2135,7 +2135,7 @@ void
Layout::create_notes() Layout::create_notes()
{ {
this->create_gold_note(); this->create_gold_note();
this->create_executable_stack_info(); this->create_stack_segment();
this->create_build_id(); this->create_build_id();
} }
@ -2985,13 +2985,15 @@ Layout::create_gold_note()
// executable. Otherwise, if at least one input file a // executable. Otherwise, if at least one input file a
// .note.GNU-stack section, and some input file has no .note.GNU-stack // .note.GNU-stack section, and some input file has no .note.GNU-stack
// section, we use the target default for whether the stack should be // section, we use the target default for whether the stack should be
// executable. Otherwise, we don't generate a stack note. When // executable. If -z stack-size was used to set a p_memsz value for
// generating a object file, we create a .note.GNU-stack section with // PT_GNU_STACK, we generate the segment regardless. Otherwise, we
// the appropriate marking. When generating an executable or shared // don't generate a stack note. When generating a object file, we
// library, we create a PT_GNU_STACK segment. // create a .note.GNU-stack section with the appropriate marking.
// When generating an executable or shared library, we create a
// PT_GNU_STACK segment.
void void
Layout::create_executable_stack_info() Layout::create_stack_segment()
{ {
bool is_stack_executable; bool is_stack_executable;
if (parameters->options().is_execstack_set()) if (parameters->options().is_execstack_set())
@ -3003,7 +3005,9 @@ Layout::create_executable_stack_info()
gold_warning(_("one or more inputs require executable stack, " gold_warning(_("one or more inputs require executable stack, "
"but -z noexecstack was given")); "but -z noexecstack was given"));
} }
else if (!this->input_with_gnu_stack_note_) else if (!this->input_with_gnu_stack_note_
&& (!parameters->options().user_set_stack_size()
|| parameters->options().relocatable()))
return; return;
else else
{ {
@ -3032,7 +3036,12 @@ Layout::create_executable_stack_info()
int flags = elfcpp::PF_R | elfcpp::PF_W; int flags = elfcpp::PF_R | elfcpp::PF_W;
if (is_stack_executable) if (is_stack_executable)
flags |= elfcpp::PF_X; flags |= elfcpp::PF_X;
Output_segment* seg =
this->make_output_segment(elfcpp::PT_GNU_STACK, flags); this->make_output_segment(elfcpp::PT_GNU_STACK, flags);
seg->set_size(parameters->options().stack_size());
// BFD lets targets override this default alignment, but the only
// targets that do so are ones that Gold does not support so far.
seg->set_minimum_p_align(16);
} }
} }
@ -3718,7 +3727,9 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
p != this->segment_list_.end(); p != this->segment_list_.end();
++p) ++p)
{ {
if ((*p)->type() != elfcpp::PT_LOAD) // PT_GNU_STACK was set up correctly when it was created.
if ((*p)->type() != elfcpp::PT_LOAD
&& (*p)->type() != elfcpp::PT_GNU_STACK)
(*p)->set_offset((*p)->type() == elfcpp::PT_GNU_RELRO (*p)->set_offset((*p)->type() == elfcpp::PT_GNU_RELRO
? increase_relro ? increase_relro
: 0); : 0);

View file

@ -1037,9 +1037,9 @@ class Layout
void void
create_gold_note(); create_gold_note();
// Record whether the stack must be executable. // Record whether the stack must be executable, and a user-supplied size.
void void
create_executable_stack_info(); create_stack_segment();
// Create a build ID note if needed. // Create a build ID note if needed.
void void

View file

@ -1342,6 +1342,8 @@ class General_options
DEFINE_bool(relro, options::DASH_Z, '\0', DEFAULT_LD_Z_RELRO, DEFINE_bool(relro, options::DASH_Z, '\0', DEFAULT_LD_Z_RELRO,
N_("Where possible mark variables read-only after relocation"), N_("Where possible mark variables read-only after relocation"),
N_("Don't mark variables read-only after relocation")); N_("Don't mark variables read-only after relocation"));
DEFINE_uint64(stack_size, options::DASH_Z, '\0', 0,
N_("Set PT_GNU_STACK segment p_memsz to SIZE"), N_("SIZE"));
DEFINE_bool(text, options::DASH_Z, '\0', false, DEFINE_bool(text, options::DASH_Z, '\0', false,
N_("Do not permit relocations in read-only segments"), N_("Do not permit relocations in read-only segments"),
N_("Permit relocations in read-only segments (default)")); N_("Permit relocations in read-only segments (default)"));

View file

@ -4796,6 +4796,13 @@ class Output_segment
this->min_p_align_ = align; this->min_p_align_ = align;
} }
// Set the memory size of this segment.
void
set_size(uint64_t size)
{
this->memsz_ = size;
}
// Set the offset of this segment based on the section. This should // Set the offset of this segment based on the section. This should
// only be called for a non-PT_LOAD segment. // only be called for a non-PT_LOAD segment.
void void