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;
}
// 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.
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)
{
{
os = this->choose_output_section(object, name, sh_type,
shdr.get_sh_flags(), true,
- ORDER_INVALID, false, false);
+ ORDER_INVALID, false, false,
+ true);
}
else
{
|| (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);
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;
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)
{
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;
{
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;
(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)
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;
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)
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)
{
elfcpp::SHF_ALLOC,
false,
ORDER_DYNAMIC_LINKER,
- false, false);
+ false, false, false);
*pdynstr = dynstr;
if (dynstr != NULL)
{
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,
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,
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)
elfcpp::SHT_GNU_verdef,
elfcpp::SHF_ALLOC,
false, ORDER_DYNAMIC_LINKER, false,
- false);
+ false, false);
if (vdsec != NULL)
{
elfcpp::SHT_GNU_verneed,
elfcpp::SHF_ALLOC,
false, ORDER_DYNAMIC_LINKER, false,
- false);
+ false, false);
if (vnsec != NULL)
{
elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC,
false, ORDER_INTERP,
- false, false);
+ false, false, false);
if (osec != NULL)
osec->add_output_section_data(odata);
}
// 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.
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
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;
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();
{
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)
{