PR 10156
* layout.cc (Layout::choose_output_section): If we find an existing section, update the flags. (Layout::create_notes): New function, broken out of Layout::finalize. (Layout::finalize): Don't create note sections. (Layout::create_note): Don't crash if linker script discards section. (Layout::create_gold_note): Likewise. (Layout::create_build_id): Likewise. Don't set after_input_sections on the section. (Layout::create_executable_stack_info): Remove target parameter. Change caller. * layout.h (class Layout): Declare create_notes. Update declaration of create_executable_stack_info. * gold.cc (queue_middle_tasks): Call create_notes. * output.cc (Output_section::update_flags_for_input_section): Move here from output.h. If SHF_ALLOC flag is newly set, mark address invalid. * output.h (Output_data::mark_address_invalid): New function. (class Output_section): Only declare, not define, update_flags_for_input_section. Remove set_flags.
This commit is contained in:
parent
554585003d
commit
9c547ec3ac
@ -1,3 +1,28 @@
|
|||||||
|
2009-06-24 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
PR 10156
|
||||||
|
* layout.cc (Layout::choose_output_section): If we find an
|
||||||
|
existing section, update the flags.
|
||||||
|
(Layout::create_notes): New function, broken out of
|
||||||
|
Layout::finalize.
|
||||||
|
(Layout::finalize): Don't create note sections.
|
||||||
|
(Layout::create_note): Don't crash if linker script discards
|
||||||
|
section.
|
||||||
|
(Layout::create_gold_note): Likewise.
|
||||||
|
(Layout::create_build_id): Likewise. Don't set
|
||||||
|
after_input_sections on the section.
|
||||||
|
(Layout::create_executable_stack_info): Remove target parameter.
|
||||||
|
Change caller.
|
||||||
|
* layout.h (class Layout): Declare create_notes. Update
|
||||||
|
declaration of create_executable_stack_info.
|
||||||
|
* gold.cc (queue_middle_tasks): Call create_notes.
|
||||||
|
* output.cc (Output_section::update_flags_for_input_section): Move
|
||||||
|
here from output.h. If SHF_ALLOC flag is newly set, mark address
|
||||||
|
invalid.
|
||||||
|
* output.h (Output_data::mark_address_invalid): New function.
|
||||||
|
(class Output_section): Only declare, not define,
|
||||||
|
update_flags_for_input_section. Remove set_flags.
|
||||||
|
|
||||||
2009-06-24 Ian Lance Taylor <iant@google.com>
|
2009-06-24 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* script-sections.cc (Output_section_definition::
|
* script-sections.cc (Output_section_definition::
|
||||||
|
@ -386,6 +386,9 @@ queue_middle_tasks(const General_options& options,
|
|||||||
// TODO: if this is too slow, do this as a task, rather than inline.
|
// TODO: if this is too slow, do this as a task, rather than inline.
|
||||||
symtab->detect_odr_violations(task, options.output_file_name());
|
symtab->detect_odr_violations(task, options.output_file_name());
|
||||||
|
|
||||||
|
// Create any automatic note sections.
|
||||||
|
layout->create_notes();
|
||||||
|
|
||||||
// Create any output sections required by any linker script.
|
// Create any output sections required by any linker script.
|
||||||
layout->create_script_sections();
|
layout->create_script_sections();
|
||||||
|
|
||||||
|
@ -416,7 +416,10 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
|
|||||||
if (output_section_slot != NULL)
|
if (output_section_slot != NULL)
|
||||||
{
|
{
|
||||||
if (*output_section_slot != NULL)
|
if (*output_section_slot != NULL)
|
||||||
return *output_section_slot;
|
{
|
||||||
|
(*output_section_slot)->update_flags_for_input_section(flags);
|
||||||
|
return *output_section_slot;
|
||||||
|
}
|
||||||
|
|
||||||
// We don't put sections found in the linker script into
|
// We don't put sections found in the linker script into
|
||||||
// SECTION_NAME_MAP_. That keeps us from getting confused
|
// SECTION_NAME_MAP_. That keeps us from getting confused
|
||||||
@ -1028,6 +1031,16 @@ Layout::layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create automatic note sections.
|
||||||
|
|
||||||
|
void
|
||||||
|
Layout::create_notes()
|
||||||
|
{
|
||||||
|
this->create_gold_note();
|
||||||
|
this->create_executable_stack_info();
|
||||||
|
this->create_build_id();
|
||||||
|
}
|
||||||
|
|
||||||
// Create the dynamic sections which are needed before we read the
|
// Create the dynamic sections which are needed before we read the
|
||||||
// relocs.
|
// relocs.
|
||||||
|
|
||||||
@ -1198,9 +1211,6 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
|
|||||||
|
|
||||||
this->count_local_symbols(task, input_objects);
|
this->count_local_symbols(task, input_objects);
|
||||||
|
|
||||||
this->create_gold_note();
|
|
||||||
this->create_executable_stack_info(target);
|
|
||||||
this->create_build_id();
|
|
||||||
this->link_stabs_sections();
|
this->link_stabs_sections();
|
||||||
|
|
||||||
Output_segment* phdr_seg = NULL;
|
Output_segment* phdr_seg = NULL;
|
||||||
@ -1442,6 +1452,9 @@ Layout::create_note(const char* name, int note_type,
|
|||||||
Output_section* os = this->choose_output_section(NULL, section_name,
|
Output_section* os = this->choose_output_section(NULL, section_name,
|
||||||
elfcpp::SHT_NOTE,
|
elfcpp::SHT_NOTE,
|
||||||
flags, false);
|
flags, false);
|
||||||
|
if (os == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Output_section_data* posd = new Output_data_const_buffer(buffer, notehdrsz,
|
Output_section_data* posd = new Output_data_const_buffer(buffer, notehdrsz,
|
||||||
size / 8,
|
size / 8,
|
||||||
"** note header");
|
"** note header");
|
||||||
@ -1467,6 +1480,8 @@ Layout::create_gold_note()
|
|||||||
Output_section *os = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
|
Output_section *os = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
|
||||||
".note.gnu.gold-version", desc.size(),
|
".note.gnu.gold-version", desc.size(),
|
||||||
false, &trailing_padding);
|
false, &trailing_padding);
|
||||||
|
if (os == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
Output_section_data* posd = new Output_data_const(desc, 4);
|
Output_section_data* posd = new Output_data_const(desc, 4);
|
||||||
os->add_output_section_data(posd);
|
os->add_output_section_data(posd);
|
||||||
@ -1491,7 +1506,7 @@ Layout::create_gold_note()
|
|||||||
// library, we create a PT_GNU_STACK segment.
|
// library, we create a PT_GNU_STACK segment.
|
||||||
|
|
||||||
void
|
void
|
||||||
Layout::create_executable_stack_info(const Target* target)
|
Layout::create_executable_stack_info()
|
||||||
{
|
{
|
||||||
bool is_stack_executable;
|
bool is_stack_executable;
|
||||||
if (parameters->options().is_execstack_set())
|
if (parameters->options().is_execstack_set())
|
||||||
@ -1503,7 +1518,8 @@ Layout::create_executable_stack_info(const Target* target)
|
|||||||
if (this->input_requires_executable_stack_)
|
if (this->input_requires_executable_stack_)
|
||||||
is_stack_executable = true;
|
is_stack_executable = true;
|
||||||
else if (this->input_without_gnu_stack_note_)
|
else if (this->input_without_gnu_stack_note_)
|
||||||
is_stack_executable = target->is_default_stack_executable();
|
is_stack_executable =
|
||||||
|
parameters->target().is_default_stack_executable();
|
||||||
else
|
else
|
||||||
is_stack_executable = false;
|
is_stack_executable = false;
|
||||||
}
|
}
|
||||||
@ -1600,6 +1616,8 @@ Layout::create_build_id()
|
|||||||
Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_BUILD_ID,
|
Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_BUILD_ID,
|
||||||
".note.gnu.build-id", descsz, true,
|
".note.gnu.build-id", descsz, true,
|
||||||
&trailing_padding);
|
&trailing_padding);
|
||||||
|
if (os == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!desc.empty())
|
if (!desc.empty())
|
||||||
{
|
{
|
||||||
@ -1622,7 +1640,6 @@ Layout::create_build_id()
|
|||||||
gold_assert(trailing_padding == 0);
|
gold_assert(trailing_padding == 0);
|
||||||
this->build_id_note_ = new Output_data_zero_fill(descsz, 4);
|
this->build_id_note_ = new Output_data_zero_fill(descsz, 4);
|
||||||
os->add_output_section_data(this->build_id_note_);
|
os->add_output_section_data(this->build_id_note_);
|
||||||
os->set_after_input_sections();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +208,10 @@ class Layout
|
|||||||
void
|
void
|
||||||
define_section_symbols(Symbol_table*);
|
define_section_symbols(Symbol_table*);
|
||||||
|
|
||||||
|
// Create automatic note sections.
|
||||||
|
void
|
||||||
|
create_notes();
|
||||||
|
|
||||||
// Create sections for linker scripts.
|
// Create sections for linker scripts.
|
||||||
void
|
void
|
||||||
create_script_sections()
|
create_script_sections()
|
||||||
@ -474,7 +478,7 @@ class Layout
|
|||||||
|
|
||||||
// Record whether the stack must be executable.
|
// Record whether the stack must be executable.
|
||||||
void
|
void
|
||||||
create_executable_stack_info(const Target*);
|
create_executable_stack_info();
|
||||||
|
|
||||||
// Create a build ID note if needed.
|
// Create a build ID note if needed.
|
||||||
void
|
void
|
||||||
|
@ -1995,6 +1995,24 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the output section flags based on input section flags.
|
||||||
|
|
||||||
|
void
|
||||||
|
Output_section::update_flags_for_input_section(elfcpp::Elf_Xword flags)
|
||||||
|
{
|
||||||
|
// If we created the section with SHF_ALLOC clear, we set the
|
||||||
|
// address. If we are now setting the SHF_ALLOC flag, we need to
|
||||||
|
// undo that.
|
||||||
|
if ((this->flags_ & elfcpp::SHF_ALLOC) == 0
|
||||||
|
&& (flags & elfcpp::SHF_ALLOC) != 0)
|
||||||
|
this->mark_address_invalid();
|
||||||
|
|
||||||
|
this->flags_ |= (flags
|
||||||
|
& (elfcpp::SHF_WRITE
|
||||||
|
| elfcpp::SHF_ALLOC
|
||||||
|
| elfcpp::SHF_EXECINSTR));
|
||||||
|
}
|
||||||
|
|
||||||
// Given an address OFFSET relative to the start of input section
|
// Given an address OFFSET relative to the start of input section
|
||||||
// SHNDX in OBJECT, return whether this address is being included in
|
// SHNDX in OBJECT, return whether this address is being included in
|
||||||
// the final link. This should only be called if SHNDX in OBJECT has
|
// the final link. This should only be called if SHNDX in OBJECT has
|
||||||
|
@ -330,6 +330,13 @@ class Output_data
|
|||||||
|
|
||||||
// Functions that child classes may call.
|
// Functions that child classes may call.
|
||||||
|
|
||||||
|
// Reset the address. The Output_section class needs this when an
|
||||||
|
// SHF_ALLOC input section is added to an output section which was
|
||||||
|
// formerly not SHF_ALLOC.
|
||||||
|
void
|
||||||
|
mark_address_invalid()
|
||||||
|
{ this->is_address_valid_ = false; }
|
||||||
|
|
||||||
// Set the size of the data.
|
// Set the size of the data.
|
||||||
void
|
void
|
||||||
set_data_size(off_t data_size)
|
set_data_size(off_t data_size)
|
||||||
@ -1948,22 +1955,9 @@ class Output_section : public Output_data
|
|||||||
flags() const
|
flags() const
|
||||||
{ return this->flags_; }
|
{ return this->flags_; }
|
||||||
|
|
||||||
// Set the section flags. This may only be used with the Layout
|
|
||||||
// code when it is prepared to move the section to a different
|
|
||||||
// segment.
|
|
||||||
void
|
|
||||||
set_flags(elfcpp::Elf_Xword flags)
|
|
||||||
{ this->flags_ = flags; }
|
|
||||||
|
|
||||||
// Update the output section flags based on input section flags.
|
// Update the output section flags based on input section flags.
|
||||||
void
|
void
|
||||||
update_flags_for_input_section(elfcpp::Elf_Xword flags)
|
update_flags_for_input_section(elfcpp::Elf_Xword flags);
|
||||||
{
|
|
||||||
this->flags_ |= (flags
|
|
||||||
& (elfcpp::SHF_WRITE
|
|
||||||
| elfcpp::SHF_ALLOC
|
|
||||||
| elfcpp::SHF_EXECINSTR));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the entsize field.
|
// Return the entsize field.
|
||||||
uint64_t
|
uint64_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user