diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 62f4d7f0c5..ca3b5db14d 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -50,6 +50,7 @@
 #include "cli/cli-setshow.h"
 #include "cli/cli-cmds.h"
 #include "cli/cli-utils.h"
+#include "cli/cli-style.h"
 
 #include "extension.h"
 #include "common/pathstuff.h"
@@ -211,6 +212,177 @@ show_command (const char *arg, int from_tty)
   cmd_show_list (showlist, from_tty, "");
 }
 
+/* Completer for the "set|show leading-args" commands.  */
+
+static void
+leading_args_cmd_completer (struct cmd_list_element *ignore,
+			    completion_tracker &tracker,
+			    const char *text, const char *word)
+{
+  tracker.set_use_custom_word_point (true);
+
+  const char *delim = strstr (text, "=");
+
+  /* If we're past the "=" delimiter, complete the
+     "set|show leading-args COMMAND = " as if the user has typed COMMAND.  */
+  if (delim != text
+      && delim != nullptr
+      && isspace (delim[-1])
+      && (isspace (delim[1]) || delim[1] == '\0'))
+    {
+      std::string new_text = std::string (text);
+
+      new_text.replace (delim - text, 1, "");
+      tracker.advance_custom_word_point_by (1);
+      complete_nested_command_line (tracker, new_text.c_str ());
+      return;
+    }
+
+  /* We're not yet past the "=" delimiter.  Complete a command.  */
+  complete_nested_command_line (tracker, text);
+}
+
+/* Look up the contents of TEXT as a command usable with leading args.
+   Throws an error if no such command is found.
+   Return the found command.  If the found command is a postfix command,
+   set *PREFIX_CMD to its prefix command.  */
+
+static struct cmd_list_element *
+lookup_cmd_for_leading_args (const char *text,
+			     struct cmd_list_element **prefix_cmd)
+{
+  struct cmd_list_element *lcmd, *alias, *cmd;
+
+  if (text == nullptr || skip_spaces (text) == nullptr)
+    error (_("COMMAND missing."));
+
+  /* We first use lookup_cmd to verify TEXT unambiguously identifies
+     a command.  */
+  const char *line = text;
+  lcmd = lookup_cmd (&line, cmdlist, "", NULL,
+		     /*allow_unknown=*/ 0,
+		     /*ignore_help_classes=*/ 1);
+
+  /* Note that we accept leading args for prefix commands,
+     as a prefix command can also be a valid usable
+     command accepting some arguments.
+     For example, "thread apply" applies a command to a
+     list of thread id, and is also the prefix command for
+     thread apply all.  */
+
+  /* We have an unambiguous command for which leading args
+     can be specified.  What remains after having found LCMD
+     is either spaces, or the = character.  */
+  size_t cmd_len = line - text;
+  line = skip_spaces (line);
+  if (*line != '=' && *line != '\0')
+    error (_("Junk after command \"%.*s\": %s"),
+	   (int) cmd_len, text, line);
+
+  /* We then use lookup_cmd_composition to detect if the user
+     has specified an alias, and find the possible prefix_cmd
+     of cmd.  */
+  (void) lookup_cmd_composition (text, &alias, prefix_cmd, &cmd);
+  gdb_assert (cmd != nullptr);
+  gdb_assert (cmd == lcmd);
+  if (alias != nullptr)
+    cmd = alias;
+
+  return cmd;
+}
+
+/* Implementation of the "set leading-args" command.  */
+
+static void
+set_leading_args_command (const char *arg, int from_tty)
+{
+  struct cmd_list_element *prefix_cmd;
+  struct cmd_list_element *cmd = lookup_cmd_for_leading_args (arg, &prefix_cmd);
+
+  const char *equals = strchr (arg, '=');;
+  const char *leading_args;
+
+  if (equals != nullptr)
+    {
+      leading_args = skip_spaces (++equals);
+      if (*leading_args == '\0')
+	error (_("Leading args missing after =."));
+    }
+  else
+    leading_args = nullptr;
+
+  if (cmd->leading_args)
+    xfree ((char *) cmd->leading_args);
+  if (leading_args == nullptr)
+    cmd->leading_args = nullptr;
+  else
+    cmd->leading_args = xstrdup (leading_args);
+}
+
+/* Print a message showing C name and its leading args or <no leading args>
+   if C has no leading args.
+   If SILENT_FOR_NO_LEADING_ARGS, does nothing if C has no leading args.  */
+
+static void
+show_leading_args (struct cmd_list_element *c,
+		   const char *prefix,
+		   bool silent_for_no_leading_args)
+{
+  if (c->leading_args != nullptr || !silent_for_no_leading_args)
+    {
+      fputs_filtered ("leading-args ", gdb_stdout);
+      fprintf_styled (gdb_stdout, title_style.style (),
+		      "%s%s",
+		      prefix == nullptr ? "" : prefix, c->name);
+      fprintf_filtered (gdb_stdout, " = %s\n",
+			c->leading_args == nullptr ?
+			"<no leading args>" : c->leading_args);
+    }
+}
+
+/* Recursively traverse COMMANDLIST and prints a message showing
+   the leading-args of the commands have have non-null leading args.
+   PREFIX is the prefix that led to COMMANDLIST.  */
+
+static void
+show_leading_args_command_1 (struct cmd_list_element *commandlist,
+			     const char *prefix)
+{
+  struct cmd_list_element *c;
+
+  /* Walk through the commands.  */
+  for (c = commandlist; c; c = c->next)
+    {
+      show_leading_args (c, prefix, true);
+      /* If C has subcommands, recursively search if its subcommands
+	 have leading args.
+	 Do not recurse for abbreviations to avoid duplicates
+	 in the output.  */
+      if (c->prefixlist != NULL && !c->abbrev_flag)
+	show_leading_args_command_1 (*c->prefixlist, c->prefixname);
+    }
+}
+
+/* Implementation of the "show leading-args" command.  */
+
+static void
+show_leading_args_command (const char *arg, int from_tty)
+{
+  if (arg != nullptr && skip_spaces (arg) != nullptr)
+    {
+      struct cmd_list_element *prefix_cmd;
+      struct cmd_list_element *c = lookup_cmd_for_leading_args (arg,
+								&prefix_cmd);
+
+      show_leading_args (c,
+			 prefix_cmd == nullptr ?
+			 "" : prefix_cmd->prefixname,
+			 false);
+    }
+  else
+    show_leading_args_command_1 (cmdlist, "");
+}
+
 
 /* Provide documentation on command or list given by COMMAND.  FROM_TTY
    is ignored.  */
