From 412ffd830b94a860e81e8515140ba5ebc5aa82be Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Mon, 19 Dec 2016 16:37:48 -0800 Subject: [PATCH] Fix problem where linker does not place .note sections according to script. gold/ PR gold/14676 PR gold/20983 * layout.h (Layout::choose_output_section): Add match_input_spec parameter. Adjust all callers. * layout.cc (Layout::choose_output_section): Likewise. Pass match_input_spec to Script_sections::output_section_name(). (Layout::create_note): Pass true for match_input_spec. * script-sections.h (Script_sections::output_section_name): Add match_input_spec parameter. * script-sections.cc (Sections_element::output_section_name): Likewise. (Output_section_definition::output_section_name): Likewise. (Script_sections::output_section_name): Likewise. --- gold/ChangeLog | 15 ++++++++++++++ gold/layout.cc | 52 +++++++++++++++++++++++++++++-------------------- gold/layout.h | 2 +- gold/script-sections.cc | 17 +++++++++------- gold/script-sections.h | 5 ++++- 5 files changed, 61 insertions(+), 30 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index faccdfb..3c89094 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,18 @@ +2016-12-19 Cary Coutant + + PR gold/14676 + PR gold/20983 + * layout.h (Layout::choose_output_section): Add match_input_spec + parameter. Adjust all callers. + * layout.cc (Layout::choose_output_section): Likewise. Pass + match_input_spec to Script_sections::output_section_name(). + (Layout::create_note): Pass true for match_input_spec. + * script-sections.h (Script_sections::output_section_name): Add + match_input_spec parameter. + * script-sections.cc (Sections_element::output_section_name): Likewise. + (Output_section_definition::output_section_name): Likewise. + (Script_sections::output_section_name): Likewise. + 2016-12-19 Igor Kudrin * arm.cc (Target_arm::Target_arm): Move initialization code ... diff --git a/gold/layout.cc b/gold/layout.cc index 0852270..de0384b 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -903,7 +903,7 @@ Layout::keep_input_section(const Relobj* relobj, const char* name) bool keep; name = ss->output_section_name(file_name, name, &output_section_slot, - &script_section_type, &keep); + &script_section_type, &keep, true); return name != NULL && keep; } @@ -935,13 +935,16 @@ Layout::get_output_section_flags(elfcpp::Elf_Xword input_section_flags) // choosing an output section for an input section found in a input // file. ORDER is where this section should appear in the output // sections. IS_RELRO is true for a relro section. This will return -// NULL if the input section should be discarded. +// NULL if the input section should be discarded. MATCH_INPUT_SPEC +// is true if the section name should be matched against input specs +// in a linker script. Output_section* Layout::choose_output_section(const Relobj* relobj, const char* name, elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, bool is_input_section, Output_section_order order, - bool is_relro, bool is_reloc) + bool is_relro, bool is_reloc, + bool match_input_spec) { // We should not see any input sections after we have attached // sections to segments. @@ -961,7 +964,8 @@ Layout::choose_output_section(const Relobj* relobj, const char* name, const char* orig_name = name; bool keep; name = ss->output_section_name(file_name, name, &output_section_slot, - &script_section_type, &keep); + &script_section_type, &keep, + match_input_spec); if (name == NULL) { @@ -1184,7 +1188,8 @@ Layout::layout(Sized_relobj_file* object, unsigned int shndx, { os = this->choose_output_section(object, name, sh_type, shdr.get_sh_flags(), true, - ORDER_INVALID, false, false); + ORDER_INVALID, false, false, + true); } else { @@ -1313,7 +1318,7 @@ Layout::layout_reloc(Sized_relobj_file* object, || (data_section->flags() & elfcpp::SHF_GROUP) == 0) os = this->choose_output_section(object, name.c_str(), sh_type, shdr.get_sh_flags(), false, - ORDER_INVALID, false, true); + ORDER_INVALID, false, true, false); else { const char* n = this->namepool_.add(name.c_str(), true, NULL); @@ -1506,7 +1511,8 @@ Layout::make_eh_frame_section(const Relobj* object) Output_section* os = this->choose_output_section(object, ".eh_frame", elfcpp::SHT_PROGBITS, elfcpp::SHF_ALLOC, false, - ORDER_EHFRAME, false, false); + ORDER_EHFRAME, false, false, + false); if (os == NULL) return NULL; @@ -1523,7 +1529,8 @@ Layout::make_eh_frame_section(const Relobj* object) this->choose_output_section(NULL, ".eh_frame_hdr", elfcpp::SHT_PROGBITS, elfcpp::SHF_ALLOC, false, - ORDER_EHFRAME, false, false); + ORDER_EHFRAME, false, false, + false); if (hdr_os != NULL) { @@ -1592,7 +1599,7 @@ Layout::add_to_gdb_index(bool is_type_unit, Output_section* os = this->choose_output_section(NULL, ".gdb_index", elfcpp::SHT_PROGBITS, 0, false, ORDER_INVALID, - false, false); + false, false, false); if (os == NULL) return; @@ -1617,7 +1624,7 @@ Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type, { Output_section* os = this->choose_output_section(NULL, name, type, flags, false, order, is_relro, - false); + false, false); if (os != NULL) os->add_output_section_data(posd); return os; @@ -2158,7 +2165,7 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab) (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE), false, ORDER_RELRO, - true, false); + true, false, false); // A linker script may discard .dynamic, so check for NULL. if (this->dynamic_section_ != NULL) @@ -2941,7 +2948,7 @@ Layout::create_note(const char* name, int note_type, Output_section* os = this->choose_output_section(NULL, section_name, elfcpp::SHT_NOTE, flags, false, order, false, - false); + false, true); if (os == NULL) return NULL; @@ -4299,7 +4306,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, - false, false); + false, false, false); // Check for NULL as a linker script may discard .dynsym. if (dynsym != NULL) @@ -4336,7 +4343,8 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, this->choose_output_section(NULL, ".dynsym_shndx", elfcpp::SHT_SYMTAB_SHNDX, elfcpp::SHF_ALLOC, - false, ORDER_DYNAMIC_LINKER, false, false); + false, ORDER_DYNAMIC_LINKER, false, false, + false); if (dynsym_xindex != NULL) { @@ -4364,7 +4372,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, - false, false); + false, false, false); *pdynstr = dynstr; if (dynstr != NULL) { @@ -4398,7 +4406,8 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, Output_section* hashsec = this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH, elfcpp::SHF_ALLOC, false, - ORDER_DYNAMIC_LINKER, false, false); + ORDER_DYNAMIC_LINKER, false, false, + false); Output_section_data* hashdata = new Output_data_const_buffer(phash, hashlen, @@ -4434,7 +4443,8 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects, Output_section* hashsec = this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH, elfcpp::SHF_ALLOC, false, - ORDER_DYNAMIC_LINKER, false, false); + ORDER_DYNAMIC_LINKER, false, false, + false); Output_section_data* hashdata = new Output_data_const_buffer(phash, hashlen, @@ -4541,7 +4551,7 @@ Layout::sized_create_version_sections( elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, - false, false); + false, false, false); // Check for NULL since a linker script may discard this section. if (vsec != NULL) @@ -4573,7 +4583,7 @@ Layout::sized_create_version_sections( elfcpp::SHT_GNU_verdef, elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, false, - false); + false, false); if (vdsec != NULL) { @@ -4606,7 +4616,7 @@ Layout::sized_create_version_sections( elfcpp::SHT_GNU_verneed, elfcpp::SHF_ALLOC, false, ORDER_DYNAMIC_LINKER, false, - false); + false, false); if (vnsec != NULL) { @@ -4655,7 +4665,7 @@ Layout::create_interp(const Target* target) elfcpp::SHT_PROGBITS, elfcpp::SHF_ALLOC, false, ORDER_INTERP, - false, false); + false, false, false); if (osec != NULL) osec->add_output_section_data(odata); } diff --git a/gold/layout.h b/gold/layout.h index b399854..10be3d4 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -1149,7 +1149,7 @@ class Layout choose_output_section(const Relobj* relobj, const char* name, elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, bool is_input_section, Output_section_order order, - bool is_relro, bool is_reloc); + bool is_relro, bool is_reloc, bool match_input_spec); // Create a new Output_section. Output_section* diff --git a/gold/script-sections.cc b/gold/script-sections.cc index ffd4666..3acb39b 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -632,7 +632,7 @@ class Sections_element // Output_section_definition. virtual const char* output_section_name(const char*, const char*, Output_section***, - Script_sections::Section_type*, bool*) + Script_sections::Section_type*, bool*, bool) { return NULL; } // Initialize OSP with an output section. @@ -2003,7 +2003,7 @@ class Output_section_definition : public Sections_element const char* output_section_name(const char* file_name, const char* section_name, Output_section***, Script_sections::Section_type*, - bool*); + bool*, bool); // Initialize OSP with an output section. void @@ -2289,11 +2289,12 @@ Output_section_definition::output_section_name( const char* section_name, Output_section*** slot, Script_sections::Section_type* psection_type, - bool* keep) + bool* keep, + bool match_input_spec) { - // If the input section is linker-created, just look for a match + // If the section is a linker-created output section, just look for a match // on the output section name. - if (file_name == NULL && this->name_ != "/DISCARD/") + if (!match_input_spec && this->name_ != "/DISCARD/") { if (this->name_ != section_name) return NULL; @@ -3568,7 +3569,8 @@ Script_sections::output_section_name( const char* section_name, Output_section*** output_section_slot, Script_sections::Section_type* psection_type, - bool* keep) + bool* keep, + bool is_input_section) { for (Sections_elements::const_iterator p = this->sections_elements_->begin(); p != this->sections_elements_->end(); @@ -3576,7 +3578,8 @@ Script_sections::output_section_name( { const char* ret = (*p)->output_section_name(file_name, section_name, output_section_slot, - psection_type, keep); + psection_type, keep, + is_input_section); if (ret != NULL) { diff --git a/gold/script-sections.h b/gold/script-sections.h index 6e108fa..22bc84f 100644 --- a/gold/script-sections.h +++ b/gold/script-sections.h @@ -164,11 +164,14 @@ class Script_sections // type specified in script. This can be SCRIPT_SECTION_TYPE_NONE if // no type is specified. // *KEEP indicates whether the section should survive garbage collection. + // MATCH_INPUT_SPEC indicates whether the section should be matched + // with input section specs or simply against the output section name + // (i.e., for linker-created sections like .dynamic). const char* output_section_name(const char* file_name, const char* section_name, Output_section*** output_section_slot, Section_type* pscript_section_type, - bool* keep); + bool* keep, bool match_input_spec); // Place a marker for an orphan output section into the SECTIONS // clause. -- 2.7.4