--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -6818,6 +6818,12 @@ section is a member of a section group
 section is used for thread-local-storage
 @item ?
 section is a member of the previously-current section's group, if any
+@item +
+section inherits attributes and (unless explicitly specified) type from the
+previously-current section, adding other attributes as specified
+@item -
+section inherits attributes and (unless explicitly specified) type from the
+previously-current section, removing other attributes as specified
 @item R
 retained section (apply SHF_GNU_RETAIN to prevent linker garbage
 collection, GNU ELF extension)
@@ -6839,6 +6845,12 @@ section may have the executable (@code{x
 @code{.attach_to_group} directive can be used to add a section to a group even
 if the section was not originally declared to be part of that group.
 
+Note further that @code{+} and @code{-} need to come first and can only take
+the effect described here unless overridden by a target.  The attributes
+inherited are those in effect at the time the directive is processed.
+Attributes added later (see above) will not be inherited.  Using either
+together with @code{?} is undefined at this point.
+
 The optional @var{type} argument may contain one of the following constants:
 
 @table @code
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -822,10 +822,12 @@ obj_elf_change_section (const char *name
 
 static bfd_vma
 obj_elf_parse_section_letters (char *str, size_t len,
-			       bool *is_clone, bfd_vma *gnu_attr)
+			       bool *is_clone, int *inherit, bfd_vma *gnu_attr)
 {
   bfd_vma attr = 0;
+
   *is_clone = false;
+  *inherit = 0;
 
   while (len > 0)
     {
@@ -923,6 +925,8 @@ obj_elf_parse_section_letters (char *str
 		  len -= (end - str);
 		  str = end;
 		}
+	      else if (!attr && !*gnu_attr && (*str == '+' || *str == '-'))
+		*inherit = *str == '+' ? 1 : -1;
 	      else
 		as_fatal ("%s", bad_msg);
 	  }
@@ -1171,6 +1175,7 @@ obj_elf_section (int push)
       if (*input_line_pointer == '"')
 	{
 	  bool is_clone;
+	  int inherit;
 
 	  beg = demand_copy_C_string (&dummy);
 	  if (beg == NULL)
@@ -1178,8 +1183,15 @@ obj_elf_section (int push)
 	      ignore_rest_of_line ();
 	      return;
 	    }
-	  attr |= obj_elf_parse_section_letters (beg, strlen (beg),
-						 &is_clone, &gnu_attr);
+	  attr = obj_elf_parse_section_letters (beg, strlen (beg), &is_clone,
+						&inherit, &gnu_attr);
+
+	  if (inherit > 0)
+	    attr |= elf_section_flags (now_seg);
+	  else if (inherit < 0)
+	    attr = elf_section_flags (now_seg) & ~attr;
+	  if (inherit)
+	    type = elf_section_type (now_seg);
 
 	  SKIP_WHITESPACE ();
 	  if (*input_line_pointer == ',')
@@ -1224,6 +1236,9 @@ obj_elf_section (int push)
 	    {
 	      ++input_line_pointer;
 	      SKIP_WHITESPACE ();
+	      if (inherit && *input_line_pointer == ','
+		  && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
+		goto fetch_entsize;
 	      entsize = get_absolute_expression ();
 	      SKIP_WHITESPACE ();
 	      if (entsize < 0)
@@ -1233,6 +1248,12 @@ obj_elf_section (int push)
 		  entsize = 0;
 		}
 	    }
+	  else if ((attr & SHF_MERGE) != 0 && inherit
+		    && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
+	    {
+	    fetch_entsize:
+	      entsize = now_seg->entsize;
+	    }
 	  else if ((attr & SHF_MERGE) != 0)
 	    {
 	      as_warn (_("entity size for SHF_MERGE not specified"));
@@ -1248,6 +1269,9 @@ obj_elf_section (int push)
 		{
 		  linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
 		}
+	      else if (inherit && *input_line_pointer == ','
+		       && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
+		goto fetch_linked_to;
 	      else
 		{
 		  char c;
@@ -1260,6 +1284,17 @@ obj_elf_section (int push)
 		    match.linked_to_symbol_name = xmemdup0 (beg, length);
 		}
 	    }
+	  else if ((attr & SHF_LINK_ORDER) != 0 && inherit
+		   && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
+	    {
+	    fetch_linked_to:
+	      if (now_seg->map_head.linked_to_symbol_name)
+		match.linked_to_symbol_name =
+		  now_seg->map_head.linked_to_symbol_name;
+	      else
+		linked_to_section_index =
+		  elf_section_data (now_seg)->this_hdr.sh_link;
+	    }
 
 	  if ((attr & SHF_GROUP) != 0 && is_clone)
 	    {
@@ -1270,6 +1305,10 @@ obj_elf_section (int push)
 	  if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
 	    {
 	      ++input_line_pointer;
+	      SKIP_WHITESPACE ();
+	      if (inherit && *input_line_pointer == ','
+		  && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
+		goto fetch_group;
 	      match.group_name = obj_elf_section_name ();
 	      if (match.group_name == NULL)
 		attr &= ~SHF_GROUP;
@@ -1286,6 +1325,14 @@ obj_elf_section (int push)
 	      else if (startswith (name, ".gnu.linkonce"))
 		linkonce = 1;
 	    }
+	  else if ((attr & SHF_GROUP) != 0 && inherit
+		   && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
+	    {
+	    fetch_group:
+	      match.group_name = elf_group_name (now_seg);
+	      linkonce =
+	        (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
+	    }
 	  else if ((attr & SHF_GROUP) != 0)
 	    {
 	      as_warn (_("group name for SHF_GROUP not specified"));
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -279,6 +279,11 @@ if { [is_elf_format] } then {
     run_dump_test "section27"
     run_dump_test "section28"
     run_dump_test "section29"
+    if { ![istarget "rx-*-*"] } then {
+	run_dump_test "section30"
+    } else {
+	run_dump_test "section30" {{as -muse-conventional-section-names}}
+    }
     run_dump_test "sh-link-zero"
     run_dump_test "size"
     run_dump_test "dwarf2-1" $dump_opts
--- /dev/null
+++ b/gas/testsuite/gas/elf/section30.d
@@ -0,0 +1,28 @@
+#as: --sectname-subst
+#readelf: -SW
+#name: --sectname-subst plus section attr/type inherting
+# Targets setting NO_PSEUDO_DOT don't allow macros of certain names.
+#notarget: m681*-*-* m68hc1*-*-* s12z-*-* spu-*-* xgate-*-* z80-*-*
+
+#...
+  \[..\] \.group +GROUP +[0-9a-f]+ [0-9a-f]+ 0+c 04 +[1-9][0-9]* +[1-9][0-9]* +4
+  \[..\] \.text +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  AX  0   0 +[1-9][0-9]*
+  \[..\] \.data +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  WA  0   0 +[1-9][0-9]*
+  \[..\] \.bss +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  WA  0   0 +[1-9][0-9]*
+#...
+  \[..\] \.text\.func1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  AX  0   0 +[1-9][0-9]*
+  \[..\] \.text\.func2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  AX  0   0 +[1-9][0-9]*
+  \[..\] \.data\.data1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+1 00  WA  0   0  1
+#...
+  \[..\] \.bss\.data2 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+2 00  WA  0   0  1
+  \[..\] \.rodata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00   A  0   0  1
+  \[..\] \.rodata\.data3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+3 00   A  0   0  1
+  \[..\] \.rodata\.str1\.1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 01 AMS  0   0  1
+  \[..\] \.rodata\.str1\.1\.str1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+8 01 AMS  0   0  1
+  \[..\] \.rodata\.2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  AL  [1-9]   0  1
+  \[..\] \.rodata\.2\.data4 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+4 00  AL  [1-9]   0  1
+  \[..\] \.bss\.data5 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+5 00  WA  0   0  1
+  \[..\] \.rodata\.3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00  AG  0   0  1
+  \[..\] \.rodata\.3\.data6 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+6 00  AG  0   0  1
+  \[..\] \.bss\.data7 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+7 00  WA  0   0  1
+#pass
--- /dev/null
+++ b/gas/testsuite/gas/elf/section30.s
@@ -0,0 +1,67 @@
+	.macro func name:req
+	.pushsection %S.\name, "+"
+	.type \name, %function
+	.global \name
+	.hidden \name
+\name:
+	.endm
+
+	.macro data name:req
+	.pushsection %S.\name, "+"
+	.type \name, %object
+\name:
+	.endm
+
+	.macro end name:req
+	.size \name, . - \name
+	.popsection
+	.endm
+
+
+	.text
+	func func1
+	.nop
+	end func1
+
+	func func2
+	.nop
+	.nop
+	end func2
+
+	.data
+	data data1
+	.byte 1
+	end data1
+
+	.section .bss
+	data data2
+	.skip 2
+	end data2
+
+	.section .rodata, "a", %progbits
+	data data3
+	.byte 3, 3, 3
+	end data3
+
+	.section .rodata.str1.1, "aMS", %progbits, 1
+	data str1
+	.asciz "string1"
+	end str1
+
+	.section .rodata.2, "ao", %progbits, func1
+	data data4
+	.byte 4, 4, 4, 4
+	end data4
+	.pushsection .bss.data5, "-o", %nobits
+	.type data5, %object
+data5:	.fill 5
+	end data5
+
+	.section .rodata.3, "aG", %progbits, sig1, comdat
+	data data6
+	.byte 6, 6, 6, 6, 6, 6
+	end data6
+	.pushsection .bss.data7, "-G", %nobits
+	.type data7, %object
+data7:	.skip 7
+	end data7