@@ -1358,7 +1530,7 @@ show_user (const char *args, int from_tty)
     {
       const char *comname = args;
 
-      c = lookup_cmd (&comname, cmdlist, "", 0, 1);
+      c = lookup_cmd (&comname, cmdlist, "", NULL, 0, 1);
       if (!cli_user_command_p (c))
 	error (_("Not a user command."));
       show_user_1 (c, "", args, gdb_stdout);
@@ -1390,6 +1562,37 @@ apropos_command (const char *arg, int from_tty)
   apropos_cmd (gdb_stdout, cmdlist, verbose, pattern, "");
 }
 
+/* Completer for the "alias_command".  */
+
+static void
+alias_command_completer (struct cmd_list_element *ignore,
+			 completion_tracker &tracker,
+			 const char *text, const char *word)
+{
+  tracker.set_use_custom_word_point (true);
+
+  const char *delim = strstr (text, "=");
+
+  /* If we're past the "=" delimiter, complete the
+     "alias ALIAS = COMMAND" as if the user is typing
+     set leading-args COMMAND = LEADING-ARGS...  */
+  if (delim != text
+      && delim != nullptr
+      && isspace (delim[-1])
+      && (isspace (delim[1]) || delim[1] == '\0'))
+    {
+      std::string new_text = std::string (delim + 1);
+
+      tracker.advance_custom_word_point_by (delim + 1 - text);
+      leading_args_cmd_completer (ignore, tracker, new_text.c_str (), word);
+      return;
+    }
+
+  /* We're not yet past the "=" delimiter.  Complete a command, as
+     the user maybe is typing an alias following a prefix.  */
+  complete_nested_command_line (tracker, text);
+}
+
 /* Subroutine of alias_command to simplify it.
    Return the first N elements of ARGV flattened back to a string
    with a space separating each element.
@@ -1424,7 +1627,7 @@ valid_command_p (const char *command)
 {
   struct cmd_list_element *c;
 
-  c = lookup_cmd_1 (& command, cmdlist, NULL, 1);
+  c = lookup_cmd_1 (& command, cmdlist, NULL, NULL, 1);
 
   if (c == NULL || c == (struct cmd_list_element *) -1)
     return false;
@@ -1442,7 +1645,7 @@ valid_command_p (const char *command)
 static void
 alias_usage_error (void)
 {
-  error (_("Usage: alias [-a] [--] ALIAS = COMMAND"));
+  error (_("Usage: alias [-a] [--] ALIAS = COMMAND [= LEADING-ARGS...]"));
 }
 
 /* Make an alias of an existing command.  */
