diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index a39ea22604..4e58ddc6d6 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1912,6 +1912,200 @@ show_max_user_call_depth (struct ui_file *file, int from_tty,
 		    value);
 }
 
+/* Returns the cmd_list_element in SHOWLIST corresponding to the first
+   argument of ARGV, which must contain one single value.
+   Throws an error if no value provided, or value not correct.
+   FNNAME is used in the error message.  */
+
+static cmd_list_element *
+setting_cmd (const char *fnname, struct cmd_list_element *showlist,
+	     int argc, struct value **argv)
+{
+  if (argc == 0)
+    error (_("You must provide an argument to %s"), fnname);
+  if (argc != 1)
+    error (_("You can only provide one argument to %s"), fnname);
+
+  struct type *type0 = check_typedef (value_type (argv[0]));
+
+  if (TYPE_CODE (type0) != TYPE_CODE_ARRAY
+      && TYPE_CODE (type0) != TYPE_CODE_STRING)
+    error (_("First argument of %s must be a string."), fnname);
+
+  const char *a0 = (const char *) value_contents (argv[0]);
+  cmd_list_element *cmd = lookup_cmd (&a0, showlist, "", -1, 0);
+
+  if (cmd == nullptr || cmd_type (cmd) != show_cmd)
+    error (_("First argument of %s must be a "
+	     "valid setting of the 'show' command."), fnname);
+
+  return cmd;
+}
+
+/* Builds a value from the show CMD.  */
+
+static struct value *
+value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
+{
+  switch (cmd->var_type)
+    {
+    case var_integer:
+      if (*(int *) cmd->var == INT_MAX)
+	return value_from_longest (builtin_type (gdbarch)->builtin_int,
+				   0);
+      else
+	return value_from_longest (builtin_type (gdbarch)->builtin_int,
+				   *(int *) cmd->var);
+    case var_zinteger:
+      return value_from_longest (builtin_type (gdbarch)->builtin_int,
+				 *(int *) cmd->var);
+    case var_boolean:
+      return value_from_longest (builtin_type (gdbarch)->builtin_int,
+				 *(bool *) cmd->var ? 1 : 0);
+    case var_zuinteger_unlimited:
+      return value_from_longest (builtin_type (gdbarch)->builtin_int,
+				 *(int *) cmd->var);
+    case var_auto_boolean:
+      {
+	int val;
+
+	switch (*(enum auto_boolean*) cmd->var)
+	  {
+	  case AUTO_BOOLEAN_TRUE:
+	    val = 1;
+	    break;
+	  case AUTO_BOOLEAN_FALSE:
+	    val = 0;
+	    break;
+	  case AUTO_BOOLEAN_AUTO:
+	    val = -1;
+	    break;
+	  default:
+	    gdb_assert_not_reached ("invalid var_auto_boolean");
+	  }
+	return value_from_longest (builtin_type (gdbarch)->builtin_int,
+				   val);
+      }
+    case var_uinteger:
+      if (*(unsigned int *) cmd->var == UINT_MAX)
+	return value_from_ulongest
+	  (builtin_type (gdbarch)->builtin_unsigned_int, 0);
+      else
+	return value_from_ulongest
+	  (builtin_type (gdbarch)->builtin_unsigned_int,
+	   *(unsigned int *) cmd->var);
+    case var_zuinteger:
+      return value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_int,
+				  *(unsigned int *) cmd->var);
+    case var_string:
+    case var_string_noescape:
+    case var_optional_filename:
+    case var_filename:
+    case var_enum:
+      if (*(char **) cmd->var)
+	return value_cstring (*(char **) cmd->var, strlen (*(char **) cmd->var),
+			      builtin_type (gdbarch)->builtin_char);
+      else
+	return value_cstring ("", 1,
+			      builtin_type (gdbarch)->builtin_char);
+    default:
+      gdb_assert_not_reached ("bad var_type");
+    }
+}
+
+/* Implementation of the convenience function $_gdb_setting.  */
+
+static struct value *
+gdb_setting_internal_fn (struct gdbarch *gdbarch,
+			 const struct language_defn *language,
+			 void *cookie, int argc, struct value **argv)
+{
+  return value_from_setting (setting_cmd ("$_gdb_setting", showlist,
+					  argc, argv),
+			     gdbarch);
+}
+
+/* Implementation of the convenience function $_gdb_maint_setting.  */
+
+static struct value *
+gdb_maint_setting_internal_fn (struct gdbarch *gdbarch,
+			       const struct language_defn *language,
+			       void *cookie, int argc, struct value **argv)
+{
+  return value_from_setting (setting_cmd ("$_gdb_maint_setting",
+					  maintenance_show_cmdlist,
+					  argc, argv),
+			     gdbarch);
+}
+
+/* Builds a string value from the show CMD.  */
+
+static struct value *
+str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
+{
+  switch (cmd->var_type)
+    {
+    case var_integer:
+    case var_zinteger:
+    case var_boolean:
+    case var_zuinteger_unlimited:
+    case var_auto_boolean:
+    case var_uinteger:
+    case var_zuinteger:
+      {
+	std::string cmd_val = get_setshow_command_value_string (cmd);
+
+	return value_cstring (cmd_val.c_str (), cmd_val.size (),
+			      builtin_type (gdbarch)->builtin_char);
+      }
+
+    case var_string:
+    case var_string_noescape:
+    case var_optional_filename:
+    case var_filename:
+    case var_enum:
+      /* For these cases, we do not use get_setshow_command_value_string,
+	 as this function handle some characters specially, e.g. by
+	 escaping quotes.  So, we directly use the cmd->var string value,
+	 similarly to the value_from_setting code for these cases.  */
+      if (*(char **) cmd->var)
+	return value_cstring (*(char **) cmd->var, strlen (*(char **) cmd->var),
+			      builtin_type (gdbarch)->builtin_char);
+      else
+	return value_cstring ("", 1,
+			      builtin_type (gdbarch)->builtin_char);
+
+    default:
+      gdb_assert_not_reached ("bad var_type");
+    }
+}
+
+/* Implementation of the convenience function $_gdb_setting_str.  */
+
+static struct value *
+gdb_setting_str_internal_fn (struct gdbarch *gdbarch,
+			     const struct language_defn *language,
+			     void *cookie, int argc, struct value **argv)
+{
+  return str_value_from_setting (setting_cmd ("$_gdb_setting_str",
+					      showlist, argc, argv),
+				 gdbarch);
+}
+
+
+/* Implementation of the convenience function $_gdb_maint_setting_str.  */
+
+static struct value *
+gdb_maint_setting_str_internal_fn (struct gdbarch *gdbarch,
+				   const struct language_defn *language,
+				   void *cookie, int argc, struct value **argv)
+{
+  return str_value_from_setting (setting_cmd ("$_gdb_maint_setting_str",
+					      maintenance_show_cmdlist,
+					      argc, argv),
+				 gdbarch);
+}
+
 void
 _initialize_cli_cmds (void)
 {
@@ -2053,6 +2247,44 @@ abbreviations for commands and/or values.  E.g.:\n\
   set_cmd_completer_handle_brkchars (c, with_command_completer);
   add_com_alias ("w", "with", class_vars, 1);
 
+  add_internal_function ("_gdb_setting_str", _("\
+$_gdb_setting_str - returns the value of a GDB setting as a string.\n\
+Usage: $_gdb_setting_str (setting)\n\
+\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as \"unlimited\"."),
+			 gdb_setting_str_internal_fn, NULL);
+
+  add_internal_function ("_gdb_setting", _("\
+$_gdb_setting - returns the value of a GDB setting.\n\
+Usage: $_gdb_setting (setting)\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as 0 or -1 depending on the setting."),
+			 gdb_setting_internal_fn, NULL);
+
+  add_internal_function ("_gdb_maint_setting_str", _("\
+$_gdb_maint_setting_str - returns the value of a GDB maintenance setting as a string.\n\
+Usage: $_gdb_maint_setting_str (setting)\n\
+\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as \"unlimited\"."),
+			 gdb_maint_setting_str_internal_fn, NULL);
+
+  add_internal_function ("_gdb_maint_setting", _("\
+$_gdb_maint_setting - returns the value of a GDB maintenance setting.\n\
+Usage: $_gdb_maint_setting (setting)\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as 0 or -1 depending on the setting."),
+			 gdb_maint_setting_internal_fn, NULL);
+
   add_cmd ("commands", no_set_class, show_commands, _("\
 Show the history of commands you typed.\n\
 You can supply a command number to start with, or a `+' to start after\n\
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
index d8391597ac..4cf2437e2a 100644
--- a/gdb/cli/cli-setshow.c
+++ b/gdb/cli/cli-setshow.c
@@ -627,7 +627,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
 /* See cli/cli-setshow.h.  */
 
 std::string
-get_setshow_command_value_string (cmd_list_element *c)
+get_setshow_command_value_string (const cmd_list_element *c)
 {
   string_file stb;
 
diff --git a/gdb/cli/cli-setshow.h b/gdb/cli/cli-setshow.h
index 8bfe7e89f0..dbb3e9fdff 100644
--- a/gdb/cli/cli-setshow.h
+++ b/gdb/cli/cli-setshow.h
@@ -58,7 +58,7 @@ extern void do_show_command (const char *arg, int from_tty,
 			     struct cmd_list_element *c);
 
 /* Get a string version of C's current value.  */
-extern std::string get_setshow_command_value_string (cmd_list_element *c);
+extern std::string get_setshow_command_value_string (const cmd_list_element *c);
 
 extern void cmd_show_list (struct cmd_list_element *list, int from_tty,
 			   const char *prefix);
