Blame SOURCES/github_0f65ae0c_readline.patch

608733
commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe
608733
Author: Dave Anderson <anderson@redhat.com>
608733
Date:   Fri Dec 7 15:17:37 2018 -0500
608733
608733
    Implemented a new plugin function for the readline library's tab
608733
    completion feature.  Without the patch, the use of the default plugin
608733
    from the embedded gdb module has been seen to cause segmentation
608733
    violations or other fatal malloc/free/corruption assertions.  The new
608733
    plugin takes gdb out of the picture entirely, and also restricts the
608733
    matching options to just symbol names, so as not to clutter the
608733
    results with irrelevant filenames.
608733
    (anderson@redhat.com)
608733
608733
diff --git a/cmdline.c b/cmdline.c
608733
index cf3e150..665f48c 100644
608733
--- a/cmdline.c
608733
+++ b/cmdline.c
608733
@@ -40,6 +40,8 @@ int shell_command(char *);
608733
 static void modify_orig_line(char *, struct args_input_file *);
608733
 static void modify_expression_arg(char *, char **, struct args_input_file *);
608733
 static int verify_args_input_file(char *);
608733
+static char *crash_readline_completion_generator(const char *, int);
608733
+static char **crash_readline_completer(const char *, int, int);
608733
 
608733
 #define READLINE_LIBRARY
608733
 
608733
@@ -2073,6 +2075,9 @@ readline_init(void)
608733
 	if (STREQ(pc->editing_mode, "emacs")) {
608733
         	rl_editing_mode = emacs_mode;
608733
 	}
608733
+
608733
+	rl_attempted_completion_function = crash_readline_completer;
608733
+	rl_attempted_completion_over = 1;
608733
 }
608733
 
608733
 /*
608733
@@ -2610,3 +2615,27 @@ exec_args_input_file(struct command_table_entry *ct, struct args_input_file *aif
608733
 	fclose(pc->args_ifile);
608733
 	pc->args_ifile = NULL;
608733
 }
608733
+
608733
+static char *
608733
+crash_readline_completion_generator(const char *match, int state)
608733
+{
608733
+	static struct syment *sp_match;
608733
+
608733
+	if (state == 0)
608733
+		sp_match = NULL;
608733
+
608733
+	sp_match = symbol_complete_match(match, sp_match);
608733
+
608733
+	if (sp_match)
608733
+		return(strdup(sp_match->name));
608733
+	else
608733
+		return NULL;
608733
+}
608733
+
608733
+static char **
608733
+crash_readline_completer(const char *match, int start, int end)
608733
+{
608733
+	rl_attempted_completion_over = 1;
608733
+	return rl_completion_matches(match, crash_readline_completion_generator);
608733
+}
608733
+
608733
diff --git a/defs.h b/defs.h
608733
index 9ce32c1..a3cb5a4 100644
608733
--- a/defs.h
608733
+++ b/defs.h
608733
@@ -5153,6 +5153,7 @@ void parse_for_member_extended(struct datatype_member *, ulong);
608733
 void add_to_downsized(char *);
608733
 int is_downsized(char *);
608733
 int is_string(char *, char *);
608733
+struct syment *symbol_complete_match(const char *, struct syment *);
608733
 
608733
 /*  
608733
  *  memory.c 
608733
diff --git a/symbols.c b/symbols.c
608733
index 05628ff..0769294 100644
608733
--- a/symbols.c
608733
+++ b/symbols.c
608733
@@ -13108,3 +13108,73 @@ is_downsized(char *name)
608733
 
608733
 	return FALSE;
608733
 }
608733
+
608733
+struct syment *
608733
+symbol_complete_match(const char *match, struct syment *sp_last)
608733
+{
608733
+	int i;
608733
+	struct syment *sp, *sp_end, *sp_start;
608733
+	struct load_module *lm;
608733
+	int search_init;
608733
+
608733
+	if (sp_last) {
608733
+		sp_start = next_symbol(NULL, sp_last);
608733
+		if (!sp_start)
608733
+			return NULL;
608733
+	} else	
608733
+		sp_start = st->symtable;
608733
+
608733
+	if ((sp_start >= st->symtable) && (sp_start < st->symend)) {
608733
+		for (sp = sp_start; sp < st->symend; sp++) {
608733
+			if (STRNEQ(sp->name, match))
608733
+				return sp;
608733
+		}
608733
+		sp_start = NULL;
608733
+	}
608733
+
608733
+	search_init = FALSE;
608733
+
608733
+	for (i = 0; i < st->mods_installed; i++) {
608733
+		lm = &st->load_modules[i];
608733
+		if (lm->mod_flags & MOD_INIT)
608733
+			search_init = TRUE;
608733
+		sp_end = lm->mod_symend;
608733
+		if (!sp_start)
608733
+			sp_start = lm->mod_symtable;
608733
+
608733
+		if ((sp_start >= lm->mod_symtable) && (sp_start < sp_end)) {
608733
+			for (sp = sp_start; sp < sp_end; sp++) {
608733
+				if (MODULE_START(sp))
608733
+					continue;
608733
+	
608733
+				if (STRNEQ(sp->name, match))
608733
+					return sp;
608733
+			}
608733
+			sp_start = NULL;
608733
+		}
608733
+	}
608733
+
608733
+	if (!search_init)
608733
+		return NULL;
608733
+	
608733
+	for (i = 0; i < st->mods_installed; i++) {
608733
+		lm = &st->load_modules[i];
608733
+		if (!lm->mod_init_symtable)
608733
+			continue;
608733
+		sp_end = lm->mod_init_symend;
608733
+		if (!sp_start)
608733
+			sp_start = lm->mod_init_symtable;
608733
+
608733
+		if ((sp_start >= lm->mod_init_symtable) && (sp_start < sp_end)) {
608733
+			for (sp = sp_start; sp < sp_end; sp++) {
608733
+				if (MODULE_START(sp))
608733
+					continue;
608733
+	
608733
+				if (STRNEQ(sp->name, match))
608733
+					return sp;
608733
+			}
608733
+		}
608733
+	}
608733
+
608733
+	return NULL;
608733
+}