@@ -1462,7 +1665,12 @@ alias_command (const char *args, int from_tty)
   std::string args2 (args, equals - args);
 
   gdb_argv built_alias_argv (args2.c_str ());
-  gdb_argv command_argv (equals + 1);
+  const char *equals_leading_args =  strchr (equals + 1, '=');
+  std::string command_argv_str (equals + 1,
+				equals_leading_args == nullptr ?
+				strlen (equals + 1)
+				: equals_leading_args - equals - 1);
+  gdb_argv command_argv (command_argv_str.c_str ());
 
   char **alias_argv = built_alias_argv.get ();
   while (alias_argv[0] != NULL)
@@ -1514,6 +1722,8 @@ alias_command (const char *args, int from_tty)
   if (valid_command_p (alias))
     error (_("Alias already exists: %s"), alias);
 
+  struct cmd_list_element *alias_cmd;
+
   /* If ALIAS is one word, it is an alias for the entire COMMAND.
      Example: alias spe = set print elements
 
@@ -1526,8 +1736,8 @@ alias_command (const char *args, int from_tty)
   if (alias_argc == 1)
     {
       /* add_cmd requires *we* allocate space for name, hence the xstrdup.  */
-      add_com_alias (xstrdup (alias_argv[0]), command, class_alias,
-		     abbrev_flag);
+      alias_cmd = add_com_alias (xstrdup (alias_argv[0]), command, class_alias,
+				 abbrev_flag);
     }
   else
     {
@@ -1546,19 +1756,30 @@ alias_command (const char *args, int from_tty)
       alias_prefix = alias_prefix_string.c_str ();
       command_prefix = command_prefix_string.c_str ();
 
-      c_command = lookup_cmd_1 (& command_prefix, cmdlist, NULL, 1);
+      c_command = lookup_cmd_1 (& command_prefix, cmdlist, NULL, NULL, 1);
       /* We've already tried to look up COMMAND.  */
       gdb_assert (c_command != NULL
 		  && c_command != (struct cmd_list_element *) -1);
       gdb_assert (c_command->prefixlist != NULL);
-      c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, 1);
+      c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, NULL, 1);
       if (c_alias != c_command)
 	error (_("ALIAS and COMMAND prefixes do not match."));
 
       /* add_cmd requires *we* allocate space for name, hence the xstrdup.  */
-      add_alias_cmd (xstrdup (alias_argv[alias_argc - 1]),
-		     command_argv[command_argc - 1],
-		     class_alias, abbrev_flag, c_command->prefixlist);
+      alias_cmd = add_alias_cmd (xstrdup (alias_argv[alias_argc - 1]),
+				 command_argv[command_argc - 1],
+				 class_alias, abbrev_flag,
+				 c_command->prefixlist);
+    }
+
+  gdb_assert (alias_cmd);
+  gdb_assert (alias_cmd->leading_args == nullptr);
+  if (equals_leading_args != nullptr)
+    {
+      const char *leading_args = skip_spaces (equals_leading_args + 1);
+
+      if (*leading_args != '\0')
+	alias_cmd->leading_args = xstrdup (leading_args);
     }
 }
 
