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)
        {