diff --git a/gas/ChangeLog b/gas/ChangeLog
index 4b78a51..9fa602c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,11 @@
+2015-06-03  Nicolas Pitre <nico@linaro.org>
+
+	* as.c (show_usage): Document --sectname-subst.
+	(parse_args): Add --sectname-subst.
+	* as.h (flag_sectname_subst): New.
+	* config/obj-elf.c (obj_elf_section_name): Add %S substitution.
+	* doc/as.texinfo: Document it.
+
 2015-06-08  Nick Clifton  <nickc@redhat.com>
 
 	* config/tc-rx.c (rx_op): Correct handling of integer bignums.
diff --git a/gas/as.c b/gas/as.c
index 2a8923f..fecfcd2 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -284,6 +284,8 @@ Options:\n\
   fprintf (stream, _("\
   --size-check=[error|warning]\n\
 			  ELF .size directive check (default --size-check=error)\n"));
+  fprintf (stream, _("\
+  --sectname-subst        enable section name substitution sequences\n"));
 #endif
   fprintf (stream, _("\
   -f                      skip whitespace and comment preprocessing\n"));
@@ -447,6 +449,7 @@ parse_args (int * pargc, char *** pargv)
       OPTION_EXECSTACK,
       OPTION_NOEXECSTACK,
       OPTION_SIZE_CHECK,
+      OPTION_SECTNAME_SUBST,
       OPTION_ALTERNATE,
       OPTION_AL,
       OPTION_HASH_TABLE_SIZE,
@@ -481,6 +484,7 @@ parse_args (int * pargc, char *** pargv)
     ,{"execstack", no_argument, NULL, OPTION_EXECSTACK}
     ,{"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK}
     ,{"size-check", required_argument, NULL, OPTION_SIZE_CHECK}
+    ,{"sectname-subst", no_argument, NULL, OPTION_SECTNAME_SUBST}
 #endif
     ,{"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
     ,{"gdwarf-2", no_argument, NULL, OPTION_GDWARF2}
@@ -848,6 +852,10 @@ This program has absolutely no warranty.\n"));
 	  else
 	    as_fatal (_("Invalid --size-check= option: `%s'"), optarg);
 	  break;
+
+	case OPTION_SECTNAME_SUBST:
+	  flag_sectname_subst = 1;
+	  break;
 #endif
 	case 'Z':
 	  flag_always_generate_output = 1;
diff --git a/gas/as.h b/gas/as.h
index 6de319e..635b2c5 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -589,6 +589,9 @@ COMMON enum
     size_check_warning
   }
 flag_size_check;
+
+/* If section name substitution sequences should be honored */
+COMMON int flag_sectname_subst;
 #endif
 
 #ifndef DOLLAR_AMBIGU
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 4d7a8a7..78dc6d9 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -917,6 +917,27 @@ obj_elf_section_name (void)
       name = (char *) xmalloc (end - input_line_pointer + 1);
       memcpy (name, input_line_pointer, end - input_line_pointer);
       name[end - input_line_pointer] = '\0';
+
+      while (flag_sectname_subst)
+        {
+	  char *subst = strchr (name, '%');
+	  if (subst && subst[1] == 'S')
+	    {
+	      int oldlen = strlen (name);
+	      int substlen = strlen (now_seg->name);
+	      int newlen = oldlen - 2 + substlen;
+	      char *newname = (char *) xmalloc (newlen + 1);
+	      int headlen = subst - name;
+	      memcpy (newname, name, headlen);
+	      strcpy (newname + headlen, now_seg->name);
+	      strcat (newname + headlen, subst + 2);
+	      xfree (name);
+	      name = newname;
+	    }
+	  else
+	    break;
+	}
+
 #ifdef tc_canonicalize_section_name
       name = tc_canonicalize_section_name (name);
 #endif
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 5710e1c..6694b23 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -238,7 +238,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
  @var{objfile}] [@b{-R}] [@b{--reduce-memory-overheads}] [@b{--statistics}]
  [@b{-v}] [@b{-version}] [@b{--version}] [@b{-W}] [@b{--warn}]
  [@b{--fatal-warnings}] [@b{-w}] [@b{-x}] [@b{-Z}] [@b{@@@var{FILE}}]
- [@b{--size-check=[error|warning]}]
+ [@b{--sectname-subst}] [@b{--size-check=[error|warning]}]
  [@b{--target-help}] [@var{target-options}]
  [@b{--}|@var{files} @dots{}]
 @c
@@ -766,6 +766,14 @@ This option reduces GAS's memory requirements, at the expense of making the
 assembly processes slower.  Currently this switch is a synonym for
 @samp{--hash-size=4051}, but in the future it may have other effects as well.
 
+@ifset ELF
+@item --sectname-subst
+Honor substitution sequences in section names.
+@ifclear man
+@xref{Section Name Substitutions,,@code{.section @var{name}}}.
+@end ifclear
+@end ifset
+
 @item --statistics
 Print the maximum space (in bytes) and total time (in seconds) used by
 assembly.
@@ -6259,6 +6267,38 @@ For ELF targets, the @code{.section} directive is used like this:
 .section @var{name} [, "@var{flags}"[, @@@var{type}[,@var{flag_specific_arguments}]]]
 @end smallexample
 
+@anchor{Section Name Substitutions}
+@kindex --sectname-subst
+@cindex section name substitution
+If the @samp{--sectname-subst} command-line option is provided, the @var{name}
+argument may contain a substitution sequence. Only @code{%S} is supported
+at the moment, and substitutes the current section name. For example:
+
+@smallexample
+.macro exception_code
+.section %S.exception
+[exception code here]
+.previous
+.endm
+
+.text
+[code]
+exception_code
+[...]
+
+.section .init
+[init code]
+exception_code
+[...]
+@end smallexample
+
+The two @code{exception_code} invocations above would create the
+@code{.text.exception} and @code{.init.exception} sections respectively.
+This is useful e.g. to discriminate between anciliary sections that are
+tied to setup code to be discarded after use from anciliary sections that
+need to stay resident without having to define multiple @code{exception_code}
+macros just for that purpose.
+
 The optional @var{flags} argument is a quoted string which may contain any
 combination of the following characters:
 @table @code