@@ -1855,6 +2076,26 @@ You can supply a command number to start with, or a `+' to start after\n\
 the previous command number shown."),
 	   &showlist);
 
+  c = add_cmd ("leading-args", class_support, set_leading_args_command, _("\
+Set or clear leading args automatically preprended to a command or alias.\n\
+Usage: set leading-args COMMAND [= LEADING-ARGS...]\n\
+Set or clear the leading arguments automatically prepended\n\
+to the arguments the user provides when COMMAND is run.\n\
+Note that COMMAND can be an alias.  Commands and their aliases\n\
+do not share their leading arguments, so you can specify different\n\
+leading arguments for a command and for each of its aliases.\n\
+Without the [= LEADING-ARGS...], clears COMMAND leading arguments."),
+	   &setlist);
+  set_cmd_completer_handle_brkchars (c, leading_args_cmd_completer);
+
+  c = add_cmd ("leading-args", class_support, show_leading_args_command, _("\
+Show the leading args of a command, or of all commands.\n\
+Usage: show leading-args [COMMAND]\n\
+Show the leading args of COMMAND.  Without COMMAND, show the leading args\n\
+of all commands."),
+	   &showlist);
+  set_cmd_completer_handle_brkchars (c, leading_args_cmd_completer);
+
   add_cmd ("version", no_set_class, show_version,
 	   _("Show what version of GDB this is."), &showlist);
 
@@ -2007,17 +2248,28 @@ When 'on', each command is displayed as it is executed."),
 
   c = add_com ("alias", class_support, alias_command, _("\
 Define a new command that is an alias of an existing command.\n\
-Usage: alias [-a] [--] ALIAS = COMMAND\n\
+Usage: alias [-a] [--] ALIAS = COMMAND [= LEADING-ARGS...]\n\
 ALIAS is the name of the alias command to create.\n\
 COMMAND is the command being aliased to.\n\
 If \"-a\" is specified, the command is an abbreviation,\n\
 and will not appear in help command list output.\n\
 \n\
+You can optionally provide LEADING-ARGS to define at the same time\n\
+ALIAS and its leading args.  This is the equivalent of:\n\
+  alias ALIAS = COMMAND\n\
+  set leading-args ALIAS = LEADING-ARGS...\n\
+\n\
 Examples:\n\
 Make \"spe\" an alias of \"set print elements\":\n\
   alias spe = set print elements\n\
 Make \"elms\" an alias of \"elements\" in the \"set print\" command:\n\
-  alias -a set print elms = set print elements"));
+  alias -a set print elms = set print elements\n\
+Make \"btf\" an alias of \"backtrace -full -past-entry -past-main\" :\n\
+  alias btf = backtrace = -full -past-entry -past-main\n\
+Make \"wLapPeu\" an alias of 2 nested \"with\":\n\
+  alias wLapPeu = with = language pascal -- with print elements unlimited --"));
+
+  set_cmd_completer_handle_brkchars (c, alias_command_completer);
 }
 
 void
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index a6ddd8cc6d..f01c8a59c2 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -343,7 +343,7 @@ add_alias_cmd (const char *name, const char *oldname,
   struct cmd_list_element *old;
 
   tmp = oldname;
-  old = lookup_cmd (&tmp, *list, "", 1, 1);
+  old = lookup_cmd (&tmp, *list, "", NULL, 1, 1);
 
   return add_alias_cmd (name, old, theclass, abbrev_flag, list);
 }
@@ -1045,6 +1045,7 @@ void
 help_cmd (const char *command, struct ui_file *stream)
 {
   struct cmd_list_element *c;
+  const char *initial_command = command;
 
   if (!command)
     {
@@ -1058,7 +1059,7 @@ help_cmd (const char *command, struct ui_file *stream)
       return;
     }
 
-  c = lookup_cmd (&command, cmdlist, "", 0, 0);
+  c = lookup_cmd (&command, cmdlist, "", NULL, 0, 0);
 
   if (c == 0)
     return;
@@ -1078,6 +1079,41 @@ help_cmd (const char *command, struct ui_file *stream)
   fputs_filtered (c->doc, stream);
   fputs_filtered ("\n", stream);
 
+  if (c->func != nullptr)
+    {
+      /* Print the leading args of the command if it has some.
+	 Use lookup_cmd_composition to find if help was requested for
+	 an alias.  In this case, rather print the alias leading_args.  */
+
+      struct cmd_list_element *alias, *prefix_cmd, *cmd;
+      const char *name, *leading_args;
+
+      (void) lookup_cmd_composition (initial_command,
+				     &alias, &prefix_cmd, &cmd);
+      gdb_assert (cmd != nullptr);
+      gdb_assert (cmd == c);
+
+      if (alias == nullptr)
+	{
+	  name = c->name;
+	  leading_args = c->leading_args;
+	}
+      else
+	{
+	  name = alias->name;
+	  leading_args = alias->leading_args;
+	}
+      if (leading_args != nullptr)
+	{
+	  fputs_filtered ("leading-args ", stream);
+	  fprintf_styled (stream, title_style.style (),
+			  "%s%s",
+			  prefix_cmd == nullptr ? "" : prefix_cmd->prefixname,
+			  name);
+	  fprintf_filtered (stream, " = %s\n", leading_args);
+	}
+    }
+
   if (c->prefixlist == 0 && c->func != NULL)
     return;
   fprintf_filtered (stream, "\n");
@@ -1409,8 +1445,12 @@ valid_user_defined_cmd_name_p (const char *name)
    the list in which there are ambiguous choices (and *TEXT will be set to
    the ambiguous text string).
 
+   if LEADING_ARGS is not null and the found command has leading args defined,
+   then *LEADING_ARGS points at these leading args.
+
    If the located command was an abbreviation, this routine returns the base
-   command of the abbreviation.
+   command of the abbreviation.  Note that *LEADING_ARGS will point at the
+   leading args defined for the alias.
 
    It does no error reporting whatsoever; control will always return
    to the superior routine.
@@ -1437,11 +1477,13 @@ valid_user_defined_cmd_name_p (const char *name)
 
 struct cmd_list_element *
 lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
-	      struct cmd_list_element **result_list, int ignore_help_classes)
+	      struct cmd_list_element **result_list, const char **leading_args,
+	      int ignore_help_classes)
 {
   char *command;
   int len, nfound;
   struct cmd_list_element *found, *c;
+  bool found_alias = false;
   const char *line = *text;
 
   while (**text == ' ' || **text == '\t')
@@ -1477,6 +1519,8 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
 	/* Will be modified in calling routine
 	   if we know what the prefix command is.  */
 	*result_list = 0;
+      if (leading_args != NULL)
+	*leading_args = nullptr;
       return CMD_LIST_AMBIGUOUS;	/* Ambiguous.  */
     }
 
@@ -1492,22 +1536,30 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
        are warning about the alias, we may also warn about the command
        itself and we will adjust the appropriate DEPRECATED_WARN_USER
        flags.  */
-      
+
       if (found->deprecated_warn_user)
 	deprecated_cmd_warning (line);
+
+      /* Return the leading_args of the alias, not the leading_args
+	 of the command it is pointing to.  */
+      if (leading_args != NULL)
+	*leading_args = found->leading_args;
       found = found->cmd_pointer;
+      found_alias = true;
     }
   /* If we found a prefix command, keep looking.  */
 
   if (found->prefixlist)
     {
       c = lookup_cmd_1 (text, *found->prefixlist, result_list,
-			ignore_help_classes);
+			leading_args, ignore_help_classes);
       if (!c)
 	{
 	  /* Didn't find anything; this is as far as we got.  */
 	  if (result_list != NULL)
 	    *result_list = clist;
+	  if (!found_alias && leading_args != NULL)
+	    *leading_args = found->leading_args;
 	  return found;
 	}
       else if (c == CMD_LIST_AMBIGUOUS)
@@ -1522,11 +1574,18 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
 	         at the top of this function to clarify what is
 	         supposed to be going on.  */
 	      *result_list = found;
+	  /* For ambiguous commands, do not return any leading_args args.  */
+	  if (leading_args != nullptr)
+	    *leading_args = nullptr;
 	  return c;
 	}
       else
 	{
 	  /* We matched!  */
+	  /*
+	  if (leading_args != NULL && *leading_args == nullptr)
+	    *leading_args = c->leading_args;
+	    */
 	  return c;
 	}
     }
@@ -1534,6 +1593,8 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
     {
       if (result_list != NULL)
 	*result_list = clist;
+      if (!found_alias && leading_args != NULL)
+	*leading_args = found->leading_args;
       return found;
     }
 }
@@ -1553,21 +1614,28 @@ undef_cmd_error (const char *cmdtype, const char *q)
 
 /* Look up the contents of *LINE as a command in the command list LIST.
    LIST is a chain of struct cmd_list_element's.
-   If it is found, return the struct cmd_list_element for that command
-   and update *LINE to point after the command name, at the first argument.
+   If it is found, return the struct cmd_list_element for that command,
+   update *LINE to point after the command name, at the first argument
+   and update *LEADING_ARGS (if LEADING_ARGS is not null) to point at
+   the leading args to prepend to the user provided args when running
+   the command.
+   Note that if the found cmd_list_element is found via an alias,
+   the leading args of the alias are returned.
+
    If not found, call error if ALLOW_UNKNOWN is zero
    otherwise (or if error returns) return zero.
    Call error if specified command is ambiguous,
    unless ALLOW_UNKNOWN is negative.
    CMDTYPE precedes the word "command" in the error message.
 
-   If INGNORE_HELP_CLASSES is nonzero, ignore any command list
+   If IGNORE_HELP_CLASSES is nonzero, ignore any command list
    elements which are actually help classes rather than commands (i.e.
    the function field of the struct cmd_list_element is 0).  */
 
 struct cmd_list_element *
 lookup_cmd (const char **line, struct cmd_list_element *list,
 	    const char *cmdtype,
+	    const char **leading_args,
 	    int allow_unknown, int ignore_help_classes)
 {
   struct cmd_list_element *last_list = 0;
@@ -1579,7 +1647,7 @@ lookup_cmd (const char **line, struct cmd_list_element *list,
   if (!*line)
     error (_("Lack of needed %scommand"), cmdtype);
 
-  c = lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
+  c = lookup_cmd_1 (line, list, &last_list, leading_args, ignore_help_classes);
 
   if (!c)
     {
diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
index 05280d9d22..82a0858351 100644
--- a/gdb/cli/cli-decode.h
+++ b/gdb/cli/cli-decode.h
@@ -68,6 +68,8 @@ struct cmd_list_element
     {
       if (doc && doc_allocated)
 	xfree ((char *) doc);
+      if (leading_args)
+	xfree ((char *) leading_args);
     }
 
     DISABLE_COPY_AND_ASSIGN (cmd_list_element);
@@ -175,6 +177,10 @@ struct cmd_list_element
     /* Hook for another command to be executed after this command.  */
     struct cmd_list_element *hook_post = nullptr;
 
+    /* Leading arguments to automatically prepend to the user
+       provided arguments when running this command or alias.  */
+    const char *leading_args = nullptr;
+
     /* Nonzero identifies a prefix command.  For them, the address
        of the variable containing the list of subcommands.  */
     struct cmd_list_element **prefixlist = nullptr;
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 361ead4725..23bbbe546c 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -971,7 +971,7 @@ process_next_line (const char *p, struct command_line **command,
       /* Resolve command abbreviations (e.g. 'ws' for 'while-stepping').  */
       const char *cmd_name = p;
       struct cmd_list_element *cmd
-	= lookup_cmd_1 (&cmd_name, cmdlist, NULL, 1);
+	= lookup_cmd_1 (&cmd_name, cmdlist, NULL, NULL, 1);
       cmd_name = skip_spaces (cmd_name);
       bool inline_cmd = *cmd_name != '\0';
 
@@ -1328,7 +1328,7 @@ validate_comname (const char **comname)
       std::string prefix (*comname, last_word - 1);
       const char *tem = prefix.c_str ();
 
-      c = lookup_cmd (&tem, cmdlist, "", 0, 1);
+      c = lookup_cmd (&tem, cmdlist, "", NULL, 0, 1);
       if (c->prefixlist == NULL)
 	error (_("\"%s\" is not a prefix command."), prefix.c_str ());
 
@@ -1384,7 +1384,7 @@ do_define_command (const char *comname, int from_tty,
 
   /* Look it up, and verify that we got an exact match.  */
   tem = comname;
-  c = lookup_cmd (&tem, *list, "", -1, 1);
+  c = lookup_cmd (&tem, *list, "", NULL, -1, 1);
   if (c && strcmp (comname, c->name) != 0)
     c = 0;
 
@@ -1419,7 +1419,7 @@ do_define_command (const char *comname, int from_tty,
     {
       /* Look up cmd it hooks, and verify that we got an exact match.  */
       tem = comname + hook_name_size;
-      hookc = lookup_cmd (&tem, *list, "", -1, 0);
+      hookc = lookup_cmd (&tem, *list, "", NULL, -1, 0);
       if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
 	hookc = 0;
       if (!hookc && commands == nullptr)
@@ -1488,7 +1488,7 @@ document_command (const char *comname, int from_tty)
   list = validate_comname (&comname);
 
   tem = comname;
-  c = lookup_cmd (&tem, *list, "", 0, 1);
+  c = lookup_cmd (&tem, *list, "", NULL, 0, 1);
 
   if (c->theclass != class_user)
     error (_("Command \"%s\" is built-in."), comfull);
diff --git a/gdb/command.h b/gdb/command.h
index 4d52f00de5..224bb1b6bc 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -244,11 +244,13 @@ extern enum cmd_types cmd_type (struct cmd_list_element *cmd);
 extern struct cmd_list_element *lookup_cmd (const char **,
 					    struct cmd_list_element *,
 					    const char *,
+					    const char **,
 					    int, int);
 
 extern struct cmd_list_element *lookup_cmd_1 (const char **,
 					      struct cmd_list_element *,
 					      struct cmd_list_element **,
+					      const char **,
 					      int);
 
 extern struct cmd_list_element *deprecate_cmd (struct cmd_list_element *,
diff --git a/gdb/completer.c b/gdb/completer.c
index 6892a62bb9..b93134ed5e 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1341,7 +1341,7 @@ complete_line_internal_1 (completion_tracker &tracker,
     }
   else
     {
-      c = lookup_cmd_1 (&p, cmdlist, &result_list, ignore_help_classes);
+      c = lookup_cmd_1 (&p, cmdlist, &result_list, NULL, ignore_help_classes);
     }
 
   /* Move p up to the next interesting thing.  */
diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c
index f2fa40e453..8cf70f6e52 100644
--- a/gdb/guile/scm-cmd.c
+++ b/gdb/guile/scm-cmd.c
@@ -515,7 +515,7 @@ gdbscm_parse_command_name (const char *name,
   prefix_text[i + 1] = '\0';
 
   prefix_text2 = prefix_text;
-  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, 1);
+  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
   if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
     {
       msg = xstrprintf (_("could not find command prefix '%s'"), prefix_text);
diff --git a/gdb/guile/scm-param.c b/gdb/guile/scm-param.c
index 53120cb23e..4d3ce6770a 100644
--- a/gdb/guile/scm-param.c
+++ b/gdb/guile/scm-param.c
@@ -463,13 +463,13 @@ add_setshow_generic (enum var_types param_type, enum command_class cmd_class,
   /* Lookup created parameter, and register Scheme object against the
      parameter context.  Perform this task against both lists.  */
   tmp_name = cmd_name;
-  param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
+  param = lookup_cmd (&tmp_name, *show_list, "", NULL, 0, 1);
   gdb_assert (param != NULL);
   set_cmd_context (param, self);
   *set_cmd = param;
 
   tmp_name = cmd_name;
-  param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
+  param = lookup_cmd (&tmp_name, *set_list, "", NULL, 0, 1);
   gdb_assert (param != NULL);
   set_cmd_context (param, self);
   *show_cmd = param;
@@ -966,7 +966,7 @@ pascm_parameter_defined_p (const char *name, struct cmd_list_element *list)
 {
   struct cmd_list_element *c;
 
-  c = lookup_cmd_1 (&name, list, NULL, 1);
+  c = lookup_cmd_1 (&name, list, NULL, NULL, 1);
 
   /* If the name is ambiguous that's ok, it's a new parameter still.  */
   return c != NULL && c != CMD_LIST_AMBIGUOUS;
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 0f94100438..bd06474688 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -3148,7 +3148,7 @@ is restored."),
 				     show_inferior_tty_command,
 				     &setlist, &showlist);
   cmd_name = "inferior-tty";
-  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
   gdb_assert (c != NULL);
   add_alias_cmd ("tty", c, class_alias, 0, &cmdlist);
 
@@ -3161,7 +3161,7 @@ Follow this command with any number of args, to be passed to the program."),
 				   set_args_command,
 				   show_args_command,
 				   &setlist, &showlist);
-  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
   gdb_assert (c != NULL);
   set_cmd_completer (c, filename_completer);
 
@@ -3180,7 +3180,7 @@ working directory."),
 				   set_cwd_command,
 				   show_cwd_command,
 				   &setlist, &showlist);
-  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
   gdb_assert (c != NULL);
   set_cmd_completer (c, filename_completer);
 
diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c
index c7b9afdb11..559652de93 100644
--- a/gdb/python/py-auto-load.c
+++ b/gdb/python/py-auto-load.c
@@ -84,12 +84,12 @@ Show the debugger's behaviour regarding auto-loaded Python scripts, "
 			   NULL, NULL, show_auto_load_python_scripts,
 			   &setlist, &showlist);
   cmd_name = "auto-load-scripts";
-  cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  cmd = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
   deprecate_cmd (cmd, "set auto-load python-scripts");
 
   /* It is needed because lookup_cmd updates the CMD_NAME pointer.  */
   cmd_name = "auto-load-scripts";
-  cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1);
+  cmd = lookup_cmd (&cmd_name, showlist, "", NULL, -1, 1);
   deprecate_cmd (cmd, "show auto-load python-scripts");
 
   add_cmd ("python-scripts", class_info, info_auto_load_python_scripts,
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 87d1888c52..70e328080c 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -396,7 +396,7 @@ gdbpy_parse_command_name (const char *name,
   std::string prefix_text (name, i + 1);
 
   prefix_text2 = prefix_text.c_str ();
-  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, 1);
+  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
   if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
     {
       PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index afeff581ee..87af351051 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -566,12 +566,12 @@ add_setshow_generic (int parmclass, enum command_class cmdclass,
   /* Lookup created parameter, and register Python object against the
      parameter context.  Perform this task against both lists.  */
   tmp_name = cmd_name;
-  param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
+  param = lookup_cmd (&tmp_name, *show_list, "", NULL, 0, 1);
   if (param)
     set_cmd_context (param, self);
 
   tmp_name = cmd_name;
-  param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
+  param = lookup_cmd (&tmp_name, *set_list, "", NULL, 0, 1);
   if (param)
     set_cmd_context (param, self);
 }
diff --git a/gdb/remote.c b/gdb/remote.c
index 124d254478..801091c9aa 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -14312,10 +14312,10 @@ If set, a break, instead of a cntrl-c, is sent to the remote target."),
 			   set_remotebreak, show_remotebreak,
 			   &setlist, &showlist);
   cmd_name = "remotebreak";
-  cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1);
+  cmd = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
   deprecate_cmd (cmd, "set remote interrupt-sequence");
   cmd_name = "remotebreak"; /* needed because lookup_cmd updates the pointer */
-  cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1);
+  cmd = lookup_cmd (&cmd_name, showlist, "", NULL, -1, 1);
   deprecate_cmd (cmd, "show remote interrupt-sequence");
 
   add_setshow_enum_cmd ("interrupt-sequence", class_support,
diff --git a/gdb/top.c b/gdb/top.c
index be736b0a87..14bd5375fd 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -542,6 +542,11 @@ set_repeat_arguments (const char *args)
   repeat_arguments = args;
 }
 
+/* Flag for whether we want to use the configured leading args.
+   Default is yes.  */
+
+static int enable_leading_args_var = 1;
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -570,6 +575,8 @@ execute_command (const char *p, int from_tty)
     {
       const char *cmd = p;
       const char *arg;
+      const char *leading_args;
+      std::string leading_args_and_arg;
       int was_sync = current_ui->prompt_state == PROMPT_BLOCKED;
 
       line = p;
@@ -577,15 +584,28 @@ execute_command (const char *p, int from_tty)
       /* If trace-commands is set then this will print this command.  */
       print_command_trace ("%s", p);
 
-      c = lookup_cmd (&cmd, cmdlist, "", 0, 1);
+      c = lookup_cmd (&cmd, cmdlist, "", &leading_args, 0, 1);
       p = cmd;
 
       scoped_restore save_repeat_args
 	= make_scoped_restore (&repeat_arguments, nullptr);
       const char *args_pointer = p;
 
-      /* Pass null arg rather than an empty one.  */
-      arg = *p ? p : 0;
+      if (leading_args != nullptr && enable_leading_args_var)
+	{
+	  leading_args_and_arg = std::string (leading_args);
+	  if (*p)
+	    leading_args_and_arg = std::string (leading_args)
+	      + ' ' + std::string (p);
+	  else
+	    leading_args_and_arg = std::string (leading_args);
+	  arg = leading_args_and_arg.c_str ();
+	}
+      else
+	{
+	  /* Pass null arg rather than an empty one.  */
+	  arg = *p ? p : 0;
+	}
 
       /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy
          while the is_complete_command(cfunc) test is just plain
@@ -1896,7 +1916,7 @@ set_verbose (const char *args, int from_tty, struct cmd_list_element *c)
   const char *cmdname = "verbose";
   struct cmd_list_element *showcmd;
 
-  showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, 1);
+  showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, NULL, 1);
   gdb_assert (showcmd != NULL && showcmd != CMD_LIST_AMBIGUOUS);
 
   if (c->doc && c->doc_allocated)
@@ -2126,6 +2146,19 @@ EMACS-like or VI-like commands like control-P or ESC."),
 			   show_editing,
 			   &setlist, &showlist);
 
+  add_setshow_boolean_cmd ("enable-leading-args", class_support,
+			   &enable_leading_args_var, _("\
+Set whether GDB prepends leading args when running a command.\n\
+The leading args for a command are configured using\n\
+\"set leading-args COMMAND = LEADING-ARGS..."), _("\
+Show whether GDB prepends leading args when running a command."), _("\
+Use \"on\" to enable the usage of the configured leading args,\n\
+and \"off\" to disable it.\n\
+Without an argument, leading args usage is enabled."),
+			   NULL,
+			   NULL,
+			   &setlist, &showlist);
+
   add_setshow_boolean_cmd ("save", no_class, &write_history_p, _("\
 Set saving of the history record on exit."), _("\
 Show saving of the history record on exit."), _("\
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index af5dcd1e33..918a485b5e 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -651,7 +651,7 @@ validate_actionline (const char *line, struct breakpoint *b)
   if (*p == '#')		/* comment line */
     return;
 
-  c = lookup_cmd (&p, cmdlist, "", -1, 1);
+  c = lookup_cmd (&p, cmdlist, "", NULL, -1, 1);
   if (c == 0)
     error (_("`%s' is not a tracepoint action, or is ambiguous."), p);
 
@@ -1309,7 +1309,7 @@ encode_actions_1 (struct command_line *action,
       action_exp = action->line;
       action_exp = skip_spaces (action_exp);
 
-      cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+      cmd = lookup_cmd (&action_exp, cmdlist, "", NULL, -1, 1);
       if (cmd == 0)
 	error (_("Bad action list item: %s"), action_exp);
 
@@ -2679,7 +2679,7 @@ trace_dump_actions (struct command_line *action,
       if (*action_exp == '#')	/* comment line */
 	continue;
 
-      cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+      cmd = lookup_cmd (&action_exp, cmdlist, "", NULL, -1, 1);
       if (cmd == 0)
 	error (_("Bad action list item: %s"), action_exp);
 
