diff --git a/.crash.metadata b/.crash.metadata
new file mode 100644
index 0000000..d966af7
--- /dev/null
+++ b/.crash.metadata
@@ -0,0 +1 @@
+1a9fa8cd6869da42314ec47df6a750e053f4bece SOURCES/crash-7.2.3.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..32212ef
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/crash-7.2.3.tar.gz
diff --git a/SOURCES/github_0f65ae0c_readline.patch b/SOURCES/github_0f65ae0c_readline.patch
new file mode 100644
index 0000000..73d317a
--- /dev/null
+++ b/SOURCES/github_0f65ae0c_readline.patch
@@ -0,0 +1,154 @@
+commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Dec 7 15:17:37 2018 -0500
+
+    Implemented a new plugin function for the readline library's tab
+    completion feature.  Without the patch, the use of the default plugin
+    from the embedded gdb module has been seen to cause segmentation
+    violations or other fatal malloc/free/corruption assertions.  The new
+    plugin takes gdb out of the picture entirely, and also restricts the
+    matching options to just symbol names, so as not to clutter the
+    results with irrelevant filenames.
+    (anderson@redhat.com)
+
+diff --git a/cmdline.c b/cmdline.c
+index cf3e150..665f48c 100644
+--- a/cmdline.c
++++ b/cmdline.c
+@@ -40,6 +40,8 @@ int shell_command(char *);
+ static void modify_orig_line(char *, struct args_input_file *);
+ static void modify_expression_arg(char *, char **, struct args_input_file *);
+ static int verify_args_input_file(char *);
++static char *crash_readline_completion_generator(const char *, int);
++static char **crash_readline_completer(const char *, int, int);
+ 
+ #define READLINE_LIBRARY
+ 
+@@ -2073,6 +2075,9 @@ readline_init(void)
+ 	if (STREQ(pc->editing_mode, "emacs")) {
+         	rl_editing_mode = emacs_mode;
+ 	}
++
++	rl_attempted_completion_function = crash_readline_completer;
++	rl_attempted_completion_over = 1;
+ }
+ 
+ /*
+@@ -2610,3 +2615,27 @@ exec_args_input_file(struct command_table_entry *ct, struct args_input_file *aif
+ 	fclose(pc->args_ifile);
+ 	pc->args_ifile = NULL;
+ }
++
++static char *
++crash_readline_completion_generator(const char *match, int state)
++{
++	static struct syment *sp_match;
++
++	if (state == 0)
++		sp_match = NULL;
++
++	sp_match = symbol_complete_match(match, sp_match);
++
++	if (sp_match)
++		return(strdup(sp_match->name));
++	else
++		return NULL;
++}
++
++static char **
++crash_readline_completer(const char *match, int start, int end)
++{
++	rl_attempted_completion_over = 1;
++	return rl_completion_matches(match, crash_readline_completion_generator);
++}
++
+diff --git a/defs.h b/defs.h
+index 9ce32c1..a3cb5a4 100644
+--- a/defs.h
++++ b/defs.h
+@@ -5153,6 +5153,7 @@ void parse_for_member_extended(struct datatype_member *, ulong);
+ void add_to_downsized(char *);
+ int is_downsized(char *);
+ int is_string(char *, char *);
++struct syment *symbol_complete_match(const char *, struct syment *);
+ 
+ /*  
+  *  memory.c 
+diff --git a/symbols.c b/symbols.c
+index 05628ff..0769294 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -13108,3 +13108,73 @@ is_downsized(char *name)
+ 
+ 	return FALSE;
+ }
++
++struct syment *
++symbol_complete_match(const char *match, struct syment *sp_last)
++{
++	int i;
++	struct syment *sp, *sp_end, *sp_start;
++	struct load_module *lm;
++	int search_init;
++
++	if (sp_last) {
++		sp_start = next_symbol(NULL, sp_last);
++		if (!sp_start)
++			return NULL;
++	} else	
++		sp_start = st->symtable;
++
++	if ((sp_start >= st->symtable) && (sp_start < st->symend)) {
++		for (sp = sp_start; sp < st->symend; sp++) {
++			if (STRNEQ(sp->name, match))
++				return sp;
++		}
++		sp_start = NULL;
++	}
++
++	search_init = FALSE;
++
++	for (i = 0; i < st->mods_installed; i++) {
++		lm = &st->load_modules[i];
++		if (lm->mod_flags & MOD_INIT)
++			search_init = TRUE;
++		sp_end = lm->mod_symend;
++		if (!sp_start)
++			sp_start = lm->mod_symtable;
++
++		if ((sp_start >= lm->mod_symtable) && (sp_start < sp_end)) {
++			for (sp = sp_start; sp < sp_end; sp++) {
++				if (MODULE_START(sp))
++					continue;
++	
++				if (STRNEQ(sp->name, match))
++					return sp;
++			}
++			sp_start = NULL;
++		}
++	}
++
++	if (!search_init)
++		return NULL;
++	
++	for (i = 0; i < st->mods_installed; i++) {
++		lm = &st->load_modules[i];
++		if (!lm->mod_init_symtable)
++			continue;
++		sp_end = lm->mod_init_symend;
++		if (!sp_start)
++			sp_start = lm->mod_init_symtable;
++
++		if ((sp_start >= lm->mod_init_symtable) && (sp_start < sp_end)) {
++			for (sp = sp_start; sp < sp_end; sp++) {
++				if (MODULE_START(sp))
++					continue;
++	
++				if (STRNEQ(sp->name, match))
++					return sp;
++			}
++		}
++	}
++
++	return NULL;
++}
diff --git a/SOURCES/github_1926150e_ppc64_stacksize.patch b/SOURCES/github_1926150e_ppc64_stacksize.patch
new file mode 100644
index 0000000..5da09da
--- /dev/null
+++ b/SOURCES/github_1926150e_ppc64_stacksize.patch
@@ -0,0 +1,27 @@
+commit 1926150ee350e17fee2aeabb8ef781222d94366e
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Jun 11 13:46:41 2018 -0400
+
+    Fix for the ppc64/ppc64le "bt" command on Linux 4.7 and later kernels
+    that contain commit d8bff643d81a58181356c0aa3ab771ac10da6894,
+    titled "[x86] asm: Make sure verify_cpu() has a good stack", which
+    inadvertently breaks the ppc64/ppc64le kernel stack size calculation
+    when running with crash-7.2.2 or later.  Without the patch, "bt" may
+    fail with a filtered kdump dumpfile with the two error messages
+    "bt: page excluded: kernel virtual address: <address> type: stack
+    contents" and "bt: read of stack at <address> failed".
+    (anderson@redhat.com)
+
+diff --git a/task.c b/task.c
+index f6956d5..1b32629 100644
+--- a/task.c
++++ b/task.c
+@@ -440,7 +440,7 @@ task_init(void)
+ 	} else if (VALID_SIZE(thread_union) && 
+ 	    	((len = SIZE(thread_union)) != STACKSIZE())) {
+ 		machdep->stacksize = len;
+-	} else {
++	} else if (!VALID_SIZE(thread_union) && !VALID_SIZE(task_union)) {
+ 		if (kernel_symbol_exists("__start_init_task") &&
+ 		    kernel_symbol_exists("__end_init_task")) {
+ 			len = symbol_value("__end_init_task");
diff --git a/SOURCES/github_27a6ebd0_dev-p.patch b/SOURCES/github_27a6ebd0_dev-p.patch
new file mode 100644
index 0000000..0cbafcc
--- /dev/null
+++ b/SOURCES/github_27a6ebd0_dev-p.patch
@@ -0,0 +1,412 @@
+commit 27a6ebd0cda386b1dfb7b0fffb4d8b489b391ccf
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Sep 24 16:33:57 2018 -0400
+
+    Resurrection of the the "dev -p" option for displaying PCI device
+    data on Linux 2.6.26 and later kernels.  The option was deprecated
+    as of Linux 2.6.26, and without the patch, the option would indicate
+    "dev: -p option not supported or applicable on this architecture
+    or kernel" when running against the newer kernel versions.  PCI Bus
+    information will also be displayed with this patch.
+    (m.mizuma@jp.fujitsu.com)
+
+diff --git a/defs.h b/defs.h
+index d6492c5..80c61ef 100644
+--- a/defs.h
++++ b/defs.h
+@@ -2032,6 +2032,17 @@ struct offset_table {
+ 	long bpf_prog_aux_user;
+ 	long user_struct_uid;
+ 	long idr_cur;
++        long pci_dev_dev;
++        long pci_dev_hdr_type;
++        long pci_dev_pcie_flags_reg;
++        long pci_bus_node;
++        long pci_bus_devices;
++        long pci_bus_dev;
++        long pci_bus_children;
++        long pci_bus_parent;
++        long pci_bus_self;
++        long device_kobj;
++        long kobject_name;
+ };
+ 
+ struct size_table {         /* stash of commonly-used sizes */
+diff --git a/dev.c b/dev.c
+index 3db898a..7ce2422 100644
+--- a/dev.c
++++ b/dev.c
+@@ -24,6 +24,7 @@ static void dump_blkdevs_v3(ulong);
+ static ulong search_cdev_map_probes(char *, int, int, ulong *);
+ static ulong search_bdev_map_probes(char *, int, int, ulong *);
+ static void do_pci(void); 
++static void do_pci2(void);
+ static void do_io(void);
+ static void do_resource_list(ulong, char *, int);
+ 
+@@ -51,11 +52,23 @@ dev_init(void)
+         MEMBER_OFFSET_INIT(pci_dev_global_list, "pci_dev", "global_list");
+         MEMBER_OFFSET_INIT(pci_dev_next, "pci_dev", "next");
+         MEMBER_OFFSET_INIT(pci_dev_bus, "pci_dev", "bus");
++	MEMBER_OFFSET_INIT(pci_dev_dev, "pci_dev", "dev");
+         MEMBER_OFFSET_INIT(pci_dev_devfn, "pci_dev", "devfn");
+         MEMBER_OFFSET_INIT(pci_dev_class, "pci_dev", "class");
+         MEMBER_OFFSET_INIT(pci_dev_device, "pci_dev", "device");
++	MEMBER_OFFSET_INIT(pci_dev_hdr_type, "pci_dev", "hdr_type");
++	MEMBER_OFFSET_INIT(pci_dev_pcie_flags_reg, "pci_dev", "pcie_flags_reg");
+         MEMBER_OFFSET_INIT(pci_dev_vendor, "pci_dev", "vendor");
+ 	MEMBER_OFFSET_INIT(pci_bus_number, "pci_bus", "number");
++	MEMBER_OFFSET_INIT(pci_bus_node, "pci_bus", "node");
++	MEMBER_OFFSET_INIT(pci_bus_devices, "pci_bus", "devices");
++	MEMBER_OFFSET_INIT(pci_bus_dev, "pci_bus", "dev");
++	MEMBER_OFFSET_INIT(pci_bus_children, "pci_bus", "children");
++	MEMBER_OFFSET_INIT(pci_bus_parent, "pci_bus", "parent");
++	MEMBER_OFFSET_INIT(pci_bus_self, "pci_bus", "self");
++
++	MEMBER_OFFSET_INIT(device_kobj, "device", "kobj");
++	MEMBER_OFFSET_INIT(kobject_name, "kobject", "name");
+ 
+         STRUCT_SIZE_INIT(resource, "resource");
+ 	if ((VALID_STRUCT(resource) && symbol_exists("do_resource_list")) ||
+@@ -114,10 +127,14 @@ cmd_dev(void)
+ 			return;
+ 
+ 		case 'p':
+-			if (machine_type("S390X") ||
+-			    (THIS_KERNEL_VERSION >= LINUX(2,6,26)))
++			if (machine_type("S390X"))
++				option_not_supported(c);
++			if (symbol_exists("pci_devices"))
++				do_pci();
++			else if (symbol_exists("pci_root_buses"))
++				do_pci2();
++			else
+ 				option_not_supported(c);
+-			do_pci();
+ 			return;
+ 
+                 default:
+@@ -2217,6 +2234,313 @@ do_resource_list(ulong first_entry, char *resource_buf, int size)
+ 
+ #endif /* USE_2_2_17_PCI_H */
+ 
++#define PCI_EXP_FLAGS_TYPE      0x00f0  /* Device/Port type */
++#define  PCI_EXP_TYPE_ENDPOINT  0x0     /* Express Endpoint */
++#define  PCI_EXP_TYPE_LEG_END   0x1     /* Legacy Endpoint */
++#define  PCI_EXP_TYPE_ROOT_PORT 0x4     /* Root Port */
++#define  PCI_EXP_TYPE_UPSTREAM  0x5     /* Upstream Port */
++#define  PCI_EXP_TYPE_DOWNSTREAM 0x6    /* Downstream Port */
++#define  PCI_EXP_TYPE_PCI_BRIDGE 0x7    /* PCIe to PCI/PCI-X Bridge */
++#define  PCI_EXP_TYPE_PCIE_BRIDGE 0x8   /* PCI/PCI-X to PCIe Bridge */
++#define  PCI_EXP_TYPE_RC_END    0x9     /* Root Complex Integrated Endpoint */
++#define  PCI_EXP_TYPE_RC_EC     0xa     /* Root Complex Event Collector */
++
++static void
++fill_dev_name(ulong pci_dev, char *name)
++{
++	ulong kobj, value;
++
++	memset(name, 0, sizeof(*name) * BUFSIZE);
++
++	kobj = pci_dev + OFFSET(pci_dev_dev) + OFFSET(device_kobj);
++
++	readmem(kobj + OFFSET(kobject_name),
++		KVADDR, &value, sizeof(void *), "kobject name",
++		FAULT_ON_ERROR);
++
++	read_string(value, name, BUFSIZE-1);
++}
++
++static void
++fill_bus_name(ulong pci_bus, char *name)
++{
++	ulong kobj, value;
++
++	memset(name, 0, sizeof(*name) * BUFSIZE);
++
++	kobj = pci_bus + OFFSET(pci_bus_dev) + OFFSET(device_kobj);
++
++	readmem(kobj + OFFSET(kobject_name),
++		KVADDR, &value, sizeof(void *), "kobject name",
++		FAULT_ON_ERROR);
++
++	read_string(value, name, BUFSIZE-1);
++}
++
++static void
++fill_dev_id(ulong pci_dev, char *id)
++{
++	unsigned short device, vendor;
++
++	memset(id, 0, sizeof(*id) * BUFSIZE);
++
++	readmem(pci_dev + OFFSET(pci_dev_device),
++		KVADDR, &device, sizeof(short), "pci dev device",
++		FAULT_ON_ERROR);
++	readmem(pci_dev + OFFSET(pci_dev_vendor), KVADDR,
++		&vendor, sizeof(short), "pci dev vendor", FAULT_ON_ERROR);
++
++	sprintf(id, "%x:%x", vendor, device);
++}
++
++static void
++fill_dev_class(ulong pci_dev, char *c)
++{
++	unsigned int class;
++
++	memset(c, 0, sizeof(*c) * BUFSIZE);
++	readmem(pci_dev + OFFSET(pci_dev_class), KVADDR,
++		&class, sizeof(int), "pci class", FAULT_ON_ERROR);
++
++	class >>= 8;
++
++	sprintf(c, "%04x", class);
++}
++
++static int
++pci_pcie_type(ulong cap)
++{
++	return (cap & PCI_EXP_FLAGS_TYPE) >> 4;
++}
++
++static int
++pci_is_bridge(unsigned char hdr_type)
++{
++	return hdr_type == PCI_HEADER_TYPE_BRIDGE ||
++		hdr_type == PCI_HEADER_TYPE_CARDBUS;
++}
++
++static void
++fill_pcie_type(ulong pcidev, char *t)
++{
++	int type, bufidx = 0;
++	unsigned short pciecap;
++	unsigned char hdr_type;
++
++	memset(t, 0, sizeof(*t) * BUFSIZE);
++
++	readmem(pcidev + OFFSET(pci_dev_hdr_type), KVADDR, &hdr_type,
++		sizeof(char), "pci dev hdr_type", FAULT_ON_ERROR);
++
++	if (!VALID_MEMBER(pci_dev_pcie_flags_reg))
++		goto bridge_chk;
++
++	readmem(pcidev + OFFSET(pci_dev_pcie_flags_reg), KVADDR, &pciecap,
++		sizeof(unsigned short), "pci dev pcie_flags_reg", FAULT_ON_ERROR);
++
++	type = pci_pcie_type(pciecap);
++
++	if (type == PCI_EXP_TYPE_ENDPOINT)
++		bufidx = sprintf(t, "ENDPOINT");
++	else if (type == PCI_EXP_TYPE_LEG_END)
++		bufidx = sprintf(t, "LEG_END");
++	else if (type == PCI_EXP_TYPE_ROOT_PORT)
++		bufidx = sprintf(t, "ROOT_PORT");
++	else if (type == PCI_EXP_TYPE_UPSTREAM)
++		bufidx = sprintf(t, "UPSTREAM");
++	else if (type == PCI_EXP_TYPE_DOWNSTREAM)
++		bufidx = sprintf(t, "DOWNSTREAM");
++	else if (type == PCI_EXP_TYPE_PCI_BRIDGE)
++		bufidx = sprintf(t, "PCI_BRIDGE");
++	else if (type == PCI_EXP_TYPE_PCIE_BRIDGE)
++		bufidx = sprintf(t, "PCIE_BRIDGE");
++	else if (type == PCI_EXP_TYPE_RC_END)
++		bufidx = sprintf(t, "RC_END");
++	else if (type == PCI_EXP_TYPE_RC_EC)
++		bufidx = sprintf(t, "RC_EC");
++
++bridge_chk:
++	if (pci_is_bridge(hdr_type))
++		sprintf(t + bufidx, " [BRIDGE]");
++}
++
++static void
++walk_devices(ulong pci_bus)
++{
++	struct list_data list_data, *ld;
++	int devcnt, i;
++	ulong *devlist, self;
++	char name[BUFSIZE], class[BUFSIZE], id[BUFSIZE], type[BUFSIZE];
++	char pcidev_hdr[BUFSIZE];
++	char buf1[BUFSIZE];
++	char buf2[BUFSIZE];
++	char buf3[BUFSIZE];
++	char buf4[BUFSIZE];
++	char buf5[BUFSIZE];
++
++	ld = &list_data;
++
++	BZERO(ld, sizeof(struct list_data));
++
++	readmem(pci_bus + OFFSET(pci_bus_devices), KVADDR,
++		&ld->start, sizeof(void *), "pci bus devices",
++		FAULT_ON_ERROR);
++
++	if (VALID_MEMBER(pci_dev_pcie_flags_reg))
++		snprintf(pcidev_hdr, sizeof(pcidev_hdr), "%s %s %s %s %s\n",
++			mkstring(buf1, VADDR_PRLEN, CENTER, "PCI DEV"),
++			mkstring(buf2, strlen("0000:00:00.0"), CENTER, "DO:BU:SL.FN"),
++			mkstring(buf3, strlen("0000") + 2, CENTER, "CLASS"),
++			mkstring(buf4, strlen("0000:0000"), CENTER, "PCI_ID"),
++			mkstring(buf5, 10, CENTER, "TYPE"));
++	else
++		snprintf(pcidev_hdr, sizeof(pcidev_hdr), "%s %s %s %s\n",
++			mkstring(buf1, VADDR_PRLEN, CENTER, "PCI DEV"),
++			mkstring(buf2, strlen("0000:00:00.0"), CENTER, "DO:BU:SL.FN"),
++			mkstring(buf3, strlen("0000") + 2, CENTER, "CLASS"),
++			mkstring(buf4, strlen("0000:0000"), CENTER, "PCI_ID"));
++
++	fprintf(fp, "  %s", pcidev_hdr);
++
++	readmem(pci_bus + OFFSET(pci_bus_self), KVADDR, &self,
++		sizeof(void *), "pci bus self", FAULT_ON_ERROR);
++	if (self) {
++		fill_dev_name(self, name);
++		fill_dev_class(self, class);
++		fill_dev_id(self, id);
++		fill_pcie_type(self, type);
++		fprintf(fp, "  %s %s %s %s %s\n",
++			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
++			MKSTR(self)),
++			mkstring(buf2, strlen("0000:00:00.0"), CENTER, name),
++			mkstring(buf3, strlen("0000") + 2, CENTER, class),
++			mkstring(buf4, strlen("0000:0000"), CENTER, id),
++			mkstring(buf5, 10, CENTER, type));
++	}
++
++	if (ld->start == (pci_bus + OFFSET(pci_bus_devices)))
++		return;
++
++	ld->end = pci_bus + OFFSET(pci_bus_devices);
++	hq_open();
++	devcnt = do_list(ld);
++	devlist = (ulong *)GETBUF(devcnt * sizeof(ulong));
++	devcnt = retrieve_list(devlist, devcnt);
++	hq_close();
++
++	for (i = 0; i < devcnt; i++) {
++		fill_dev_name(devlist[i], name);
++		fill_dev_class(devlist[i], class);
++		fill_dev_id(devlist[i], id);
++		fill_pcie_type(devlist[i], type);
++		fprintf(fp, "  %s %s %s %s %s\n",
++			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
++			MKSTR(devlist[i])),
++			mkstring(buf2, strlen("0000:00:00.0"), CENTER, name),
++			mkstring(buf3, strlen("0000") + 2, CENTER, class),
++			mkstring(buf4, strlen("0000:0000"), CENTER, id),
++			mkstring(buf5, 10, CENTER, type));
++	}
++	FREEBUF(devlist);
++}
++
++static void
++walk_buses(ulong pci_bus)
++{
++	struct list_data list_data, *ld;
++	int buscnt, i;
++	ulong *buslist, parent;
++	char pcibus_hdr[BUFSIZE];
++	char buf1[BUFSIZE];
++	char buf2[BUFSIZE];
++
++	ld = &list_data;
++
++	BZERO(ld, sizeof(struct list_data));
++
++	readmem(pci_bus + OFFSET(pci_bus_children), KVADDR,
++		&ld->start, sizeof(void *), "pci bus children",
++		FAULT_ON_ERROR);
++
++	if (ld->start == (pci_bus + OFFSET(pci_bus_children)))
++		return;
++
++	ld->end = pci_bus + OFFSET(pci_bus_children);
++	hq_open();
++	buscnt = do_list(ld);
++	buslist = (ulong *)GETBUF(buscnt * sizeof(ulong));
++	buscnt = retrieve_list(buslist, buscnt);
++	hq_close();
++
++	snprintf(pcibus_hdr, sizeof(pcibus_hdr), "%s %s\n",
++		mkstring(buf1, VADDR_PRLEN, CENTER, "PCI BUS"),
++		mkstring(buf2, VADDR_PRLEN, CENTER, "PARENT BUS"));
++
++	for (i = 0; i < buscnt; i++) {
++		readmem(buslist[i] + OFFSET(pci_bus_parent), KVADDR, &parent,
++			sizeof(void *), "pci bus parent", FAULT_ON_ERROR);
++
++		fprintf(fp, "  %s", pcibus_hdr);
++
++		fprintf(fp, "  %s %s\n",
++			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
++			MKSTR(buslist[i])),
++			mkstring(buf2, VADDR_PRLEN, LJUST|LONG_HEX,
++			MKSTR(parent)));
++		walk_devices(buslist[i]);
++		fprintf(fp, "\n");
++		walk_buses(buslist[i]);
++	}
++	FREEBUF(buslist);
++}
++
++static void
++do_pci2(void)
++{
++	struct list_data list_data, *ld;
++	int rootbuscnt, i;
++	ulong *rootbuslist;
++	unsigned long pci_root_bus_addr = symbol_value("pci_root_buses");
++	char name[BUFSIZE];
++	char pcirootbus_hdr[BUFSIZE];
++	char buf1[BUFSIZE];
++	char buf2[BUFSIZE];
++
++	ld = &list_data;
++	BZERO(ld, sizeof(struct list_data));
++
++	get_symbol_data("pci_root_buses", sizeof(void *), &ld->start);
++
++	if (ld->start == pci_root_bus_addr)
++		error(FATAL, "no PCI devices found on this system.\n");
++
++	ld->end = pci_root_bus_addr;
++
++	hq_open();
++	rootbuscnt = do_list(ld);
++	rootbuslist = (ulong *)GETBUF(rootbuscnt * sizeof(ulong));
++	rootbuscnt = retrieve_list(rootbuslist, rootbuscnt);
++	hq_close();
++
++	snprintf(pcirootbus_hdr, sizeof(pcirootbus_hdr), "%s %s\n",
++			mkstring(buf1, VADDR_PRLEN, CENTER, "ROOT BUS"),
++			mkstring(buf2, strlen("0000:00"), CENTER, "BUSNAME"));
++
++	for (i = 0; i < rootbuscnt; i++) {
++		fprintf(fp, "%s", pcirootbus_hdr);
++		fill_bus_name(rootbuslist[i], name);
++		fprintf(fp, "%s %s\n",
++			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
++			MKSTR(rootbuslist[i])),
++			mkstring(buf2, strlen("0000:00"), CENTER, name));
++		 walk_devices(rootbuslist[i]);
++		 walk_buses(rootbuslist[i]);
++
++		fprintf(fp, "\n");
++	}
++	FREEBUF(rootbuslist);
++}
++
+ static void
+ do_pci(void)
+ {
+@@ -2230,9 +2554,6 @@ do_pci(void)
+ 	char 		  buf2[BUFSIZE];
+ 	char 		  buf3[BUFSIZE];
+ 
+-	if (!symbol_exists("pci_devices"))
+-		error(FATAL, "no PCI devices found on this system.\n");
+-
+ 	BZERO(&pcilist_data, sizeof(struct list_data));
+ 
+ 	if (VALID_MEMBER(pci_dev_global_list)) {
diff --git a/SOURCES/github_28fa7bd0_to_02efd083.patch b/SOURCES/github_28fa7bd0_to_02efd083.patch
new file mode 100644
index 0000000..177c106
--- /dev/null
+++ b/SOURCES/github_28fa7bd0_to_02efd083.patch
@@ -0,0 +1,174 @@
+commit 28fa7bd09013455b5ddc020dea4706278cda0d65
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue Jun 19 16:31:54 2018 -0400
+
+    Fix for PPC64 kernel virtual address translation in Linux 4.17 and
+    later kernels with commit c2b4d8b7417a59b7f9a52d0d8402f5257cbbd398,
+    titled "powerpc/mm/hash64: Increase the VA range", in which the
+    maximum virtual address value has been increased to 4PB.  Without
+    the patch, the translation/access of high vmalloc space addresses
+    fails; for example, the "kmem -[sS]" option fails the translation
+    of per-cpu kmem_cache_cpu addresses located in vmalloc space, with
+    the error messages "kmem: invalid kernel virtual address: <address>
+    type: kmem_cache_cpu.freelist" and "kmem: invalid kernel virtual
+    address: <address>  type: kmem_cache_cpu.page", and the "vtop"
+    command shows the addresses as "(not mapped)".
+    (hbathini@linux.ibm.com)
+
+diff --git a/defs.h b/defs.h
+index 6e6f6be..e6e3850 100644
+--- a/defs.h
++++ b/defs.h
+@@ -3977,6 +3977,7 @@ struct efi_memory_desc_t {
+ #define PMD_INDEX_SIZE_L4_64K_4_12 10
+ #define PUD_INDEX_SIZE_L4_64K_4_12 7
+ #define PGD_INDEX_SIZE_L4_64K_4_12 8
++#define PUD_INDEX_SIZE_L4_64K_4_17 10
+ #define PTE_INDEX_SIZE_RADIX_64K  5
+ #define PMD_INDEX_SIZE_RADIX_64K  9
+ #define PUD_INDEX_SIZE_RADIX_64K  9
+diff --git a/ppc64.c b/ppc64.c
+index 0dd8a2a..f5d0dac 100644
+--- a/ppc64.c
++++ b/ppc64.c
+@@ -451,7 +451,10 @@ ppc64_init(int when)
+ 
+ 					if (THIS_KERNEL_VERSION >= LINUX(4,12,0)) {
+ 						m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
+-						m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
++						if (THIS_KERNEL_VERSION >= LINUX(4,17,0))
++							m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_17;
++						else
++							m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
+ 						m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
+ 					} else {
+ 						m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
+
+commit e5df29d54bbdb8b84cb1661233ed186b153be746
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Jun 20 11:15:38 2018 -0400
+
+    Fix for the x86_64 "bt" command in which a legitimate exception
+    frame is appended with the message "bt: WARNING: possibly bogus
+    exception frame".  This only happens in KASLR-enabled kernels when
+    the text address that was executing when the exception occurred
+    is marked as a "weak" symbol (type "W") instead of a text symbol
+    (type "T" or "t").  As a result, the exception frame's RIP is not
+    recognized as a text symbol, and the warning message is displayed.
+    (anderson@redhat.com)
+
+diff --git a/symbols.c b/symbols.c
+index bb4ae3a..bf55319 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -2755,9 +2755,14 @@ is_kernel_text(ulong value)
+ 					section);
+ 				end = start + (ulong)bfd_section_size(st->bfd, 
+ 					section);
++
++				if (kt->flags2 & KASLR) {
++					start += (kt->relocate * -1);
++					end += (kt->relocate * -1);
++				}
+ 	
+-	        		if ((value >= start) && (value < end)) 
+-	                		return TRUE;
++				if ((value >= start) && (value < end)) 
++					return TRUE;
+ 			}
+ 		}
+ 	}
+@@ -2833,7 +2838,16 @@ is_kernel_text_offset(ulong value)
+ int
+ is_symbol_text(struct syment *sp)
+ {
+-	return ((sp->type == 'T') || (sp->type == 't'));
++	if ((sp->type == 'T') || (sp->type == 't'))
++		return TRUE;
++
++	if ((sp->type == 'W') || (sp->type == 'w')) {
++		if ((sp->value >= kt->stext) &&
++		    (sp->value < kt->etext))
++			return TRUE;
++	}
++
++	return FALSE;
+ }
+ 
+ /*
+
+commit a7e5b90757bb41ad5e148177c5b3aaf5d892243d
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Jun 20 16:33:43 2018 -0400
+
+    Fix for the x86_64 "bt" command in Linux 4.16 and later kernels
+    containing commit 3aa99fc3e708b9cd9b4cfe2df0b7a66cf293e3cf, titled
+    "x86/entry/64: Remove 'interrupt' macro".  Without the patch, the
+    exception frame display generated by an interrupt exception will
+    show incorrect contents, and be followed by the message "bt: WARNING:
+    possibly bogus exception frame".
+    (anderson@redhat.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index e01082b..6d1ae2f 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -4285,6 +4285,12 @@ x86_64_exception_frame(ulong flags, ulong kvaddr, char *local,
+ 	long err;
+ 	char buf[BUFSIZE];
+ 
++	if (flags == EFRAME_VERIFY) {
++		if (!accessible(kvaddr) || 
++		    !accessible(kvaddr + SIZE(pt_regs) - sizeof(long)))
++			return FALSE;
++	}
++
+ 	ms = machdep->machspec;
+ 	sp = NULL;
+ 
+@@ -6283,6 +6289,9 @@ x86_64_irq_eframe_link(ulong stkref, struct bt_info *bt, FILE *ofp)
+ {
+ 	ulong irq_eframe;
+ 
++	if (x86_64_exception_frame(EFRAME_VERIFY, stkref, 0, bt, ofp))
++		return stkref;
++
+ 	irq_eframe = stkref - machdep->machspec->irq_eframe_link;
+ 
+ 	if (x86_64_exception_frame(EFRAME_VERIFY, irq_eframe, 0, bt, ofp))
+
+commit 02efd0838f05ef8a7fe21b0b8ba6cad729270645
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jun 22 11:00:01 2018 -0400
+
+    Fix for the failure of several "kmem" command options, most notably
+    seen if the command is piped directly into a crash session, or if
+    the command is contained in an input file.  For examples:
+      $ echo "kmem -i" | crash ...
+      $ crash -i <input-file> ...
+    Without the patch, the kmem command may fail with the error message
+    "<segmentation violation in gdb>".  While the bug is due to a buffer
+    overflow that has always existed, it only is triggered by certain
+    kernel configurations.
+    (anderson@redhat.com)
+
+diff --git a/memory.c b/memory.c
+index 2f568d5..5c0a853 100644
+--- a/memory.c
++++ b/memory.c
+@@ -17498,13 +17498,12 @@ vm_stat_init(void)
+ 			STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
+ 			continue;
+ 		} else {
+-			stringlen += strlen(arglist[0]);
++			stringlen += strlen(arglist[0]) + 1;
+ 			count++;
+ 		}
+         }
+ 
+-	total = stringlen + vt->nr_vm_stat_items + 
+-		(sizeof(void *) * vt->nr_vm_stat_items);
++	total = stringlen + (sizeof(void *) * vt->nr_vm_stat_items);
+         if (!(vt->vm_stat_items = (char **)malloc(total))) {
+ 		close_tmpfile();
+                 error(FATAL, "cannot malloc vm_stat_items cache\n");
diff --git a/SOURCES/github_2f57a96c_files-c-p.patch b/SOURCES/github_2f57a96c_files-c-p.patch
new file mode 100644
index 0000000..18c9255
--- /dev/null
+++ b/SOURCES/github_2f57a96c_files-c-p.patch
@@ -0,0 +1,58 @@
+commit 2f57a96ce27d8b121c2822de2a66c71b83bdad21
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue Sep 4 14:29:45 2018 -0400
+
+    Fix for the "files" command in Linux 4.17 and later kernels that
+    contain commit b93b016313b3ba8003c3b8bb71f569af91f19fc7, titled
+    "page cache: use xa_lock".  Without the patch, the "files -c" option
+    fails with the message "files: -c option not supported or applicable
+    on this architecture or kernel", and the "files -p &lt;inode>" option
+    fails in a similar manner.
+    (k-hagio@ab.jp.nec.com)
+
+diff --git a/filesys.c b/filesys.c
+index 47f5a24..32daa5a 100644
+--- a/filesys.c
++++ b/filesys.c
+@@ -2207,6 +2207,11 @@ dump_inode_page_cache_info(ulong inode)
+ 		RJUST|LONG_DEC,
+ 		MKSTR(nrpages)));
+ 
++	FREEBUF(inode_buf);
++
++	if (!nrpages)
++		return;
++
+ 	root_rnode = i_mapping + OFFSET(address_space_page_tree);
+ 	rtp.index = 0;
+ 	rtp.value = (void *)&dump_inode_page;
+@@ -2217,7 +2222,6 @@ dump_inode_page_cache_info(ulong inode)
+ 		error(INFO, "page_tree count: %ld  nrpages: %ld\n",
+ 			count, nrpages);
+ 
+-	FREEBUF(inode_buf);
+ 	return;
+ }
+ 
+@@ -2275,7 +2279,7 @@ cmd_files(void)
+ 			return;
+ 
+ 		case 'c':
+-			if (VALID_MEMBER(address_space_page_tree) &&
++			if (VALID_MEMBER(address_space_nrpages) &&
+ 			    VALID_MEMBER(inode_i_mapping))
+ 				open_flags |= PRINT_NRPAGES;
+ 			else
+diff --git a/memory.c b/memory.c
+index 24fce5e..ea25047 100644
+--- a/memory.c
++++ b/memory.c
+@@ -485,6 +485,8 @@ vm_init(void)
+ 	MEMBER_OFFSET_INIT(block_device_bd_disk, "block_device", "bd_disk");
+ 	MEMBER_OFFSET_INIT(inode_i_mapping, "inode", "i_mapping");
+ 	MEMBER_OFFSET_INIT(address_space_page_tree, "address_space", "page_tree");
++	if (INVALID_MEMBER(address_space_page_tree))
++		MEMBER_OFFSET_INIT(address_space_page_tree, "address_space", "i_pages");
+ 	MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "nrpages");
+ 	if (INVALID_MEMBER(address_space_nrpages))
+ 		MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "__nrpages");
diff --git a/SOURCES/github_3141bba9.patch b/SOURCES/github_3141bba9.patch
new file mode 100644
index 0000000..4629517
--- /dev/null
+++ b/SOURCES/github_3141bba9.patch
@@ -0,0 +1,45 @@
+commit 3141bba98af302e2a7c5e2a19203bb8a40b6aa63
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Oct 10 09:15:42 2018 -0400
+
+    Fix the calculation of the vmalloc memory region size to account for
+    Linux 4.17 commit a7412546d8cb5ad578805060b4006f2a021b5868, titled
+    "x86/mm: Adjust vmalloc base and size at boot-time", which increases
+    the region's size from 32TB to 1280TB when 5-level pagetables are
+    enabled.  Also presume that virtual addresses above the end of the
+    vmalloc space up to the beginning of vmemmap space are translatable
+    via 5-level page tables.  Without the patch, mapped virtual addresses
+    may fail translation in whatever command accesses them, with errors
+    indicating "seek error: kernel virtual address: <mapped-address>
+    type: <type-string>"
+    (anderson@redhat.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index 6f547e8..345122c 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -393,8 +393,12 @@ x86_64_init(int when)
+ 				readmem(symbol_value("vmalloc_base"), KVADDR,
+ 					&machdep->machspec->vmalloc_start_addr,
+ 					sizeof(ulong), "vmalloc_base", FAULT_ON_ERROR);
+-				machdep->machspec->vmalloc_end =
+-					machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
++				if (machdep->flags & VM_5LEVEL)
++					machdep->machspec->vmalloc_end =
++						machdep->machspec->vmalloc_start_addr + TERABYTES(1280) - 1;
++				else
++					machdep->machspec->vmalloc_end =
++						machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
+ 				if (kernel_symbol_exists("vmemmap_base")) {
+ 					readmem(symbol_value("vmemmap_base"), KVADDR,
+ 						&machdep->machspec->vmemmap_vaddr, sizeof(ulong),
+@@ -1626,7 +1630,8 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
+ 		(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
+ 		(machdep->machspec->cpu_entry_area_start && 
+ 		 vaddr >= machdep->machspec->cpu_entry_area_start &&
+-		 vaddr <= machdep->machspec->cpu_entry_area_end));
++		 vaddr <= machdep->machspec->cpu_entry_area_end) ||
++		((machdep->flags & VM_5LEVEL) && vaddr > VMALLOC_END && vaddr < VMEMMAP_VADDR));
+ }
+ 
+ static int 
diff --git a/SOURCES/github_361f050e_dev-d.patch b/SOURCES/github_361f050e_dev-d.patch
new file mode 100644
index 0000000..0091f96
--- /dev/null
+++ b/SOURCES/github_361f050e_dev-d.patch
@@ -0,0 +1,196 @@
+commit 361f050e3148c6188afb45942e06d4a509852b86
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Jan 7 13:56:15 2019 -0500
+
+    Fix for the "dev -[dD]" options in kernels containing Linux 5.0-rc1
+    commit 7ff4f8035695984c513598e2d49c8277d5d234ca, titled "block:
+    remove dead queue members", in which the number of I/Os issued to
+    a disk driver are no longer stored in the request_queue structure.
+    Without the patch, the options indicate "dev: -d option not supported
+    or applicable on this architecture or kernel".  With the patch, the
+    "DRV" column is not shown.
+    (m.mizuma@jp.fujitsu.com)
+
+diff --git a/defs.h b/defs.h
+index a3cb5a4..9ebdde6 100644
+--- a/defs.h
++++ b/defs.h
+@@ -2043,6 +2043,8 @@ struct offset_table {
+         long pci_bus_self;
+         long device_kobj;
+         long kobject_name;
++	long hd_struct_dkstats;
++	long disk_stats_in_flight;
+ };
+ 
+ struct size_table {         /* stash of commonly-used sizes */
+diff --git a/dev.c b/dev.c
+index 7ce2422..24efea2 100644
+--- a/dev.c
++++ b/dev.c
+@@ -3974,7 +3974,7 @@ struct iter {
+ 	 * this function reads request_list.count[2], and the first argument
+ 	 * is the address of request_queue.
+ 	 */
+-	void (*get_diskio)(unsigned long , struct diskio *);
++	void (*get_diskio)(unsigned long , unsigned long, struct diskio *);
+ 
+ 	/*
+ 	 * check if device.type == &disk_type
+@@ -4187,24 +4187,55 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
+ 	}
+ }
+ 
++static void
++get_one_diskio_from_dkstats(unsigned long dkstats, unsigned long *count)
++{
++	int cpu;
++	unsigned long dkstats_addr;
++	unsigned long in_flight[2];
++
++	for (cpu = 0; cpu < kt->cpus; cpu++) {
++		if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
++			dkstats_addr = dkstats + kt->__per_cpu_offset[cpu];
++			readmem(dkstats_addr + OFFSET(disk_stats_in_flight),
++				KVADDR, in_flight, sizeof(long) * 2,
++				"disk_stats.in_flight", FAULT_ON_ERROR);
++			count[0] += in_flight[0];
++			count[1] += in_flight[1];
++		}
++	}
++}
++
++
+ /* read request_queue.rq.count[2] */
+ static void 
+-get_diskio_1(unsigned long rq, struct diskio *io)
++get_diskio_1(unsigned long rq, unsigned long gendisk, struct diskio *io)
+ {
+ 	int count[2];
+-	unsigned long mq_count[2] = { 0 };
++	unsigned long io_counts[2] = { 0 };
++	unsigned long dkstats;
+ 
+ 	if (!use_mq_interface(rq)) {
+-		readmem(rq + OFFSET(request_queue_rq) +
+-			OFFSET(request_list_count), KVADDR, count,
+-			sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
++		if (VALID_MEMBER(request_queue_rq)) {
++			readmem(rq + OFFSET(request_queue_rq) +
++				OFFSET(request_list_count), KVADDR, count,
++				sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
++
++			io->read = count[0];
++			io->write = count[1];
++		} else {
++			readmem(gendisk + OFFSET(gendisk_part0) +
++				OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
++				sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
++			get_one_diskio_from_dkstats(dkstats, io_counts);
+ 
+-		io->read = count[0];
+-		io->write = count[1];
++			io->read = io_counts[0];
++			io->write = io_counts[1];
++		}
+ 	} else {
+-		get_mq_diskio(rq, mq_count);
+-		io->read = mq_count[0];
+-		io->write = mq_count[1];
++		get_mq_diskio(rq, io_counts);
++		io->read = io_counts[0];
++		io->write = io_counts[1];
+ 	}
+ }
+ 
+@@ -4250,9 +4281,6 @@ init_iter(struct iter *i)
+ 		i->get_in_flight = get_in_flight_1;
+ 	} else if (SIZE(rq_in_flight) == sizeof(int) * 2) {
+ 		i->get_in_flight = get_in_flight_2;
+-	} else {
+-		option_not_supported('d');
+-		return;
+ 	}
+ 	i->get_diskio = get_diskio_1;
+ 
+@@ -4354,7 +4382,7 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
+ 		sizeof(ulong), "gen_disk.queue", FAULT_ON_ERROR);
+ 	readmem(gendisk + OFFSET(gendisk_major), KVADDR, &major, sizeof(int),
+ 		"gen_disk.major", FAULT_ON_ERROR);
+-	i->get_diskio(queue_addr, &io);
++	i->get_diskio(queue_addr, gendisk, &io);
+ 
+ 	if ((flags & DIOF_NONZERO)
+ 		&& (io.read + io.write == 0))
+@@ -4379,11 +4407,14 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
+ 			(char *)(unsigned long)io.write),
+ 		space(MINSPACE));
+ 
+-	if (!use_mq_interface(queue_addr)) {
+-		in_flight = i->get_in_flight(queue_addr);
+-		fprintf(fp, "%5u\n", in_flight);
++	if (VALID_MEMBER(request_queue_in_flight)) {
++		if (!use_mq_interface(queue_addr)) {
++			in_flight = i->get_in_flight(queue_addr);
++			fprintf(fp, "%5u\n", in_flight);
++		} else
++			fprintf(fp, "%s\n", "N/A(MQ)");
+ 	} else
+-		fprintf(fp, "%s\n", "N/A(MQ)");
++		fprintf(fp, "\n");
+ }
+ 
+ static void 
+@@ -4418,7 +4449,7 @@ display_all_diskio(ulong flags)
+ 		i.sync_count ? mkstring(buf4, 5, RJUST, "SYNC") :
+ 			mkstring(buf4, 5, RJUST, "WRITE"),
+ 		space(MINSPACE),
+-		mkstring(buf5, 5, RJUST, "DRV"));
++		VALID_MEMBER(request_queue_in_flight) ? mkstring(buf5, 5, RJUST, "DRV") : "");
+ 
+ 	while ((gendisk = i.next_disk(&i)) != 0)
+ 		display_one_diskio(&i, gendisk, flags);
+@@ -4446,6 +4477,7 @@ void diskio_init(void)
+ 	MEMBER_OFFSET_INIT(gendisk_part0, "gendisk", "part0");
+ 	MEMBER_OFFSET_INIT(gendisk_queue, "gendisk", "queue");
+ 	MEMBER_OFFSET_INIT(hd_struct_dev, "hd_struct", "__dev");
++	MEMBER_OFFSET_INIT(hd_struct_dkstats, "hd_struct", "dkstats");
+ 	MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
+ 	MEMBER_OFFSET_INIT(klist_node_n_klist, "klist_node", "n_klist");
+ 	MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
+@@ -4476,6 +4508,7 @@ void diskio_init(void)
+ 	MEMBER_SIZE_INIT(rq_in_flight, "request_queue", "in_flight");
+ 	MEMBER_SIZE_INIT(class_private_devices, "class_private",
+ 		"class_devices");
++	MEMBER_OFFSET_INIT(disk_stats_in_flight, "disk_stats", "in_flight");
+ 
+ 	dt->flags |= DISKIO_INIT;
+ }
+diff --git a/help.c b/help.c
+index aadd2ed..1593e82 100644
+--- a/help.c
++++ b/help.c
+@@ -3218,7 +3218,7 @@ char *help_dev[] = {
+ "         WRITE: I/O requests that are writes (older kernels)",
+ "           DRV: I/O requests that are in-flight in the device driver.",
+ "                If the device driver uses blk-mq interface, this field",
+-"                shows N/A(MQ).",
++"                shows N/A(MQ).  If not available, this column is not shown.",
+ "    -D  same as -d, but filter out disks with no in-progress I/O requests.",
+ "\nEXAMPLES",
+ "  Display character and block device data:\n",
+diff --git a/symbols.c b/symbols.c
+index ef6f934..5f77e27 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -10021,6 +10021,10 @@ dump_offset_table(char *spec, ulong makestruct)
+ 		OFFSET(gendisk_queue));
+ 	fprintf(fp, "                 hd_struct_dev: %ld\n",
+ 		OFFSET(hd_struct_dev));
++	fprintf(fp, "             hd_struct_dkstats: %ld\n",
++		OFFSET(hd_struct_dkstats));
++	fprintf(fp, "          disk_stats_in_flight: %ld\n",
++		OFFSET(disk_stats_in_flight));
+ 	fprintf(fp, "                  klist_k_list: %ld\n",
+ 		OFFSET(klist_k_list));
+ 	fprintf(fp, "            klist_node_n_klist: %ld\n",
diff --git a/SOURCES/github_46d21219_to_9446958f.patch b/SOURCES/github_46d21219_to_9446958f.patch
new file mode 100644
index 0000000..c871403
--- /dev/null
+++ b/SOURCES/github_46d21219_to_9446958f.patch
@@ -0,0 +1,414 @@
+commit 46d2121960d81354facf4e2558c81f82257b740e
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue May 29 14:04:03 2018 -0400
+
+    Fix for the "timer -r" command on Linux 4.10 and later kernels that
+    contain commit 2456e855354415bfaeb7badaa14e11b3e02c8466, titled
+    "ktime: Get rid of the union".  Without the patch, the command fails
+    with the error message "timer: invalid structure member offset:
+    ktime_t_sec".
+    (k-hagio@ab.jp.nec.com)
+
+diff --git a/kernel.c b/kernel.c
+index b1886ce..138a47f 100644
+--- a/kernel.c
++++ b/kernel.c
+@@ -7740,7 +7740,7 @@ ktime_to_ns(const void *ktime)
+ 	if (VALID_MEMBER(ktime_t_tv64)) {
+ 		readmem((ulong)ktime + OFFSET(ktime_t_tv64), KVADDR, &ns,
+ 			sizeof(ns), "ktime_t tv64", QUIET|RETURN_ON_ERROR);
+-	} else {
++	} else if (VALID_MEMBER(ktime_t_sec) && VALID_MEMBER(ktime_t_nsec)) {
+ 		uint32_t sec, nsec;
+ 
+ 		sec = 0;
+@@ -7753,6 +7753,9 @@ ktime_to_ns(const void *ktime)
+ 			sizeof(nsec), "ktime_t nsec", QUIET|RETURN_ON_ERROR);
+ 
+ 		ns = sec * 1000000000L + nsec;
++	} else {
++		readmem((ulong)ktime, KVADDR, &ns,
++			sizeof(ns), "ktime_t", QUIET|RETURN_ON_ERROR);
+ 	}
+ 
+ 	return ns;
+
+commit a6cd8408d1d214a67ed0c4b09343fec77a8e2ae7
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu May 31 11:43:14 2018 -0400
+
+    Fix for the x86 and x86_64 "mach -m" option on Linux 4.12 and later
+    kernels to account for the structure name changes "e820map" to
+    "e820_table", and "e820entry" to "e820_entry", and for the symbol
+    name change from "e820" to "e820_table".  Also updated the display
+    output to properly translate E820_PRAM and E820_RESERVED_KERN entries.
+    Without the patch on all kernels, E820_PRAM and E820_RESERVED_KERN
+    entries show "type 12" and "type 128" respectively.  Without the
+    patch on Linux 4.12 and later kernels, the command fails with the
+    error message "mach: cannot resolve e820".
+    (anderson@redhat.com)
+
+diff --git a/x86.c b/x86.c
+index 47767b6..88562b6 100644
+--- a/x86.c
++++ b/x86.c
+@@ -1,8 +1,8 @@
+ /* x86.c - core analysis suite
+  *
+  * Portions Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
+- * Copyright (C) 2002-2014,2017 David Anderson
+- * Copyright (C) 2002-2014,2017 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2002-2014,2017-2018 David Anderson
++ * Copyright (C) 2002-2014,2017-2018 Red Hat, Inc. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -1967,15 +1967,27 @@ x86_init(int when)
+ 		}
+ 		MEMBER_OFFSET_INIT(thread_struct_cr3, "thread_struct", "cr3");
+ 		STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
+-		STRUCT_SIZE_INIT(e820map, "e820map");
+-		STRUCT_SIZE_INIT(e820entry, "e820entry");
+ 		STRUCT_SIZE_INIT(irq_ctx, "irq_ctx");
++		if (STRUCT_EXISTS("e820map")) {
++			STRUCT_SIZE_INIT(e820map, "e820map");
++			MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
++		} else {
++			STRUCT_SIZE_INIT(e820map, "e820_table");
++			MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries");
++		}
++		if (STRUCT_EXISTS("e820entry")) {
++			STRUCT_SIZE_INIT(e820entry, "e820entry");
++			MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
++			MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
++			MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
++		} else {
++			STRUCT_SIZE_INIT(e820entry, "e820_entry");
++			MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr");
++			MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size");
++			MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type");
++		}
+ 		if (!VALID_STRUCT(irq_ctx))
+ 			STRUCT_SIZE_INIT(irq_ctx, "irq_stack");
+-		MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
+-		MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
+-		MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
+-		MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+ 		if (KVMDUMP_DUMPFILE())
+ 			set_kvm_iohole(NULL);
+ 		if (symbol_exists("irq_desc"))
+@@ -4415,33 +4427,54 @@ static char *e820type[] = {
+ static void
+ x86_display_memmap(void)
+ {
+-	ulong e820;
+-	int nr_map, i;
+-	char *buf, *e820entry_ptr;
+-	ulonglong addr, size;
+-	ulong type;
++        ulong e820;
++        int nr_map, i;
++        char *buf, *e820entry_ptr;
++        ulonglong addr, size;
++        uint type;
++
++	if (kernel_symbol_exists("e820")) {
++		if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
++			get_symbol_data("e820", sizeof(void *), &e820);
++		else
++			e820 = symbol_value("e820");
++
++	} else if (kernel_symbol_exists("e820_table"))
++		get_symbol_data("e820_table", sizeof(void *), &e820);
++	else
++		error(FATAL, "neither e820 or e820_table symbols exist\n");
+ 
+-	e820 = symbol_value("e820");
+-	buf = (char *)GETBUF(SIZE(e820map));
++	if (CRASHDEBUG(1)) {
++		if (STRUCT_EXISTS("e820map"))
++			dump_struct("e820map", e820, RADIX(16));
++		else if (STRUCT_EXISTS("e820_table"))
++			dump_struct("e820_table", e820, RADIX(16));
++	}
++        buf = (char *)GETBUF(SIZE(e820map));
+ 
+-        readmem(e820, KVADDR, &buf[0], SIZE(e820map), 
+-		"e820map", FAULT_ON_ERROR);
++        readmem(e820, KVADDR, &buf[0], SIZE(e820map),
++                "e820map", FAULT_ON_ERROR);
+ 
+-	nr_map = INT(buf + OFFSET(e820map_nr_map));
++        nr_map = INT(buf + OFFSET(e820map_nr_map));
+ 
+-	fprintf(fp, "      PHYSICAL ADDRESS RANGE         TYPE\n");
++        fprintf(fp, "      PHYSICAL ADDRESS RANGE         TYPE\n");
+ 
+-	for (i = 0; i < nr_map; i++) {
+-		e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i);
+-		addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr));
+-		size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
+-		type = ULONG(e820entry_ptr + OFFSET(e820entry_type));
++        for (i = 0; i < nr_map; i++) {
++                e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i);
++                addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr));
++                size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
++                type = UINT(e820entry_ptr + OFFSET(e820entry_type));
+ 		fprintf(fp, "%016llx - %016llx  ", addr, addr+size);
+-		if (type >= (sizeof(e820type)/sizeof(char *)))
+-			fprintf(fp, "type %ld\n", type);
+-		else
++		if (type >= (sizeof(e820type)/sizeof(char *))) {
++			if (type == 12)
++				fprintf(fp, "E820_PRAM\n");
++			else if (type == 128)
++				fprintf(fp, "E820_RESERVED_KERN\n");
++			else
++				fprintf(fp, "type %d\n", type);
++		} else
+ 			fprintf(fp, "%s\n", e820type[type]);
+-	}
++        }
+ }
+ 
+ /*
+diff --git a/x86_64.c b/x86_64.c
+index 921552b..1d5e155 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -415,12 +415,26 @@ x86_64_init(int when)
+ 			STRUCT_SIZE_INIT(gate_struct, "gate_desc");
+ 		else
+ 			STRUCT_SIZE_INIT(gate_struct, "gate_struct");
+-                STRUCT_SIZE_INIT(e820map, "e820map");
+-                STRUCT_SIZE_INIT(e820entry, "e820entry");
+-                MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
+-                MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
+-                MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
+-                MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
++
++		if (STRUCT_EXISTS("e820map")) {
++			STRUCT_SIZE_INIT(e820map, "e820map");
++			MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
++		} else {
++			STRUCT_SIZE_INIT(e820map, "e820_table");
++			MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries");
++		}
++		if (STRUCT_EXISTS("e820entry")) {
++			STRUCT_SIZE_INIT(e820entry, "e820entry");
++			MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
++			MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
++			MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
++		} else {
++			STRUCT_SIZE_INIT(e820entry, "e820_entry");
++			MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr");
++			MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size");
++			MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type");
++		}
++
+ 		if (KVMDUMP_DUMPFILE())
+ 			set_kvm_iohole(NULL);
+ 		MEMBER_OFFSET_INIT(thread_struct_rip, "thread_struct", "rip");
+@@ -5643,12 +5657,23 @@ x86_64_display_memmap(void)
+         ulonglong addr, size;
+         uint type;
+ 
+-	if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
+-		get_symbol_data("e820", sizeof(void *), &e820);
++	if (kernel_symbol_exists("e820")) {
++		if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
++			get_symbol_data("e820", sizeof(void *), &e820);
++		else
++			e820 = symbol_value("e820");
++
++	} else if (kernel_symbol_exists("e820_table"))
++		get_symbol_data("e820_table", sizeof(void *), &e820);
+ 	else
+-		e820 = symbol_value("e820");
+-	if (CRASHDEBUG(1))
+-		dump_struct("e820map", e820, RADIX(16));
++		error(FATAL, "neither e820 or e820_table symbols exist\n");
++
++	if (CRASHDEBUG(1)) {
++		if (STRUCT_EXISTS("e820map"))
++			dump_struct("e820map", e820, RADIX(16));
++		else if (STRUCT_EXISTS("e820_table"))
++			dump_struct("e820_table", e820, RADIX(16));
++	}
+         buf = (char *)GETBUF(SIZE(e820map));
+ 
+         readmem(e820, KVADDR, &buf[0], SIZE(e820map),
+@@ -5664,9 +5689,14 @@ x86_64_display_memmap(void)
+                 size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
+                 type = UINT(e820entry_ptr + OFFSET(e820entry_type));
+ 		fprintf(fp, "%016llx - %016llx  ", addr, addr+size);
+-		if (type >= (sizeof(e820type)/sizeof(char *)))
+-			fprintf(fp, "type %d\n", type);
+-		else
++		if (type >= (sizeof(e820type)/sizeof(char *))) {
++			if (type == 12)
++				fprintf(fp, "E820_PRAM\n");
++			else if (type == 128)
++				fprintf(fp, "E820_RESERVED_KERN\n");
++			else
++				fprintf(fp, "type %d\n", type);
++		} else
+ 			fprintf(fp, "%s\n", e820type[type]);
+         }
+ }
+
+commit da49e2010b3cb88b4755d69d38fe90af6ba218b2
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jun 1 10:58:00 2018 -0400
+
+    Update for the recognition of the new x86_64 CPU_ENTRY_AREA virtual
+    address range introduced in Linux 4.15.  The memory range exists
+    above the vmemmap range and below the mapped kernel static text/data
+    region, and where all of the x86_64 exception stacks have been moved.
+    Without the patch, reads from the new memory region fail because the
+    address range is not recognized as a legitimate virtual address.
+    Most notable is the failure of "bt" on tasks whose backtraces
+    originate from any of the exception stacks, which fail with the two
+    error messages "bt: seek error: kernel virtual address: <address>
+    type: stack contents" followed by "bt: read of stack at <address>
+    failed".
+    (anderson@redhat.com)
+
+diff --git a/defs.h b/defs.h
+index 931be07..6e6f6be 100644
+--- a/defs.h
++++ b/defs.h
+@@ -3391,6 +3391,9 @@ struct arm64_stackframe {
+ #define VSYSCALL_START             0xffffffffff600000
+ #define VSYSCALL_END               0xffffffffff601000
+ 
++#define CPU_ENTRY_AREA_START       0xfffffe0000000000
++#define CPU_ENTRY_AREA_END         0xfffffe7fffffffff
++
+ #define PTOV(X)               ((unsigned long)(X)+(machdep->kvbase))
+ #define VTOP(X)               x86_64_VTOP((ulong)(X))
+ #define IS_VMALLOC_ADDR(X)    x86_64_IS_VMALLOC_ADDR((ulong)(X))
+@@ -5829,6 +5832,8 @@ struct machine_specific {
+ 	ulong kpti_entry_stack;
+ 	ulong kpti_entry_stack_size;
+ 	ulong ptrs_per_pgd;
++	ulong cpu_entry_area_start;
++	ulong cpu_entry_area_end;
+ };
+ 
+ #define KSYMS_START    (0x1)
+diff --git a/x86_64.c b/x86_64.c
+index 1d5e155..54b6539 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -407,6 +407,11 @@ x86_64_init(int when)
+ 				machdep->machspec->modules_end = MODULES_END_2_6_31;
+ 			}
+ 		}
++		if (STRUCT_EXISTS("cpu_entry_area")) {
++			machdep->machspec->cpu_entry_area_start = CPU_ENTRY_AREA_START;	
++			machdep->machspec->cpu_entry_area_end = CPU_ENTRY_AREA_END;	
++		}
++
+                 STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
+ 		/* 
+ 		 * Before 2.6.25 the structure was called gate_struct
+@@ -879,20 +884,21 @@ x86_64_dump_machdep_table(ulong arg)
+ 
+ 	/* pml4 and upml is legacy for extension modules */
+ 	if (ms->pml4) {
+-		fprintf(fp, "			  pml4: %lx\n", (ulong)ms->pml4);
+-		fprintf(fp, "		last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
++		fprintf(fp, "                     pml4: %lx\n", (ulong)ms->pml4);
++		fprintf(fp, "           last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
+ 
+ 	} else {
+-		fprintf(fp, "		      pml4: (unused)\n");
+-		fprintf(fp, "	    last_pml4_read: (unused)\n");
++		fprintf(fp, "                     pml4: (unused)\n");
++		fprintf(fp, "           last_pml4_read: (unused)\n");
+ 	}
+ 
+ 	if (ms->upml) {
+-		fprintf(fp, "		      upml: %lx\n", (ulong)ms->upml);
+-		fprintf(fp, "	    last_upml_read: %lx\n", (ulong)ms->last_upml_read);
++		fprintf(fp, "                     upml: %lx\n", (ulong)ms->upml);
++		fprintf(fp, "           last_upml_read: %lx\n", (ulong)ms->last_upml_read);
+ 	} else {
+-		fprintf(fp, "		      upml: (unused)\n");
+-		fprintf(fp, "	    last_upml_read: (unused)\n");
++		fprintf(fp, "                 GART_end: %lx\n", ms->GART_end);
++		fprintf(fp, "                     upml: (unused)\n");
++		fprintf(fp, "           last_upml_read: (unused)\n");
+ 	}
+ 
+ 	if (ms->p4d) {
+@@ -1016,10 +1022,14 @@ x86_64_dump_machdep_table(ulong arg)
+ 			fprintf(fp, "\n   ");
+ 		fprintf(fp, "%016lx ", ms->stkinfo.ibase[c]);
+ 	}
+-	fprintf(fp, "\n                 kpti_entry_stack_size: %ld", ms->kpti_entry_stack_size);
+-	fprintf(fp, "\n                      kpti_entry_stack: ");
++	fprintf(fp, "\n    kpti_entry_stack_size: ");
++	if (ms->kpti_entry_stack_size)
++		fprintf(fp, "%ld", ms->kpti_entry_stack_size);
++	else
++		fprintf(fp, "(unused)");
++	fprintf(fp, "\n         kpti_entry_stack: ");
+ 	if (machdep->flags & KPTI) {
+-		fprintf(fp, "%lx\n   ", ms->kpti_entry_stack);
++		fprintf(fp, "(percpu: %lx):\n   ", ms->kpti_entry_stack);
+ 		for (c = 0; c < cpus; c++) {
+ 			if (c && !(c%4))
+ 				fprintf(fp, "\n   ");
+@@ -1028,6 +1038,16 @@ x86_64_dump_machdep_table(ulong arg)
+ 		fprintf(fp, "\n");
+ 	} else
+ 		fprintf(fp, "(unused)\n");
++	fprintf(fp, "     cpu_entry_area_start: ");
++	if (ms->cpu_entry_area_start)
++		fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_start);
++	else
++		fprintf(fp, "(unused)\n");
++	fprintf(fp, "       cpu_entry_area_end: ");
++	if (ms->cpu_entry_area_end)
++		fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end);
++	else
++		fprintf(fp, "(unused)\n");
+ }
+ 
+ /*
+@@ -1586,7 +1606,10 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
+                 ((machdep->flags & VMEMMAP) && 
+ 		 (vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END)) ||
+                 (vaddr >= MODULES_VADDR && vaddr <= MODULES_END) ||
+-		(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END));
++		(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
++		(machdep->machspec->cpu_entry_area_start && 
++		 vaddr >= machdep->machspec->cpu_entry_area_start &&
++		 vaddr <= machdep->machspec->cpu_entry_area_end));
+ }
+ 
+ static int 
+
+commit 9446958fe211825ed5524317b05d5ea020bb00d6
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jun 1 14:01:01 2018 -0400
+
+    Fix to address a "__builtin___snprintf_chk" compiler warning if bpf.c
+    is compiled with -D_FORTIFY_SOURCE=2.
+    (anderson@redhat.com)
+
+diff --git a/bpf.c b/bpf.c
+index 305d49f..ee1986f 100644
+--- a/bpf.c
++++ b/bpf.c
+@@ -362,7 +362,7 @@ do_bpf(ulong flags, ulong prog_id, ulong map_id, int radix)
+ 			fprintf(fp, "     LOAD_TIME: ");
+ 			if (VALID_MEMBER(bpf_prog_aux_load_time)) {
+ 				load_time = ULONGLONG(bpf->bpf_prog_aux_buf + OFFSET(bpf_prog_aux_load_time));
+-				print_boot_time(load_time, buf5, BUFSIZE);
++				print_boot_time(load_time, buf5, BUFSIZE/2);
+ 				fprintf(fp, "%s\n", buf5);
+ 			} else
+ 				fprintf(fp, "(unknown)\n");
diff --git a/SOURCES/github_64dad6d0.patch b/SOURCES/github_64dad6d0.patch
new file mode 100644
index 0000000..7f41a57
--- /dev/null
+++ b/SOURCES/github_64dad6d0.patch
@@ -0,0 +1,34 @@
+
+commit 64dad6d0d60514498252e6071738fa1b4c12db8c
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Nov 29 14:21:19 2018 -0500
+
+    Fix for the "ps -s" option on ARM64 if the number of tasks exceeds
+    2000.  Without the patch, the command ultimately fails with a
+    dump of the internal buffer allocation stats, followed by the
+    message "ps: cannot allocate any more memory!".
+    (anderson@redhat.com)
+
+diff -up crash-7.2.3/task.c.orig crash-7.2.3/task.c
+--- crash-7.2.3/task.c.orig	2018-11-29 13:54:39.108320730 -0500
++++ crash-7.2.3/task.c	2018-11-29 13:54:48.598279086 -0500
+@@ -4133,6 +4133,10 @@ task_pointer_string(struct task_context
+         		readmem(tc->task + OFFSET(task_struct_thread_ksp), 
+ 				KVADDR, &bt->stkptr, sizeof(void *),
+                 		"thread_struct ksp", FAULT_ON_ERROR);
++		} else if (VALID_MEMBER(task_struct_thread_context_sp)) {
++			readmem(tc->task + OFFSET(task_struct_thread_context_sp), 
++				KVADDR, &bt->stkptr, sizeof(void *),
++				"cpu_context sp", FAULT_ON_ERROR);
+ 		} else {
+ 			if ((bt->stackbase = GET_STACKBASE(tc->task))) {
+ 				bt->stacktop = GET_STACKTOP(tc->task);
+@@ -4140,6 +4144,8 @@ task_pointer_string(struct task_context
+ 				bt->tc = tc;
+ 				bt->flags |= BT_KSTACKP;
+ 				back_trace(bt);
++				if (bt->stackbuf)
++					FREEBUF(bt->stackbuf);
+ 			} else
+ 				bt->stkptr = 0;
+ 		}
diff --git a/SOURCES/github_6b93714b_cmdline.patch b/SOURCES/github_6b93714b_cmdline.patch
new file mode 100644
index 0000000..0fe9a66
--- /dev/null
+++ b/SOURCES/github_6b93714b_cmdline.patch
@@ -0,0 +1,39 @@
+commit 6b93714b83d59ae4147b8ec3887261aca7fd6f65
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Jan 7 10:44:29 2019 -0500
+
+    Prevent a SIGSEGV if a user attempts to input a command line that
+    exceeds the maximum length of 1500 bytes.  The patch displays an
+    error message and ignores the command line.
+    (anderson@redhat.com)
+
+diff --git a/cmdline.c b/cmdline.c
+index 665f48c..796f7c5 100644
+--- a/cmdline.c
++++ b/cmdline.c
+@@ -1,8 +1,8 @@
+ /* cmdline.c - core analysis suite
+  *
+  * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
+- * Copyright (C) 2002-2015,2018 David Anderson
+- * Copyright (C) 2002-2015,2018 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2002-2015,2019 David Anderson
++ * Copyright (C) 2002-2015,2019 Red Hat, Inc. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -121,9 +121,11 @@ process_command_line(void)
+ 			args[0] = NULL;
+ 			fprintf(fp, "\n");
+ 			return;
+-		} 
+-
+-		strcpy(pc->command_line, pc->readline);
++		}
++		if (strlen(pc->readline) >= BUFSIZE)
++			error(FATAL, "input line exceeds maximum of 1500 bytes\n");	
++		else	
++			strcpy(pc->command_line, pc->readline);
+ 		free(pc->readline); 
+ 
+ 		clean_line(pc->command_line);
diff --git a/SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52 b/SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
new file mode 100644
index 0000000..c15eddc
--- /dev/null
+++ b/SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
@@ -0,0 +1,212 @@
+commit 8618ddd817621c40c1f44f0ab6df7c7805234416
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Feb 1 15:01:29 2019 -0500
+
+    First phase of support for ARM64 kernels that are configured with
+    CONFIG_ARM64_USER_VA_BITS_52, which causes the PTRS_PER_PGD count
+    to increase from 64 to 1024.  Without the patch, "WARNING: cannot
+    access vmalloc'd module memory" will be displayed during session
+    initialization, and the translation of any mapped kernel virtual
+    address that requires a page table walk will fail, leading to a
+    myriad of other errors.
+    (anderson@redhat.com)
+
+diff --git a/arm64.c b/arm64.c
+index 45c7313..2308612 100644
+--- a/arm64.c
++++ b/arm64.c
+@@ -1,8 +1,8 @@
+ /*
+  * arm64.c - core analysis suite
+  *
+- * Copyright (C) 2012-2018 David Anderson
+- * Copyright (C) 2012-2018 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2012-2019 David Anderson
++ * Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -209,6 +209,8 @@ arm64_init(int when)
+ 		ms->page_offset = ARM64_PAGE_OFFSET;
+ 		machdep->identity_map_base = ARM64_PAGE_OFFSET;
+ 		machdep->kvbase = ARM64_VA_START;
++		machdep->is_kvaddr = generic_is_kvaddr;
++		machdep->kvtop = arm64_kvtop;
+ 		ms->userspace_top = ARM64_USERSPACE_TOP;
+ 		if (machdep->flags & NEW_VMEMMAP) {
+ 			struct syment *sp;
+@@ -262,11 +264,17 @@ arm64_init(int when)
+ 			break;
+ 
+ 		case 65536:
++			if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
++			    readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
++			    &value, sizeof(ulong), "idmap_ptrs_per_pgd", RETURN_ON_ERROR))
++				machdep->ptrs_per_pgd = value;
++		
+ 			if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_64K) {
+ 				machdep->flags |= VM_L3_64K;
+-				machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
++				if (!machdep->ptrs_per_pgd)
++					machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
+ 				if ((machdep->pgd =
+-				    (char *)malloc(PTRS_PER_PGD_L3_64K * 8)) == NULL)
++				    (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
+ 					error(FATAL, "cannot malloc pgd space.");
+ 				if ((machdep->pmd =
+ 				    (char *)malloc(PTRS_PER_PMD_L3_64K * 8)) == NULL)
+@@ -276,9 +284,10 @@ arm64_init(int when)
+ 					error(FATAL, "cannot malloc ptbl space.");
+ 			} else {
+ 				machdep->flags |= VM_L2_64K;
+-				machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
++				if (!machdep->ptrs_per_pgd)
++					machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
+ 				if ((machdep->pgd =
+-				    (char *)malloc(PTRS_PER_PGD_L2_64K * 8)) == NULL)
++				    (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
+ 					error(FATAL, "cannot malloc pgd space.");
+ 				if ((machdep->ptbl =
+ 				    (char *)malloc(PTRS_PER_PTE_L2_64K * 8)) == NULL)
+@@ -306,9 +315,11 @@ arm64_init(int when)
+ 		machdep->flags |= VMEMMAP;
+ 
+ 		machdep->uvtop = arm64_uvtop;
+-		machdep->kvtop = arm64_kvtop;
+-		machdep->is_kvaddr = generic_is_kvaddr;
+ 		machdep->is_uvaddr = arm64_is_uvaddr;
++		if (kernel_symbol_exists("vabits_user") && 
++		    readmem(symbol_value("vabits_user"), KVADDR,
++		    &value, sizeof(ulong), "vabits_user", RETURN_ON_ERROR))
++			machdep->machspec->vabits_user = value;
+ 		machdep->eframe_search = arm64_eframe_search;
+ 		machdep->back_trace = arm64_back_trace_cmd;
+ 		machdep->in_alternate_stack = arm64_in_alternate_stack;
+@@ -350,10 +361,14 @@ arm64_init(int when)
+ 	case POST_GDB:
+ 		arm64_calc_virtual_memory_ranges();
+ 		machdep->section_size_bits = _SECTION_SIZE_BITS;
+-		if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
+-			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
+-		else
+-			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
++		if (!machdep->max_physmem_bits) {
++			if (machdep->machspec->VA_BITS == 52)  /* guess */
++				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
++			else if (THIS_KERNEL_VERSION >= LINUX(3,17,0)) 
++				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
++			else
++				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
++		}
+ 		ms = machdep->machspec;
+ 
+ 		if (THIS_KERNEL_VERSION >= LINUX(4,0,0)) {
+@@ -601,6 +616,11 @@ arm64_dump_machdep_table(ulong arg)
+ 
+ 	fprintf(fp, "            machspec: %lx\n", (ulong)ms);
+ 	fprintf(fp, "               VA_BITS: %ld\n", ms->VA_BITS);
++	fprintf(fp, "           vabits_user: ");
++	if (ms->vabits_user)
++		fprintf(fp, "%ld\n", ms->vabits_user);
++	else
++		fprintf(fp, "(unused)\n");
+ 	fprintf(fp, "         userspace_top: %016lx\n", ms->userspace_top);
+ 	fprintf(fp, "           page_offset: %016lx\n", ms->page_offset);
+ 	fprintf(fp, "    vmalloc_start_addr: %016lx\n", ms->vmalloc_start_addr);
+@@ -691,6 +711,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
+ 			*value = dtol(p, flags, &err);
+ 			if (!err)
+ 				*value = MEGABYTES(*value);
++		} else if (STRNEQ(argstring, "max_physmem_bits")) {
++			*value = dtol(p, flags, &err);
+ 		} else {
+ 			*value = htol(p, flags, &err);
+ 		}
+@@ -750,6 +772,12 @@ arm64_parse_cmdline_args(void)
+ 					"setting kimage_voffset to: 0x%lx\n\n",
+ 					machdep->machspec->kimage_voffset);
+ 				continue;
++			} else if (arm64_parse_machdep_arg_l(arglist[i], "max_physmem_bits",
++			        &machdep->max_physmem_bits)) {
++				error(NOTE,
++					"setting max_physmem_bits to: %ld\n\n",
++					machdep->max_physmem_bits);
++				continue;
+ 			}
+ 
+ 			error(WARNING, "ignoring --machdep option: %s\n",
+@@ -1065,8 +1093,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
+                 fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
+ 
+ 	pgd_base = (ulong *)pgd;
+-	FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L2_64K * sizeof(ulong));
+-	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (PTRS_PER_PGD_L2_64K - 1));
++	FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
++	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (machdep->ptrs_per_pgd - 1));
+         pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr));
+         if (verbose) 
+                 fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
+@@ -1129,8 +1157,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
+                 fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
+ 
+ 	pgd_base = (ulong *)pgd;
+-	FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L3_64K * sizeof(ulong));
+-	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (PTRS_PER_PGD_L3_64K - 1));
++	FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
++	pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (machdep->ptrs_per_pgd - 1));
+         pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_64K(pgd_ptr));
+         if (verbose)
+                 fprintf(fp, "   PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
+diff --git a/crash.8 b/crash.8
+index 8c11615..f9de36d 100644
+--- a/crash.8
++++ b/crash.8
+@@ -278,6 +278,7 @@ ARM:
+ ARM64:  
+   phys_offset=<physical-address>
+   kimage_voffset=<kimage_voffset-value>
++  max_physmem_bits=<value>
+ X86:
+   page_offset=<CONFIG_PAGE_OFFSET-value>
+ .fi
+diff --git a/defs.h b/defs.h
+index b473972..05f2d17 100644
+--- a/defs.h
++++ b/defs.h
+@@ -3049,7 +3049,7 @@ typedef signed int s32;
+ #define PMD_SHIFT_L3_64K     (29)
+ #define PMD_SIZE_L3_64K      (1UL << PMD_SHIFT_L3_64K)
+ #define PMD_MASK_L3_64K      (~(PMD_SIZE_L3_64K-1))
+-#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((PTRS_PER_PGD_L3_64K * 8) - 1))
++#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1))
+ 
+ /*
+  * 2-levels / 64K pages
+@@ -3136,6 +3136,7 @@ typedef signed int s32;
+ #define _SECTION_SIZE_BITS      30
+ #define _MAX_PHYSMEM_BITS       40
+ #define _MAX_PHYSMEM_BITS_3_17  48
++#define _MAX_PHYSMEM_BITS_52    52
+ 
+ typedef unsigned long long __u64;
+ typedef unsigned long long u64;
+@@ -3215,6 +3216,7 @@ struct machine_specific {
+ 	ulong kern_eframe_offset;
+ 	ulong machine_kexec_start;
+ 	ulong machine_kexec_end;
++	ulong vabits_user;
+ };
+ 
+ struct arm64_stackframe {
+diff --git a/help.c b/help.c
+index ff0c80b..ba15dec 100644
+--- a/help.c
++++ b/help.c
+@@ -179,6 +179,7 @@ char *program_usage_info[] = {
+     "    ARM64:",
+     "      phys_offset=<physical-address>",
+     "      kimage_voffset=<kimage_voffset-value>",
++    "      max_physmem_bits=<value>",
+     "    X86:",
+     "      page_offset=<CONFIG_PAGE_OFFSET-value>",
+     "",
diff --git a/SOURCES/github_95daa11b.patch b/SOURCES/github_95daa11b.patch
new file mode 100644
index 0000000..b36d5ab
--- /dev/null
+++ b/SOURCES/github_95daa11b.patch
@@ -0,0 +1,23 @@
+commit 95daa11b82dfa6aa3e68ffc92e1282abc1b2b62a
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jun 1 15:28:55 2018 -0400
+
+    Fix for the "bpf -t" option.  Although highly unlikely, without the
+    patch, the target function name of a BPF bytecode call instruction
+    may fail to be resolved correctly.
+    (anderson@redhat.com)
+
+diff --git a/bpf.c b/bpf.c
+index ee1986f..427263d 100644
+--- a/bpf.c
++++ b/bpf.c
+@@ -1060,8 +1060,7 @@ static char *__func_get_name(const struct bpf_insn *insn,
+ 		return buff;
+ 
+ 	if (insn->src_reg != BPF_PSEUDO_CALL &&
+-	    insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID &&
+-	    func_id_str[insn->imm]) {
++	    insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID) {
+ //              return func_id_str[insn->imm];
+ 		if (!readmem(symbol_value("func_id_str") + (insn->imm * sizeof(void *)), 
+ 		    KVADDR, &func_id_ptr, sizeof(void *), "func_id_str pointer", 
diff --git a/SOURCES/github_9b494b70_to_eb823b79.patch b/SOURCES/github_9b494b70_to_eb823b79.patch
new file mode 100644
index 0000000..5723118
--- /dev/null
+++ b/SOURCES/github_9b494b70_to_eb823b79.patch
@@ -0,0 +1,1233 @@
+
+commit 9b494b7006bcc7f3f0bf3be9e3c6d3a5e703a728
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue Jun 26 16:00:28 2018 -0400
+
+    Update for the "kmem -V" option to also dump the global entries that
+    are contained in the "vm_numa_stat" array that was introduced in
+    Linux 4.14.  Also, the command output separates the "vm_zone_stat",
+    "vm_node_stat" and "vm_numa_stat" entries into separate sections with
+    "VM_ZONE_STAT", "VM_NODE_STAT" and "VM_NUMA_STAT" headers.  Without
+    the patch, the "vm_zone_stat" and "vm_node_stat" entries are listed
+    together under a "VM_STAT" header.
+    (anderson@redhat.com)
+
+diff --git a/help.c b/help.c
+index 5a52650..638c6ec 100644
+--- a/help.c
++++ b/help.c
+@@ -6451,9 +6451,10 @@ char *help_kmem[] = {
+ "        -C  same as -c, but also dumps all pages in the page_hash_table.",
+ "        -i  displays general memory usage information",
+ "        -v  displays the mapped virtual memory regions allocated by vmalloc().",
+-"        -V  displays the kernel vm_stat table if it exists, the cumulative",
+-"            page_states counter values if they exist, and/or the cumulative",
+-"            vm_event_states counter values if they exist.",
++"        -V  displays the kernel vm_stat table if it exists, or in more recent",
++"            kernels, the vm_zone_stat, vm_node_stat and vm_numa_stat tables,",
++"            the cumulative page_states counter values if they exist, and/or ",
++"            the cumulative, vm_event_states counter values if they exist.",
+ "        -n  display memory node data (if supported).",
+ "        -z  displays per-zone memory statistics.",
+ "        -o  displays each cpu's offset value that is added to per-cpu symbol",
+@@ -6761,24 +6762,69 @@ char *help_kmem[] = {
+ "    f63d5cc0   f6287b80   f83c2000 - f84c3000  1052672",
+ "    ...",
+ " ",
+-"  Dump the vm_table contents:\n",
++"  Dump the virtual memory statistics:\n",
+ "    %s> kmem -V",
+-"           NR_ANON_PAGES: 38989",
+-"          NR_FILE_MAPPED: 3106",
+-"           NR_FILE_PAGES: 169570",
+-"                 NR_SLAB: 32439",
+-"            NR_PAGETABLE: 1181",
+-"           NR_FILE_DIRTY: 4633",
+-"            NR_WRITEBACK: 0",
+-"         NR_UNSTABLE_NFS: 0",
+-"               NR_BOUNCE: 0",
+-"                NUMA_HIT: 63545992",
+-"               NUMA_MISS: 0",
+-"            NUMA_FOREIGN: 0",
+-"     NUMA_INTERLEAVE_HIT: 24002",
+-"              NUMA_LOCAL: 63545992",
+-"              NUMA_OTHER: 0",
+-" ",
++"      VM_ZONE_STAT:",
++"             NR_FREE_PAGES: 30085",
++"     NR_ZONE_INACTIVE_ANON: 1985",
++"       NR_ZONE_ACTIVE_ANON: 338275",
++"     NR_ZONE_INACTIVE_FILE: 19760",
++"       NR_ZONE_ACTIVE_FILE: 12018",
++"       NR_ZONE_UNEVICTABLE: 0",
++"     NR_ZONE_WRITE_PENDING: 4",
++"                  NR_MLOCK: 0",
++"              NR_PAGETABLE: 1562",
++"        NR_KERNEL_STACK_KB: 1728",
++"                 NR_BOUNCE: 0",
++"         NR_FREE_CMA_PAGES: 0",
++"    ",
++"      VM_NODE_STAT:",
++"          NR_INACTIVE_ANON: 1985",
++"            NR_ACTIVE_ANON: 338275",
++"          NR_INACTIVE_FILE: 19760",
++"            NR_ACTIVE_FILE: 12018",
++"            NR_UNEVICTABLE: 0",
++"       NR_SLAB_RECLAIMABLE: 3111",
++"     NR_SLAB_UNRECLAIMABLE: 3039",
++"          NR_ISOLATED_ANON: 0",
++"          NR_ISOLATED_FILE: 0",
++"        WORKINGSET_REFAULT: 0",
++"       WORKINGSET_ACTIVATE: 0",
++"    WORKINGSET_NODERECLAIM: 0",
++"            NR_ANON_MAPPED: 338089",
++"            NR_FILE_MAPPED: 8102",
++"             NR_FILE_PAGES: 33949",
++"             NR_FILE_DIRTY: 4",
++"              NR_WRITEBACK: 0",
++"         NR_WRITEBACK_TEMP: 0",
++"                  NR_SHMEM: 2171",
++"             NR_SHMEM_THPS: 0",
++"        NR_SHMEM_PMDMAPPED: 0",
++"              NR_ANON_THPS: 86",
++"           NR_UNSTABLE_NFS: 0",
++"           NR_VMSCAN_WRITE: 0",
++"       NR_VMSCAN_IMMEDIATE: 0",
++"                NR_DIRTIED: 155",
++"                NR_WRITTEN: 75",
++"    ",
++"      VM_NUMA_STAT:",
++"                  NUMA_HIT: 575409",
++"                 NUMA_MISS: 0",
++"              NUMA_FOREIGN: 0",
++"       NUMA_INTERLEAVE_HIT: 12930",
++"                NUMA_LOCAL: 575409",
++"                NUMA_OTHER: 0",
++"    ",
++"      VM_EVENT_STATES:",
++"                           PGPGIN: 282492",
++"                          PGPGOUT: 6773",
++"                           PSWPIN: 0",
++"                          PSWPOUT: 0",
++"                      PGALLOC_DMA: 0",
++"                    PGALLOC_DMA32: 693092",
++"                   PGALLOC_NORMAL: 0",
++"    ...",
++"    ",
+ "  Display hugepage hstate information: \n",
+ "    %s> kmem -h",
+ "         HSTATE        SIZE    FREE   TOTAL  NAME",
+diff --git a/memory.c b/memory.c
+index 5c0a853..81ed689 100644
+--- a/memory.c
++++ b/memory.c
+@@ -17422,7 +17422,7 @@ vm_stat_init(void)
+ 	int c ATTRIBUTE_UNUSED;
+         struct gnu_request *req;
+ 	char *start;
+-	long enum_value, zc = -1;
++	long enum_value, zone_cnt = -1, node_cnt = -1;
+ 	int split_vmstat = 0, ni = 0;
+ 
+ 	if (vt->flags & VM_STAT)
+@@ -17451,11 +17451,21 @@ vm_stat_init(void)
+ 		} else if (symbol_exists("vm_zone_stat") &&
+ 			get_symbol_type("vm_zone_stat",
+ 			NULL, NULL) == TYPE_CODE_ARRAY) {
+-			vt->nr_vm_stat_items =
+-				get_array_length("vm_zone_stat", NULL, 0)
+-				+ get_array_length("vm_node_stat", NULL, 0);
+-			split_vmstat = 1;
+-			enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc);
++			if (symbol_exists("vm_numa_stat")) {
++				vt->nr_vm_stat_items =
++					get_array_length("vm_zone_stat", NULL, 0)
++					+ get_array_length("vm_node_stat", NULL, 0) 
++					+ get_array_length("vm_numa_stat", NULL, 0);
++				split_vmstat = 2;
++				enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt);
++				enumerator_value("NR_VM_NODE_STAT_ITEMS", &node_cnt);
++			} else {
++				vt->nr_vm_stat_items =
++					get_array_length("vm_zone_stat", NULL, 0)
++					+ get_array_length("vm_node_stat", NULL, 0);
++				split_vmstat = 1;
++				enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt);
++			}
+ 		} else {
+ 			goto bailout;
+ 		}
+@@ -17468,13 +17478,20 @@ vm_stat_init(void)
+         req->flags = GNU_PRINT_ENUMERATORS;
+         gdb_interface(req);
+ 
+-	if (split_vmstat) {
++	if (split_vmstat >= 1) {
+ 		req->command = GNU_GET_DATATYPE;
+ 		req->name = "node_stat_item";
+ 		req->flags = GNU_PRINT_ENUMERATORS;
+ 		gdb_interface(req);
+ 	}
+ 
++	if (split_vmstat == 2) {
++		req->command = GNU_GET_DATATYPE;
++		req->name = "numa_stat_item";
++		req->flags = GNU_PRINT_ENUMERATORS;
++		gdb_interface(req);
++	}
++
+         FREEBUF(req);
+ 
+ 	stringlen = 1;
+@@ -17488,15 +17505,20 @@ vm_stat_init(void)
+ 		c = parse_line(buf, arglist);
+ 		if ((!split_vmstat &&
+ 			STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) ||
+-			(split_vmstat &&
+-			STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS"))) {
++			((split_vmstat == 1) &&
++			STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS")) ||
++			((split_vmstat == 2) &&
++			STREQ(arglist[0], "NR_VM_NUMA_STAT_ITEMS"))) {
+ 			if (LKCD_KERNTYPES())
+ 				vt->nr_vm_stat_items = 
+ 					MAX(atoi(arglist[2]), count);
+ 			break;
+-		} else if (split_vmstat &&
++		} else if ((split_vmstat == 1) &&
+ 			STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
+ 			continue;
++		} else if ((split_vmstat == 2) && 
++			STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS")) {
++			continue;
+ 		} else {
+ 			stringlen += strlen(arglist[0]) + 1;
+ 			count++;
+@@ -17523,8 +17545,11 @@ vm_stat_init(void)
+ 		}
+ 
+ 		i = ni + enum_value;
+-		if (!ni && (enum_value == zc)) {
+-			ni = zc;
++		if (!ni && (enum_value == zone_cnt)) {
++			ni = zone_cnt;
++			continue;
++		} else if ((ni == zone_cnt) && (enum_value == node_cnt)) {
++			ni += node_cnt;
+ 			continue;
+ 		}
+ 
+@@ -17556,8 +17581,8 @@ dump_vm_stat(char *item, long *retval, ulong zone)
+ 	char *buf;
+ 	ulong *vp;
+ 	ulong location;
+-	int i, maxlen, len;
+-	long tc, zc = 0, nc = 0;
++	int i, maxlen, len, node_start = -1, numa_start = 1;
++	long total_cnt, zone_cnt = 0, node_cnt = 0, numa_cnt = 0;
+ 	int split_vmstat = 0;
+ 
+ 	if (!vm_stat_init()) {
+@@ -17570,48 +17595,86 @@ dump_vm_stat(char *item, long *retval, ulong zone)
+ 
+ 	buf = GETBUF(sizeof(ulong) * vt->nr_vm_stat_items);
+ 
+-	if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat"))
++	if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat") &&
++	    symbol_exists("vm_numa_stat"))
++		split_vmstat = 2;
++	else if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat"))
+ 		split_vmstat = 1;
+ 	else
+ 		location = zone ? zone : symbol_value("vm_stat");
+ 
+-	if (split_vmstat) {
+-		enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc);
++	if (split_vmstat == 1) {
++		enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt);
+ 		location = zone ? zone : symbol_value("vm_zone_stat");
+ 		readmem(location, KVADDR, buf,
+-			sizeof(ulong) * zc,
++			sizeof(ulong) * zone_cnt,
+ 			"vm_zone_stat", FAULT_ON_ERROR);
+ 		if (!zone) {
+ 			location = symbol_value("vm_node_stat");
+-			enumerator_value("NR_VM_NODE_STAT_ITEMS", &nc);
+-			readmem(location, KVADDR, buf + (sizeof(ulong) * zc),
+-				sizeof(ulong) * nc,
++			enumerator_value("NR_VM_NODE_STAT_ITEMS", &node_cnt);
++			readmem(location, KVADDR, buf + (sizeof(ulong) * zone_cnt),
++				sizeof(ulong) * node_cnt,
+ 				"vm_node_stat", FAULT_ON_ERROR);
+ 		}
+-		tc = zc + nc;
++		node_start = zone_cnt;
++		total_cnt = zone_cnt + node_cnt;
++	} else if (split_vmstat == 2) {
++		enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt);
++		location = zone ? zone : symbol_value("vm_zone_stat");
++		readmem(location, KVADDR, buf,
++			sizeof(ulong) * zone_cnt,
++			"vm_zone_stat", FAULT_ON_ERROR);
++		if (!zone) {
++			location = symbol_value("vm_node_stat");
++			enumerator_value("NR_VM_NODE_STAT_ITEMS", &node_cnt);
++			readmem(location, KVADDR, buf + (sizeof(ulong) * zone_cnt),
++				sizeof(ulong) * node_cnt,
++				"vm_node_stat", FAULT_ON_ERROR);
++		}
++		node_start = zone_cnt;
++		if (!zone) {
++			location = symbol_value("vm_numa_stat");
++			enumerator_value("NR_VM_NUMA_STAT_ITEMS", &numa_cnt);
++			readmem(location, KVADDR, buf + (sizeof(ulong) * (zone_cnt+node_cnt)),
++				sizeof(ulong) * numa_cnt,
++				"vm_numa_stat", FAULT_ON_ERROR);
++		}
++		numa_start = zone_cnt+node_cnt;
++		total_cnt = zone_cnt + node_cnt + numa_cnt;
+ 	} else {
+ 		readmem(location, KVADDR, buf,
+ 			sizeof(ulong) * vt->nr_vm_stat_items,
+ 			"vm_stat", FAULT_ON_ERROR);
+-		tc = vt->nr_vm_stat_items;
++		total_cnt = vt->nr_vm_stat_items;
+ 	}
+ 
+ 	if (!item) {
+-		if (!zone)
+-			fprintf(fp, "  VM_STAT:\n");
+-		for (i = maxlen = 0; i < tc; i++)
++		if (!zone) {
++			if (symbol_exists("vm_zone_stat"))
++				fprintf(fp, "  VM_ZONE_STAT:\n");
++			else
++				fprintf(fp, "  VM_STAT:\n");
++		}
++		for (i = maxlen = 0; i < total_cnt; i++)
+ 			if ((len = strlen(vt->vm_stat_items[i])) > maxlen)
+ 				maxlen = len;
+ 		vp = (ulong *)buf;
+-		for (i = 0; i < tc; i++)
++		for (i = 0; i < total_cnt; i++) {
++			if (!zone) {
++				if ((i == node_start) && symbol_exists("vm_node_stat")) 
++					fprintf(fp, "\n  VM_NODE_STAT:\n"); 
++				if ((i == numa_start) && symbol_exists("vm_numa_stat")) 
++					fprintf(fp, "\n  VM_NUMA_STAT:\n"); 
++			}
+ 			fprintf(fp, "%s%s: %ld\n",
+ 				space(maxlen - strlen(vt->vm_stat_items[i])),
+ 				 vt->vm_stat_items[i], vp[i]);
++		}
+ 		return TRUE;
+ 	}
+ 
+ 	vp = (ulong *)buf;
+-	for (i = 0; i < tc; i++) {
++	for (i = 0; i < total_cnt; i++) {
+ 		if (STREQ(vt->vm_stat_items[i], item)) {
+ 			*retval = vp[i];
+ 			return TRUE;
+
+commit f294197b5511537e6b14d5e1db324f4fc4fdd3f8
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jul 6 10:57:50 2018 -0400
+
+    Support for the "bpf" command on RHEL 3.10.0-913.el7 and later
+    3.10-based RHEL7 kernels, which contain a backport of the upstream
+    eBPF code, but still use the older, pre-4.11, IDR facility that does
+    not use radix trees for linking the active bpf_prog and bpf_map
+    structures.  Without the patch, the command indicates "bpf: command
+    not supported or applicable on this architecture or kernel".
+    (anderson@redhat.com)
+
+diff --git a/bpf.c b/bpf.c
+index 427263d..8871b76 100644
+--- a/bpf.c
++++ b/bpf.c
+@@ -45,6 +45,10 @@ static void bpf_prog_gpl_compatible(char *, ulong);
+ static void dump_xlated_plain(void *, unsigned int, int);
+ static void print_boot_time(unsigned long long, char *, unsigned int);
+ 
++static int do_old_idr(int, ulong, struct radix_tree_pair *);
++#define OLD_IDR_INIT   (1)
++#define OLD_IDR_COUNT  (2)
++#define OLD_IDR_GATHER (3)
+ 
+ #define PROG_ID        (0x1)
+ #define MAP_ID         (0x2)
+@@ -167,7 +171,6 @@ bpf_init(struct bpf_info *bpf)
+ 		    !VALID_STRUCT(bpf_map) ||
+ 		    !VALID_STRUCT(bpf_insn) ||
+ 		    INVALID_MEMBER(bpf_prog_aux) ||
+-		    INVALID_MEMBER(idr_idr_rt) ||
+ 		    INVALID_MEMBER(bpf_prog_type) ||
+ 		    INVALID_MEMBER(bpf_prog_tag) ||
+ 		    INVALID_MEMBER(bpf_prog_jited_len) ||
+@@ -210,6 +213,9 @@ bpf_init(struct bpf_info *bpf)
+ 			mkstring(buf2, VADDR_PRLEN, CENTER|LJUST, "BPF_MAP"),
+ 			mkstring(buf3, bpf->bpf_map_map_type_size, CENTER|LJUST, "BPF_MAP_TYPE"));
+ 
++		if (INVALID_MEMBER(idr_idr_rt))
++			do_old_idr(OLD_IDR_INIT, 0, NULL);
++
+ 		bpf->status = TRUE;
+ 		break;
+ 
+@@ -220,24 +226,38 @@ bpf_init(struct bpf_info *bpf)
+ 		command_not_supported();
+ 	}
+ 
+-	bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt),
+-		RADIX_TREE_COUNT, NULL);
++	if (VALID_MEMBER(idr_idr_rt))
++		bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt),
++			RADIX_TREE_COUNT, NULL);
++	else 
++		bpf->progs = do_old_idr(OLD_IDR_COUNT, symbol_value("prog_idr"), NULL);
++
+ 	if (bpf->progs) {
+ 		len = sizeof(struct radix_tree_pair) * (bpf->progs+1);
+ 		bpf->proglist = (struct radix_tree_pair *)GETBUF(len);
+ 		bpf->proglist[0].index = bpf->progs;
+-		bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt),
+-			RADIX_TREE_GATHER, bpf->proglist);
++		if (VALID_MEMBER(idr_idr_rt))
++			bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt),
++				RADIX_TREE_GATHER, bpf->proglist);
++		else
++			bpf->progs = do_old_idr(OLD_IDR_GATHER, symbol_value("prog_idr"), bpf->proglist);
+ 	}
+ 
+-	bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), 
+-		RADIX_TREE_COUNT, NULL);
++	if (VALID_MEMBER(idr_idr_rt))
++		bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), 
++			RADIX_TREE_COUNT, NULL);
++	else
++		bpf->maps = do_old_idr(OLD_IDR_COUNT, symbol_value("map_idr"), NULL);
++
+ 	if (bpf->maps) {
+ 		len = sizeof(struct radix_tree_pair) * (bpf->maps+1);
+ 		bpf->maplist = (struct radix_tree_pair *)GETBUF(len);
+ 		bpf->maplist[0].index = bpf->maps;
+-		bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt),
+-			RADIX_TREE_GATHER, bpf->maplist);
++		if (VALID_MEMBER(idr_idr_rt))
++			bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt),
++				RADIX_TREE_GATHER, bpf->maplist);
++		else
++			bpf->maps = do_old_idr(OLD_IDR_GATHER, symbol_value("map_idr"), bpf->maplist);
+ 	}
+ 
+ 	bpf->bpf_prog_buf = GETBUF(SIZE(bpf_prog));
+@@ -538,8 +558,10 @@ do_map_only:
+ 	}
+ 
+ bailout:
+-	FREEBUF(bpf->proglist);
+-	FREEBUF(bpf->maplist);
++	if (bpf->proglist)
++		FREEBUF(bpf->proglist);
++	if (bpf->maplist)
++		FREEBUF(bpf->maplist);
+ 	FREEBUF(bpf->bpf_prog_buf);
+ 	FREEBUF(bpf->bpf_prog_aux_buf);
+ 	FREEBUF(bpf->bpf_map_buf);
+@@ -1255,3 +1277,50 @@ print_boot_time(unsigned long long nsecs, char *buf, unsigned int size)
+ 	sprintf(buf, "(unknown)");
+ #endif
+ }
++
++/*
++ *  Borrow the old (pre-radix_tree) IDR facility code used by
++ *  the ipcs command.
++ */
++static int
++do_old_idr(int cmd, ulong idr, struct radix_tree_pair *rtp)
++{
++	int i, max, cur, next_id, total = 0;
++	ulong entry;
++
++	switch (cmd)
++	{
++	case OLD_IDR_INIT:
++		ipcs_init();
++		break;
++
++	case OLD_IDR_COUNT:
++		readmem(idr + OFFSET(idr_cur), KVADDR, &cur, 
++			sizeof(int), "idr.cur", FAULT_ON_ERROR);
++		for (total = next_id = 0; next_id < cur; next_id++) {
++			entry = idr_find(idr, next_id);
++			if (entry == 0)
++				continue;
++			total++;
++		}
++		break;
++
++	case OLD_IDR_GATHER:
++		max = rtp[0].index;
++		readmem(idr + OFFSET(idr_cur), KVADDR, &cur, 
++			sizeof(int), "idr.cur", FAULT_ON_ERROR);
++		for (i = total = next_id = 0; next_id < cur; next_id++) {
++			entry = idr_find(idr, next_id);
++			if (entry == 0)
++				continue;
++			total++;
++			rtp[i].index = next_id;
++			rtp[i].value = (void *)entry;
++			if (++i == max)
++				break;
++		}
++		break;
++	}
++
++	return total;
++}
+diff --git a/defs.h b/defs.h
+index e6e3850..b05aecc 100644
+--- a/defs.h
++++ b/defs.h
+@@ -2031,6 +2031,7 @@ struct offset_table {                    /* stash of commonly-used offsets */
+ 	long bpf_prog_aux_load_time;
+ 	long bpf_prog_aux_user;
+ 	long user_struct_uid;
++	long idr_cur;
+ };
+ 
+ struct size_table {         /* stash of commonly-used sizes */
+@@ -5591,6 +5592,12 @@ enum {
+ void dev_init(void);
+ void dump_dev_table(void);
+ 
++/*
++ *  ipcs.c
++ */
++void ipcs_init(void);
++ulong idr_find(ulong, int);
++
+ #ifdef ARM
+ void arm_init(int);
+ void arm_dump_machdep_table(ulong);
+diff --git a/ipcs.c b/ipcs.c
+index ef51fdd..80f78e4 100644
+--- a/ipcs.c
++++ b/ipcs.c
+@@ -79,13 +79,11 @@ struct ipcs_table {
+  * function declaration
+  */
+ 
+-static void ipcs_init(void);
+ static int dump_shared_memory(int, ulong, int, ulong);
+ static int dump_semaphore_arrays(int, ulong, int, ulong);
+ static int dump_message_queues(int, ulong, int, ulong);
+ static int ipc_search_idr(ulong, int, ulong, int (*)(ulong, int, ulong, int, int), int);
+ static int ipc_search_array(ulong, int, ulong, int (*)(ulong, int, ulong, int, int), int);
+-static ulong idr_find(ulong, int);
+ static int dump_shm_info(ulong, int, ulong, int, int);
+ static int dump_sem_info(ulong, int, ulong, int, int);
+ static int dump_msg_info(ulong, int, ulong, int, int);
+@@ -101,7 +99,7 @@ static void gather_radix_tree_entries(ulong);
+  */
+ static struct ipcs_table ipcs_table = { 0 };
+ 
+-static void
++void
+ ipcs_init(void)
+ {
+ 	if (ipcs_table.init_flags & IPCS_INIT) {
+@@ -119,6 +117,7 @@ ipcs_init(void)
+ 	MEMBER_OFFSET_INIT(idr_layer_layer, "idr_layer", "layer");
+ 	MEMBER_OFFSET_INIT(idr_layer_ary, "idr_layer", "ary");
+ 	MEMBER_OFFSET_INIT(idr_top, "idr", "top");
++	MEMBER_OFFSET_INIT(idr_cur, "idr", "cur");
+ 	MEMBER_OFFSET_INIT(ipc_id_ary_p, "ipc_id_ary", "p");
+ 	MEMBER_OFFSET_INIT(ipc_ids_entries, "ipc_ids", "entries");
+ 	MEMBER_OFFSET_INIT(ipc_ids_max_id, "ipc_ids", "max_id");
+@@ -188,7 +187,10 @@ ipcs_init(void)
+ 		ipcs_table.shm_f_op_huge_addr = -1;
+ 	}
+ 
+-	if (BITS32())
++	if (VALID_MEMBER(idr_layer_ary) && 
++	    get_array_length("idr_layer.ary", NULL, 0) > 64)
++		ipcs_table.idr_bits = 8;
++	else if (BITS32())
+ 		ipcs_table.idr_bits = 5;
+ 	else if (BITS64())
+ 		ipcs_table.idr_bits = 6;
+@@ -635,7 +637,7 @@ ipc_search_idr(ulong ipc_ids_p, int specified, ulong specified_value, int (*fn)(
+ /*
+  * search every idr_layer
+  */
+-static ulong
++ulong
+ idr_find(ulong idp, int id)
+ {
+ 	ulong idr_layer_p;
+diff --git a/symbols.c b/symbols.c
+index bf55319..8ff1430 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -10055,6 +10055,8 @@ dump_offset_table(char *spec, ulong makestruct)
+ 		OFFSET(idr_layers));
+ 	fprintf(fp, "                       idr_top: %ld\n",
+ 		OFFSET(idr_top));
++	fprintf(fp, "                       idr_cur: %ld\n",
++		OFFSET(idr_cur));
+ 	fprintf(fp, "                  ipc_id_ary_p: %ld\n",
+ 		OFFSET(ipc_id_ary_p));
+ 	fprintf(fp, "               ipc_ids_entries: %ld\n",
+
+commit b21633026a725a10b9394aabc65d8c57d5bbe33a
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue Jul 10 15:24:38 2018 -0400
+
+    Third phase of support for x86_64 5-level page tables in Linux 4.17
+    and later kernels.  With this patch, the usage of 5-level page tables
+    is automatically detected on live systems and when running against
+    vmcores that contain the new "NUMBER(pgtable_l5_enabled)" VMCOREINFO
+    entry.  Without the patch, the "--machdep vm=5level" command line
+    option is required.
+    (douly.fnst@cn.fujitsu.com, anderson@redhat.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index 6d1ae2f..b07d6f2 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -294,25 +294,6 @@ x86_64_init(int when)
+ 			machdep->machspec->pgdir_shift = PGDIR_SHIFT;
+ 			machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD;
+ 			break;
+-
+-		case VM_5LEVEL:
+-			machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL;
+-			machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL;
+-			machdep->machspec->vmalloc_start_addr = VMALLOC_START_ADDR_5LEVEL;
+-			machdep->machspec->vmalloc_end = VMALLOC_END_5LEVEL;
+-			machdep->machspec->modules_vaddr = MODULES_VADDR_5LEVEL;
+-			machdep->machspec->modules_end = MODULES_END_5LEVEL;
+-			machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_5LEVEL;
+-			machdep->machspec->vmemmap_end = VMEMMAP_END_5LEVEL;
+-			if (symbol_exists("vmemmap_populate"))
+-				machdep->flags |= VMEMMAP;
+-			machdep->machspec->physical_mask_shift = __PHYSICAL_MASK_SHIFT_5LEVEL;
+-			machdep->machspec->pgdir_shift = PGDIR_SHIFT_5LEVEL;
+-			machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD_5LEVEL;
+-			if ((machdep->machspec->p4d = (char *)malloc(PAGESIZE())) == NULL)
+-				error(FATAL, "cannot malloc p4d space.");
+-			machdep->machspec->last_p4d_read = 0;
+-			machdep->uvtop = x86_64_uvtop_level4;  /* 5-level is optional per-task */
+ 		}
+ 	        machdep->kvbase = (ulong)PAGE_OFFSET;
+ 		machdep->identity_map_base = (ulong)PAGE_OFFSET;
+@@ -346,6 +327,43 @@ x86_64_init(int when)
+ 		break;
+ 
+ 	case POST_RELOC:
++		/* Check for 5-level paging */
++		if (!(machdep->flags & VM_5LEVEL)) {
++			int l5_enabled = 0;
++			if ((string = pc->read_vmcoreinfo("NUMBER(pgtable_l5_enabled)"))) {
++				l5_enabled = atoi(string);
++				free(string);
++			} else if (kernel_symbol_exists("__pgtable_l5_enabled"))
++				readmem(symbol_value("__pgtable_l5_enabled"), KVADDR,
++					&l5_enabled, sizeof(int), "__pgtable_l5_enabled",
++					FAULT_ON_ERROR);
++
++			if (l5_enabled)
++				machdep->flags |= VM_5LEVEL;
++		}
++		if (machdep->flags & VM_5LEVEL) {
++			machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL;
++			machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL;
++			machdep->machspec->vmalloc_start_addr = VMALLOC_START_ADDR_5LEVEL;
++			machdep->machspec->vmalloc_end = VMALLOC_END_5LEVEL;
++			machdep->machspec->modules_vaddr = MODULES_VADDR_5LEVEL;
++			machdep->machspec->modules_end = MODULES_END_5LEVEL;
++			machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_5LEVEL;
++			machdep->machspec->vmemmap_end = VMEMMAP_END_5LEVEL;
++			if (symbol_exists("vmemmap_populate"))
++				machdep->flags |= VMEMMAP;
++			machdep->machspec->physical_mask_shift = __PHYSICAL_MASK_SHIFT_5LEVEL;
++			machdep->machspec->pgdir_shift = PGDIR_SHIFT_5LEVEL;
++			machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD_5LEVEL;
++			if ((machdep->machspec->p4d = (char *)malloc(PAGESIZE())) == NULL)
++				error(FATAL, "cannot malloc p4d space.");
++			machdep->machspec->last_p4d_read = 0;
++			machdep->uvtop = x86_64_uvtop_level4;  /* 5-level is optional per-task */
++			machdep->kvbase = (ulong)PAGE_OFFSET;
++			machdep->identity_map_base = (ulong)PAGE_OFFSET;
++
++		}
++
+ 		/*
+ 		 *  Check for CONFIG_RANDOMIZE_MEMORY, and set page_offset here.
+ 		 *  The remainder of the virtual address range setups will get
+
+commit 6596f1121b89162f96d1e1825c2905b83b59bec1
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Jul 11 16:25:59 2018 -0400
+
+    The existing "list" command uses a hash table to detect duplicate
+    items as it traverses the list.  The hash table approach has worked
+    well for many years.  However, with increasing memory sizes and list
+    sizes, the overhead of the hash table can be substantial, often
+    leading to commands running for a very long time.  For large lists,
+    we have found that the existing hash based approach may slow the
+    system to a crawl and possibly never complete.  You can turn off
+    the hash with "set hash off" but then there is no loop detection; in
+    that case, loop detection must be done manually after dumping the
+    list to disk or some other method.  This patch is an implementation
+    of the cycle detection algorithm from R. P. Brent as an alternative
+    algorithm for the "list" command.  The algorithm both avoids the
+    overhead of the hash table and yet is able to detect a loop.  In
+    addition, further loop characteristics are printed, such as the
+    distance to the start of the loop as well as the loop length.
+    An excellent description of the algorithm can be found here on
+    the crash-utility mailing list:
+    
+    https://www.redhat.com/archives/crash-utility/2018-July/msg00019.html
+    
+    A new "list -B" option has been added to the "list" command to
+    invoke this new algorithm rather than using the hash table.  In
+    addition to low memory usage, the output of the list command is
+    slightly different when a loop is detected.  In addition to printing
+    the first duplicate entry, the length of the loop, and the distance
+    to the loop is output.
+    (dwysocha@redhat.com)
+
+diff --git a/defs.h b/defs.h
+index b05aecc..5af82be 100644
+--- a/defs.h
++++ b/defs.h
+@@ -2491,6 +2491,7 @@ struct list_data {             /* generic structure used by do_list() to walk */
+ #define CALLBACK_RETURN     (VERBOSE << 12)
+ #define LIST_PARSE_MEMBER   (VERBOSE << 13)
+ #define LIST_READ_MEMBER    (VERBOSE << 14)
++#define LIST_BRENT_ALGO     (VERBOSE << 15)
+ 
+ struct tree_data {
+ 	ulong flags;
+@@ -4944,6 +4945,7 @@ char *shift_string_right(char *, int);
+ int bracketed(char *, char *, int);
+ void backspace(int);
+ int do_list(struct list_data *);
++int do_list_no_hash(struct list_data *);
+ struct radix_tree_ops {
+ 	void (*entry)(ulong node, ulong slot, const char *path,
+ 		      ulong index, void *private);
+diff --git a/help.c b/help.c
+index 638c6ec..54bf9b4 100644
+--- a/help.c
++++ b/help.c
+@@ -5724,7 +5724,7 @@ char *help__list[] = {
+ "list",
+ "linked list",
+ "[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
+-"\n       [-r|-h|-H] start",
++"\n       [-r|-B] [-h|-H] start",
+ " ",
+ "  This command dumps the contents of a linked list.  The entries in a linked",
+ "  list are typically data structures that are tied together in one of two",
+@@ -5822,6 +5822,12 @@ char *help__list[] = {
+ "           -r  For a list linked with list_head structures, traverse the list",
+ "               in the reverse order by using the \"prev\" pointer instead",
+ "               of \"next\".",
++"           -B  Use the algorithm from R. P. Brent to detect loops instead of",
++"               using a hash table.  This algorithm uses a tiny fixed amount of",
++"               memory and so is especially helpful for longer lists.  The output",
++"               is slightly different than the normal list output as it will",
++"               print the length of the loop, the start of the loop, and the",
++"               first duplicate in the list.",
+ " ",
+ "  The meaning of the \"start\" argument, which can be expressed symbolically,",
+ "  in hexadecimal format, or an expression evaluating to an address, depends",
+diff --git a/tools.c b/tools.c
+index 1a83643..634aec6 100644
+--- a/tools.c
++++ b/tools.c
+@@ -3266,9 +3266,12 @@ cmd_list(void)
+ 	BZERO(ld, sizeof(struct list_data));
+ 	struct_list_offset = 0;
+ 
+-	while ((c = getopt(argcnt, args, "Hhrs:S:e:o:xdl:")) != EOF) {
++	while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+                 switch(c)
+ 		{
++		case 'B':
++			ld->flags |= LIST_BRENT_ALGO;
++			break;
+ 		case 'H':
+ 			ld->flags |= LIST_HEAD_FORMAT;
+ 			ld->flags |= LIST_HEAD_POINTER;
+@@ -3516,9 +3519,13 @@ next_arg:
+ 	ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
+ 	ld->flags |= VERBOSE;
+ 
+-	hq_open();
+-	c = do_list(ld);
+-	hq_close();
++	if (ld->flags & LIST_BRENT_ALGO)
++		c = do_list_no_hash(ld);
++	else {
++		hq_open();
++		c = do_list(ld);
++		hq_close();
++	}
+ 
+         if (ld->structname_args)
+ 		FREEBUF(ld->structname);
+@@ -3862,6 +3869,283 @@ do_list(struct list_data *ld)
+ 	return count;
+ }
+ 
++static void 
++do_list_debug_entry(struct list_data *ld)
++{
++	int i, others;
++
++	if (CRASHDEBUG(1)) {
++		others = 0;
++		console("             flags: %lx (", ld->flags);
++		if (ld->flags & VERBOSE)
++			console("%sVERBOSE", others++ ? "|" : "");
++		if (ld->flags & LIST_OFFSET_ENTERED)
++			console("%sLIST_OFFSET_ENTERED", others++ ? "|" : "");
++		if (ld->flags & LIST_START_ENTERED)
++			console("%sLIST_START_ENTERED", others++ ? "|" : "");
++		if (ld->flags & LIST_HEAD_FORMAT)
++			console("%sLIST_HEAD_FORMAT", others++ ? "|" : "");
++		if (ld->flags & LIST_HEAD_POINTER)
++			console("%sLIST_HEAD_POINTER", others++ ? "|" : "");
++		if (ld->flags & RETURN_ON_DUPLICATE)
++			console("%sRETURN_ON_DUPLICATE", others++ ? "|" : "");
++		if (ld->flags & RETURN_ON_LIST_ERROR)
++			console("%sRETURN_ON_LIST_ERROR", others++ ? "|" : "");
++		if (ld->flags & RETURN_ON_LIST_ERROR)
++			console("%sRETURN_ON_LIST_ERROR", others++ ? "|" : "");
++		if (ld->flags & LIST_STRUCT_RADIX_10)
++			console("%sLIST_STRUCT_RADIX_10", others++ ? "|" : "");
++		if (ld->flags & LIST_STRUCT_RADIX_16)
++			console("%sLIST_STRUCT_RADIX_16", others++ ? "|" : "");
++		if (ld->flags & LIST_ALLOCATE)
++			console("%sLIST_ALLOCATE", others++ ? "|" : "");
++		if (ld->flags & LIST_CALLBACK)
++			console("%sLIST_CALLBACK", others++ ? "|" : "");
++		if (ld->flags & CALLBACK_RETURN)
++			console("%sCALLBACK_RETURN", others++ ? "|" : "");
++		console(")\n");
++		console("             start: %lx\n", ld->start);
++		console("     member_offset: %ld\n", ld->member_offset);
++		console("  list_head_offset: %ld\n", ld->list_head_offset);
++		console("               end: %lx\n", ld->end);
++		console("         searchfor: %lx\n", ld->searchfor);
++		console("   structname_args: %lx\n", ld->structname_args);
++		if (!ld->structname_args)
++			console("        structname: (unused)\n");
++		for (i = 0; i < ld->structname_args; i++)
++			console("     structname[%d]: %s\n", i, ld->structname[i]);
++		console("            header: %s\n", ld->header);
++		console("          list_ptr: %lx\n", (ulong)ld->list_ptr);
++		console("     callback_func: %lx\n", (ulong)ld->callback_func);
++		console("     callback_data: %lx\n", (ulong)ld->callback_data);
++		console("struct_list_offset: %lx\n", ld->struct_list_offset);
++	}
++}
++
++
++static void 
++do_list_output_struct(struct list_data *ld, ulong next, ulong offset,
++				  unsigned int radix, struct req_entry **e)
++{
++	int i;
++
++	for (i = 0; i < ld->structname_args; i++) {
++		switch (count_chars(ld->structname[i], '.'))
++		{
++			case 0:
++				dump_struct(ld->structname[i],
++					    next - offset, radix);
++				break;
++			default:
++				if (ld->flags & LIST_PARSE_MEMBER)
++					dump_struct_members(ld, i, next);
++				else if (ld->flags & LIST_READ_MEMBER)
++					dump_struct_members_fast(e[i],
++						 radix, next - offset);
++				break;
++		}
++	}
++}
++
++static int 
++do_list_no_hash_readmem(struct list_data *ld, ulong *next_ptr,
++				   ulong readflag)
++{
++	if (!readmem(*next_ptr + ld->member_offset, KVADDR, next_ptr,
++		     sizeof(void *), "list entry", readflag)) {
++		error(INFO, "\ninvalid list entry: %lx\n", *next_ptr);
++		return -1;
++	}
++	return 0;
++}
++
++static ulong brent_x; /* tortoise */
++static ulong brent_y; /* hare */
++static ulong brent_r; /* power */
++static ulong brent_lambda; /* loop length */
++static ulong brent_mu; /* distance to start of loop */
++static ulong brent_loop_detect;
++static ulong brent_loop_exit;
++/*
++ * 'ptr': representative of x or y; modified on return
++ */
++static int 
++brent_f(ulong *ptr, struct list_data *ld, ulong readflag)
++{
++       return do_list_no_hash_readmem(ld, ptr, readflag);
++}
++
++/*
++ * Similar to do_list() but without the hash_table or LIST_ALLOCATE.
++ * Useful for the 'list' command and other callers needing faster list
++ * enumeration.
++ */
++int
++do_list_no_hash(struct list_data *ld)
++{
++	ulong next, last, first, offset;
++	ulong searchfor, readflag;
++	int i, count, ret;
++	unsigned int radix;
++	struct req_entry **e = NULL;
++
++	do_list_debug_entry(ld);
++
++	count = 0;
++	searchfor = ld->searchfor;
++	ld->searchfor = 0;
++	if (ld->flags & LIST_STRUCT_RADIX_10)
++		radix = 10;
++	else if (ld->flags & LIST_STRUCT_RADIX_16)
++		radix = 16;
++	else
++		radix = 0;
++	next = ld->start;
++
++	readflag = ld->flags & RETURN_ON_LIST_ERROR ?
++		(RETURN_ON_ERROR|QUIET) : FAULT_ON_ERROR;
++
++	if (!readmem(next + ld->member_offset, KVADDR, &first, sizeof(void *),
++            "first list entry", readflag)) {
++                error(INFO, "\ninvalid list entry: %lx\n", next);
++		return -1;
++	}
++
++	if (ld->header)
++		fprintf(fp, "%s", ld->header);
++
++	offset = ld->list_head_offset + ld->struct_list_offset;
++
++	if (ld->structname && (ld->flags & LIST_READ_MEMBER)) {
++		e = (struct req_entry **)GETBUF(sizeof(*e) * ld->structname_args);
++		for (i = 0; i < ld->structname_args; i++)
++			e[i] = fill_member_offsets(ld->structname[i]);
++	}
++
++	brent_loop_detect = brent_loop_exit = 0;
++	brent_lambda = 0;
++	brent_r = 2;
++	brent_x = brent_y = next;
++	ret = brent_f(&brent_y, ld, readflag);
++	if (ret == -1)
++		return -1;
++	while (1) {
++		if (!brent_loop_detect && ld->flags & VERBOSE) {
++			fprintf(fp, "%lx\n", next - ld->list_head_offset);
++			if (ld->structname) {
++				do_list_output_struct(ld, next, offset, radix, e);
++			}
++		}
++
++                if (next && brent_loop_exit) {
++			if (ld->flags &
++			    (RETURN_ON_DUPLICATE|RETURN_ON_LIST_ERROR)) {
++				error(INFO, "\nduplicate list entry: %lx\n",
++					brent_x);
++				return -1;
++			}
++			error(FATAL, "\nduplicate list entry: %lx\n", brent_x);
++		}
++
++		if ((searchfor == next) ||
++		    (searchfor == (next - ld->list_head_offset)))
++			ld->searchfor = searchfor;
++
++		count++;
++                last = next;
++
++		if ((ld->flags & LIST_CALLBACK) &&
++		    ld->callback_func((void *)(next - ld->list_head_offset),
++		    ld->callback_data) && (ld->flags & CALLBACK_RETURN))
++			break;
++
++		ret = do_list_no_hash_readmem(ld, &next, readflag);
++		if (ret == -1)
++			return -1;
++
++		if (!brent_loop_detect) {
++			if (brent_x == brent_y) {
++				brent_loop_detect = 1;
++				error(INFO, "loop detected, loop length: %lx\n", brent_lambda);
++				/* reset x and y to start; advance y loop length */
++				brent_mu = 0;
++				brent_x = brent_y = ld->start;
++				while (brent_lambda--) {
++					ret = brent_f(&brent_y, ld, readflag);
++					if (ret == -1)
++						return -1;
++				}
++			} else {
++				if (brent_r == brent_lambda) {
++					brent_x = brent_y;
++					brent_r *= 2;
++					brent_lambda = 0;
++				}
++				brent_y = next;
++				brent_lambda++;
++			}
++		} else {
++			if (!brent_loop_exit && brent_x == brent_y) {
++				brent_loop_exit = 1;
++				error(INFO, "length from start to loop: %lx",
++					brent_mu);
++			} else {
++				ret = brent_f(&brent_x, ld, readflag);
++				if (ret == -1)
++					return -1;
++				ret = brent_f(&brent_y, ld, readflag);
++				if (ret == -1)
++					return -1;
++				brent_mu++;
++			}
++		}
++
++		if (next == 0) {
++			if (ld->flags & LIST_HEAD_FORMAT) {
++				error(INFO, "\ninvalid list entry: 0\n");
++				return -1;
++			}
++			if (CRASHDEBUG(1))
++				console("do_list end: next:%lx\n", next);
++
++			break;
++		}
++
++		if (next == ld->end) {
++			if (CRASHDEBUG(1))
++				console("do_list end: next:%lx == end:%lx\n",
++					next, ld->end);
++			break;
++		}
++
++		if (next == ld->start) {
++			if (CRASHDEBUG(1))
++				console("do_list end: next:%lx == start:%lx\n",
++					next, ld->start);
++			break;
++		}
++
++		if (next == last) {
++			if (CRASHDEBUG(1))
++				console("do_list end: next:%lx == last:%lx\n",
++					next, last);
++			break;
++		}
++
++		if ((next == first) && (count != 1)) {
++			if (CRASHDEBUG(1))
++		      console("do_list end: next:%lx == first:%lx (count %d)\n",
++				next, last, count);
++			break;
++		}
++	}
++
++	if (CRASHDEBUG(1))
++		console("do_list count: %d\n", count);
++
++	return count;
++}
++
+ /*
+  *  Issue a dump_struct_member() call for one or more structure
+  *  members.  Multiple members are passed in a comma-separated
+
+commit 582f8b1ea4bb843f996d5285288e7a12b519ee73
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Jul 12 14:06:22 2018 -0400
+
+    Fix for x86_64 "bt" command to prevent an in-kernel exception frame
+    from not being displayed.  Without the patch, if the RIP in a pt_regs
+    structure on the stack is not a kernel text address, such as a NULL
+    pointer, it is not recognized as an exception frame and the register
+    set is not displayed.
+    (anderson@redhat.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index b07d6f2..15800fb 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -4662,6 +4662,8 @@ x86_64_eframe_verify(struct bt_info *bt, long kvaddr, long cs, long ss,
+ 		    STREQ(sp->name, "page_fault"))
+ 			return TRUE;
+ 			
++		if ((kvaddr + SIZE(pt_regs)) == rsp)
++			return TRUE;
+ 	}
+ 
+         if ((cs == 0x10) && kvaddr) {
+@@ -8393,7 +8395,7 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp)
+ 			*p1 = NULLCHAR;
+ 			p2 = arglist[arg];
+ 			reterror = 0;
+-			offset =  htol(p2+1, RETURN_ON_ERROR, &reterror);
++			offset =  htol(p2+1, RETURN_ON_ERROR|QUIET, &reterror);
+ 			if (reterror)
+ 				continue;
+ 			framesize += offset;
+
+commit 528849c15a02d9162c2dd17f4551390763711ad5
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jul 13 13:50:44 2018 -0400
+
+    Fix for the "repeat" command when the argument consists of an input
+    file construct, for example, "repeat -1 < input_file".  Without the
+    patch, only the first command line in the input file is executed
+    each time.
+    (anderson@redhat.com)
+
+diff --git a/cmdline.c b/cmdline.c
+index aab37ce..ee08f06 100644
+--- a/cmdline.c
++++ b/cmdline.c
+@@ -1,8 +1,8 @@
+ /* cmdline.c - core analysis suite
+  *
+  * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
+- * Copyright (C) 2002-2015,2017 David Anderson
+- * Copyright (C) 2002-2015,2017 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2002-2015,2018 David Anderson
++ * Copyright (C) 2002-2015,2018 Red Hat, Inc. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -2324,6 +2324,9 @@ is_args_input_file(struct command_table_entry *ct, struct args_input_file *aif)
+ 	if (pc->curcmd_flags & NO_MODIFY)
+ 		return FALSE;
+ 
++	if (STREQ(ct->name, "repeat"))
++		return FALSE;
++
+ 	BZERO(aif, sizeof(struct args_input_file));
+ 	retval = FALSE;
+ 
+
+commit 61fcad549faa479e6831d5283387f8f2e4ec9202
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Jul 16 09:32:57 2018 -0400
+
+    Fourth phase of support for x86_64 5-level page tables in Linux 4.17
+    and later kernels.  This patch adds support for user virtual address
+    translation when the kernel is configured with CONFIG_X86_5LEVEL.
+    (douly.fnst@cn.fujitsu.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index 15800fb..4073acb 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -24,7 +24,6 @@ static int x86_64_uvtop(struct task_context *, ulong, physaddr_t *, int);
+ static int x86_64_uvtop_level4(struct task_context *, ulong, physaddr_t *, int);
+ static int x86_64_uvtop_level4_xen_wpt(struct task_context *, ulong, physaddr_t *, int);
+ static int x86_64_uvtop_level4_rhel4_xen_wpt(struct task_context *, ulong, physaddr_t *, int);
+-static int x86_64_task_uses_5level(struct task_context *);
+ static ulong x86_64_vmalloc_start(void);
+ static int x86_64_is_task_addr(ulong);
+ static int x86_64_verify_symbol(const char *, ulong, char);
+@@ -341,6 +340,7 @@ x86_64_init(int when)
+ 			if (l5_enabled)
+ 				machdep->flags |= VM_5LEVEL;
+ 		}
++
+ 		if (machdep->flags & VM_5LEVEL) {
+ 			machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL;
+ 			machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL;
+@@ -361,7 +361,6 @@ x86_64_init(int when)
+ 			machdep->uvtop = x86_64_uvtop_level4;  /* 5-level is optional per-task */
+ 			machdep->kvbase = (ulong)PAGE_OFFSET;
+ 			machdep->identity_map_base = (ulong)PAGE_OFFSET;
+-
+ 		}
+ 
+ 		/*
+@@ -812,7 +811,7 @@ x86_64_dump_machdep_table(ulong arg)
+ 	else if (machdep->uvtop == x86_64_uvtop_level4) {
+         	fprintf(fp, "              uvtop: x86_64_uvtop_level4()");
+ 		if (machdep->flags & VM_5LEVEL)
+-        		fprintf(fp, " or x86_64_uvtop_5level()");
++			fprintf(fp, " (uses 5-level page tables)");
+ 		fprintf(fp, "\n");
+ 	} else if (machdep->uvtop == x86_64_uvtop_level4_xen_wpt)
+         	fprintf(fp, "              uvtop: x86_64_uvtop_level4_xen_wpt()\n");
+@@ -1915,7 +1914,7 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
+ 		goto no_upage;
+ 
+ 	/* If the VM is in 5-level page table */
+-	if (machdep->flags & VM_5LEVEL && x86_64_task_uses_5level(tc)) {
++	if (machdep->flags & VM_5LEVEL) {
+ 		ulong p4d_pte;
+ 		/*
+ 		 *  p4d = p4d_offset(pgd, address);
+@@ -1987,12 +1986,6 @@ no_upage:
+ }
+ 
+ static int
+-x86_64_task_uses_5level(struct task_context *tc)
+-{
+-	return FALSE;
+-}
+-
+-static int
+ x86_64_uvtop_level4_xen_wpt(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose)
+ {
+ 	ulong pgd_pte;
+
+commit eb823b79385f61be97411a06dd57b6fc0973d280
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Jul 16 10:50:19 2018 -0400
+
+    Fix to prevent an unnecessary "read error" message during session
+    initialization on live systems running a kernel that is configured
+    with CONFIG_X86_5LEVEL.  Without the patch, a message indicating
+    "crash: read error: kernel virtual address: &lt;address>  type:
+    __pgtable_l5_enabled" will be displayed if /proc/kcore gets
+    selected as the live memory source after /dev/mem is determined
+    to be unusable.
+    (anderson@redhat.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index 4073acb..0574041 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -335,7 +335,7 @@ x86_64_init(int when)
+ 			} else if (kernel_symbol_exists("__pgtable_l5_enabled"))
+ 				readmem(symbol_value("__pgtable_l5_enabled"), KVADDR,
+ 					&l5_enabled, sizeof(int), "__pgtable_l5_enabled",
+-					FAULT_ON_ERROR);
++					QUIET|FAULT_ON_ERROR);
+ 
+ 			if (l5_enabled)
+ 				machdep->flags |= VM_5LEVEL;
diff --git a/SOURCES/github_a10917ba_to_e9532aea.patch b/SOURCES/github_a10917ba_to_e9532aea.patch
new file mode 100644
index 0000000..0a858bd
--- /dev/null
+++ b/SOURCES/github_a10917ba_to_e9532aea.patch
@@ -0,0 +1,894 @@
+commit a10917ba3203aa8b20e2aa1b84dc12c1e17445e1
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Jul 19 13:43:07 2018 -0400
+
+    Update for "ps" and "foreach" commands to display and recognize two
+    new process states, "ID" for the TASK_IDLE macro introduced in
+    Linux 4.2, and "NE" for the TASK_NEW bit introduced in Linux 4.8.
+    (k-hagio@ab.jp.nec.com)
+
+diff --git a/help.c b/help.c
+index 54bf9b4..83cda7c 100644
+--- a/help.c
++++ b/help.c
+@@ -837,7 +837,7 @@ char *help_foreach[] = {
+ "   kernel  perform the command(s) on all kernel threads.",
+ "   active  perform the command(s) on the active thread on each CPU.",
+ "    state  perform the command(s) on all tasks in the specified state, which",
+-"           may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA or PA.\n",
++"           may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA, PA, ID or NE.\n",
+ "  If none of the task-identifying arguments above are entered, the command",
+ "  will be performed on all tasks.\n",
+ "  command  select one or more of the following commands to be run on the tasks",
+@@ -1292,7 +1292,7 @@ char *help_ps[] = {
+ "    3. the CPU number that the task ran on last.",
+ "    4. the task_struct address or the kernel stack pointer of the process.",
+ "       (see -s option below)",
+-"    5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA).",
++"    5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA, ID, NE).",
+ "    6. the percentage of physical memory being used by this task.",
+ "    7. the virtual address size of this task in kilobytes.",
+ "    8. the resident set size of this task in kilobytes.",
+diff --git a/task.c b/task.c
+index 1b32629..39fb0de 100644
+--- a/task.c
++++ b/task.c
+@@ -5172,6 +5172,7 @@ static long _WAKING_ = TASK_STATE_UNINITIALIZED;
+ static long _NONINTERACTIVE_ = TASK_STATE_UNINITIALIZED;
+ static long _PARKED_ = TASK_STATE_UNINITIALIZED;
+ static long _NOLOAD_ = TASK_STATE_UNINITIALIZED;
++static long _NEW_ = TASK_STATE_UNINITIALIZED;
+ 
+ #define valid_task_state(X) ((X) != TASK_STATE_UNINITIALIZED)
+ 
+@@ -5249,6 +5250,10 @@ dump_task_states(void)
+ 	if (valid_task_state(_NOLOAD_))
+ 		fprintf(fp, "            NOLOAD: %3ld (0x%lx)\n", 
+ 			_NOLOAD_, _NOLOAD_);
++
++	if (valid_task_state(_NEW_))
++		fprintf(fp, "               NEW: %3ld (0x%lx)\n",
++			_NEW_, _NEW_);
+ }
+ 
+ 
+@@ -5282,6 +5287,7 @@ old_defaults:
+ 	/*
+ 	 *  If the later version of stat_nam[] array exists that contains 
+ 	 *  WAKING, WAKEKILL and PARKED, use it instead of task_state_array[].
++	 *  Available since kernel version 2.6.33 to 4.13.
+ 	 */
+ 	if (((len = get_array_length("stat_nam", NULL, 0)) > 0) &&
+ 	    read_string(symbol_value("stat_nam"), buf, BUFSIZE-1) &&
+@@ -5331,6 +5337,9 @@ old_defaults:
+ 			case 'N':
+ 				_NOLOAD_ = (1 << (i-1));
+ 				break;
++			case 'n':
++				_NEW_ = (1 << (i-1));
++				break;
+ 			}
+ 		}
+ 
+@@ -5393,7 +5402,16 @@ old_defaults:
+ 		_NONINTERACTIVE_ = 64;
+ 	}
+ 
+-	if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
++	if (THIS_KERNEL_VERSION >= LINUX(4,14,0)) {
++		if (valid_task_state(_PARKED_)) {
++			bitpos = _PARKED_;
++			_DEAD_ |= (bitpos << 1);    /* TASK_DEAD */
++			_WAKEKILL_ = (bitpos << 2); /* TASK_WAKEKILL */
++			_WAKING_ = (bitpos << 3);   /* TASK_WAKING */
++			_NOLOAD_ = (bitpos << 4);   /* TASK_NOLOAD */
++			_NEW_ = (bitpos << 5);      /* TASK_NEW */
++		}
++	} else if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
+ 		/*
+ 	 	 * Account for states not listed in task_state_array[]
+ 		 */
+@@ -5481,6 +5499,10 @@ task_state_string_verbose(ulong task, char *buf)
+ 		sprintf(&buf[strlen(buf)], "%sTASK_NOLOAD",
+ 			count++ ? "|" : "");
+ 
++	if (valid_task_state(_NEW_) && (state & _NEW_))
++		sprintf(&buf[strlen(buf)], "%sTASK_NEW",
++			count++ ? "|" : "");
++
+ 	if (valid_task_state(_NONINTERACTIVE_) &&
+ 	    (state & _NONINTERACTIVE_))
+ 		sprintf(&buf[strlen(buf)], "%sTASK_NONINTERACTIVE",
+@@ -5530,7 +5552,11 @@ task_state_string(ulong task, char *buf, int verbose)
+ 	}
+ 
+ 	if (state & _UNINTERRUPTIBLE_) {
+-		sprintf(buf, "UN");
++		if (valid_task_state(_NOLOAD_) &&
++		    (state & _NOLOAD_))
++			sprintf(buf, "ID");
++		else
++			sprintf(buf, "UN");
+ 		valid++; 
+ 		set++;
+ 	}
+@@ -5576,6 +5602,11 @@ task_state_string(ulong task, char *buf, int verbose)
+ 		valid++;
+ 	}
+ 
++	if (state == _NEW_) {
++		sprintf(buf, "NE");
++		valid++;
++	}
++
+ 	if (valid && exclusive) 
+ 		strcat(buf, "EX");
+ 
+@@ -6273,6 +6304,8 @@ cmd_foreach(void)
+ 		    STREQ(args[optind], "DE") ||
+ 		    STREQ(args[optind], "PA") ||
+ 		    STREQ(args[optind], "WA") ||
++		    STREQ(args[optind], "ID") ||
++		    STREQ(args[optind], "NE") ||
+ 		    STREQ(args[optind], "SW")) {
+ 
+ 			if (fd->flags & FOREACH_STATE)
+@@ -6298,6 +6331,10 @@ cmd_foreach(void)
+ 				fd->state = _PARKED_;
+ 			else if (STREQ(args[optind], "WA"))
+ 				fd->state = _WAKING_;
++			else if (STREQ(args[optind], "ID"))
++				fd->state = _UNINTERRUPTIBLE_|_NOLOAD_;
++			else if (STREQ(args[optind], "NE"))
++				fd->state = _NEW_;
+ 
+ 			if (fd->state == TASK_STATE_UNINITIALIZED)
+ 				error(FATAL, 
+@@ -6678,6 +6715,19 @@ foreach(struct foreach_data *fd)
+ 			if (fd->state == _RUNNING_) {
+ 				if (task_state(tc->task) != _RUNNING_)
+ 					continue;
++			} else if (fd->state & _UNINTERRUPTIBLE_) {
++				if (!(task_state(tc->task) & _UNINTERRUPTIBLE_))
++					continue;
++
++				if (valid_task_state(_NOLOAD_)) {
++					if (fd->state & _NOLOAD_) {
++						if (!(task_state(tc->task) & _NOLOAD_))
++							continue;
++					} else {
++						if ((task_state(tc->task) & _NOLOAD_))
++							continue;
++					}
++				}
+ 			} else if (!(task_state(tc->task) & fd->state))
+ 				continue;
+ 		}
+
+commit 6c39a3d39b799e1f3f26e8017bcfa458d38d3820
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Aug 8 11:31:17 2018 -0400
+
+    Fix for running live on ARM64 kernels against /proc/kcore on kernels
+    configured with CONFIG_RANDOMIZE_BASE.  Without the patch, depending
+    upon the hardware platform, the session may fail with the error message
+    "crash: vmlinux and /proc/kcore do not match!".
+    (anderson@redhat.com)
+
+diff --git a/arm64.c b/arm64.c
+index 150e7d7..4ee53ce 100644
+--- a/arm64.c
++++ b/arm64.c
+@@ -125,7 +125,8 @@ arm64_init(int when)
+ 			free(string);
+ 		}
+ 
+-		if (ms->kimage_voffset) {
++		if (ms->kimage_voffset ||
++		    (ACTIVE() && (symbol_value_from_proc_kallsyms("kimage_voffset") != BADVAL))) {
+ 			machdep->flags |= NEW_VMEMMAP;
+ 
+ 			/*
+@@ -771,6 +772,17 @@ arm64_calc_kimage_voffset(void)
+ 		char *p1;
+ 		int errflag;
+ 		FILE *iomem;
++		ulong kimage_voffset, vaddr;
++
++		if (pc->flags & PROC_KCORE) {
++			kimage_voffset = symbol_value_from_proc_kallsyms("kimage_voffset");
++			if ((kimage_voffset != BADVAL) && 
++			    (READMEM(pc->mfd, &vaddr, sizeof(ulong),
++			     kimage_voffset, KCORE_USE_VADDR) > 0)) {
++				ms->kimage_voffset = vaddr;
++				return;
++			}
++		}
+ 
+ 		if ((iomem = fopen("/proc/iomem", "r")) == NULL)
+ 			return;
+@@ -838,16 +850,22 @@ arm64_calc_phys_offset(void)
+ 		int errflag;
+ 		FILE *iomem;
+ 		physaddr_t paddr;
++		ulong vaddr;
+ 		struct syment *sp;
+ 
+ 		if ((machdep->flags & NEW_VMEMMAP) &&
+ 		    ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
+-			if (pc->flags & PROC_KCORE)
++			if (pc->flags & PROC_KCORE) {
++				vaddr = symbol_value_from_proc_kallsyms("memstart_addr");
++				if (vaddr == BADVAL)
++					vaddr = sp->value;
+ 				paddr = KCORE_USE_VADDR;
+-			else
++			} else {
++				vaddr = sp->value;
+ 				paddr =	sp->value - machdep->machspec->kimage_voffset;
++			}
+ 			if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
+-			    sp->value, paddr) > 0) {
++			    vaddr, paddr) > 0) {
+ 				ms->phys_offset = phys_offset;
+ 				return;
+ 			}
+diff --git a/defs.h b/defs.h
+index 5af82be..da2ae04 100644
+--- a/defs.h
++++ b/defs.h
+@@ -5067,6 +5067,7 @@ struct syment *per_cpu_symbol_search(char *);
+ int symbol_exists(char *s);
+ int kernel_symbol_exists(char *s);
+ struct syment *kernel_symbol_search(char *);
++ulong symbol_value_from_proc_kallsyms(char *);
+ int get_syment_array(char *, struct syment **, int);
+ void set_temporary_radix(unsigned int, unsigned int *);
+ void restore_current_radix(unsigned int);
+diff --git a/symbols.c b/symbols.c
+index 8ff1430..df84ee2 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -28,7 +28,6 @@ static void store_sysmap_symbols(void);
+ static ulong relocate(ulong, char *, int);
+ static int relocate_force(ulong, char *);
+ static void kaslr_init(void);
+-static ulong symbol_value_from_proc_kallsyms(char *);
+ static void strip_module_symbol_end(char *s);
+ static int compare_syms(const void *, const void *);
+ static int compare_mods(const void *, const void *);
+@@ -997,7 +996,7 @@ relocate_force(ulong symval, char *symname)
+ /*
+  *  Get a symbol value from /proc/kallsyms.
+  */
+-static ulong
++ulong
+ symbol_value_from_proc_kallsyms(char *symname)
+ {
+         FILE *kp;
+
+commit 455da1ae5c7f22ba870aa57e071dad340749bdcd
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Aug 8 14:20:21 2018 -0400
+
+    Modify the output of the "kmem -[sS]" header and contents such that
+    the slab cache name string is moved from the second column to the
+    the last column.  Since the slab cache name strings have become
+    increasingly longer over time, without the patch, the numerical
+    column contents may be skewed so far to the right that the output
+    becomes difficult to read.
+    (k-hagio@ab.jp.nec.com)
+
+diff --git a/help.c b/help.c
+index 83cda7c..a189038 100644
+--- a/help.c
++++ b/help.c
+@@ -6692,8 +6692,8 @@ char *help_kmem[] = {
+ "  Find all of the combined slab/page structures that are used by",
+ "  the kmalloc-8192 slab cache:\n",
+ "    %s> kmem -s kmalloc-8192",
+-"    CACHE            NAME             OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE",
+-"    ffff880215802e00 kmalloc-8192        8192         65        80     20    32k",
++"    CACHE             OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME",
++"    ffff880215802e00     8192         65        80     20    32k  kmalloc-8192",
+ "    %s> kmem -m slab_cache | grep ffff880215802e00",
+ "    ffffea0004117800  ffff880215802e00  ",
+ "    ffffea00041ca600  ffff880215802e00  ",
+@@ -6889,72 +6889,72 @@ char *help_kmem[] = {
+ " ",
+ "  Display kmalloc() slab data:\n",
+ "    %s> kmem -s",
+-"    CACHE     NAME                OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE",
+-"    c02eadc0 kmem_cache               232         58        68      4     4k",
+-"    f79c2888 ip_vs_conn               128          0         0      0     4k",
+-"    f79c2970 tcp_tw_bucket             96          0         0      0     4k",
+-"    f79c2a58 tcp_bind_bucket           32         12       565      5     4k",
+-"    f79c2b40 tcp_open_request          64          0        59      1     4k",
+-"    f79c2c28 inet_peer_cache           64          1        59      1     4k",
+-"    f79c2d10 ip_fib_hash               32         11       339      3     4k",
+-"    f79c2df8 ip_dst_cache             160          8       120      5     4k",
+-"    f79c2ee0 arp_cache                128          1        30      1     4k",
+-"    c8402970 blkdev_requests           96      30208     37800    945     4k",
+-"    c8402a58 nfs_read_data            384          0         0      0     4k",
+-"    c8402b40 nfs_write_data           384          0         0      0     4k",
+-"    c8402c28 nfs_page                  96          0         0      0     4k",
+-"    c8402d10 dnotify cache             20          0         0      0     4k",
+-"    c8402df8 file lock cache           92          3       336      8     4k",
+-"    c8402ee0 fasync cache              16          0         0      0     4k",
+-"    c84027a0 uid_cache                 32          3       339      3     4k",
+-"    c84026b8 skbuff_head_cache        160        320       624     26     4k",
+-"    c84025d0 sock                     832         32       180     20     8k",
+-"    c84024e8 sigqueue                 132          0       203      7     4k",
+-"    c8402400 cdev_cache                64         19       472      8     4k",
+-"    c8402318 bdev_cache                64          8       236      4     4k",
+-"    c8402230 mnt_cache                 96         11       120      3     4k",
+-"    c8402148 inode_cache              480        817       848    106     4k",
+-"    c8402060 dentry_cache             128       1352      1470     49     4k",
+-"    c8403ee0 filp                      96        244       440     11     4k",
+-"    c8403df8 names_cache             4096          0        12     12     4k",
+-"    c8403d10 buffer_head               96      14936     16000    400     4k",
+-"    c8403c28 mm_struct                128         25       240      8     4k",
+-"    c8403b40 vm_area_struct            64        393      1298     22     4k",
+-"    c8403a58 fs_cache                  64         30       472      8     4k",
+-"    c8403970 files_cache              416         30       135     15     4k",
+-"    c8403888 signal_act              1312         32        99     33     4k",
+-"    c84037a0 size-131072(DMA)      131072          0         0      0   128k",
+-"    c84036b8 size-131072           131072          1         1      1   128k",
+-"    c84035d0 size-65536(DMA)        65536          0         0      0    64k",
+-"    c84034e8 size-65536             65536          0         0      0    64k",
+-"    c8403400 size-32768(DMA)        32768          0         0      0    32k",
+-"    c8403318 size-32768             32768          0         1      1    32k",
+-"    c8403230 size-16384(DMA)        16384          0         0      0    16k",
+-"    c8403148 size-16384             16384          0         0      0    16k",
+-"    c8403060 size-8192(DMA)          8192          0         0      0     8k",
+-"    c8401ee0 size-8192               8192          1         2      2     8k",
+-"    c8401df8 size-4096(DMA)          4096          0         0      0     4k",
+-"    c8401d10 size-4096               4096         30        30     30     4k",
+-"    c8401c28 size-2048(DMA)          2048          0         0      0     4k",
+-"    c8401b40 size-2048               2048         37       132     66     4k",
+-"    c8401a58 size-1024(DMA)          1024          0         0      0     4k",
+-"    c8401970 size-1024               1024        301       328     82     4k",
+-"    c8401888 size-512(DMA)            512          0         0      0     4k",
+-"    c84017a0 size-512                 512        141       168     21     4k",
+-"    c84016b8 size-256(DMA)            256          0         0      0     4k",
+-"    c84015d0 size-256                 256         80       435     29     4k",
+-"    c84014e8 size-128(DMA)            128          0         0      0     4k",
+-"    c8401400 size-128                 128        508       840     28     4k",
+-"    c8401318 size-64(DMA)              64          0         0      0     4k",
+-"    c8401230 size-64                   64        978      1357     23     4k",
+-"    c8401148 size-32(DMA)              32          0         0      0     4k",
+-"    c8401060 size-32                   32       1244      1808     16     4k",
++"    CACHE     OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME",
++"    c02eadc0      232         58        68      4     4k  kmem_cache",
++"    f79c2888      128          0         0      0     4k  ip_vs_conn",
++"    f79c2970       96          0         0      0     4k  tcp_tw_bucket",
++"    f79c2a58       32         12       565      5     4k  tcp_bind_bucket",
++"    f79c2b40       64          0        59      1     4k  tcp_open_request",
++"    f79c2c28       64          1        59      1     4k  inet_peer_cache",
++"    f79c2d10       32         11       339      3     4k  ip_fib_hash",
++"    f79c2df8      160          8       120      5     4k  ip_dst_cache",
++"    f79c2ee0      128          1        30      1     4k  arp_cache",
++"    c8402970       96      30208     37800    945     4k  blkdev_requests",
++"    c8402a58      384          0         0      0     4k  nfs_read_data",
++"    c8402b40      384          0         0      0     4k  nfs_write_data",
++"    c8402c28       96          0         0      0     4k  nfs_page",
++"    c8402d10       20          0         0      0     4k  dnotify cache",
++"    c8402df8       92          3       336      8     4k  file lock cache",
++"    c8402ee0       16          0         0      0     4k  fasync cache",
++"    c84027a0       32          3       339      3     4k  uid_cache",
++"    c84026b8      160        320       624     26     4k  skbuff_head_cache",
++"    c84025d0      832         32       180     20     8k  sock",
++"    c84024e8      132          0       203      7     4k  sigqueue",
++"    c8402400       64         19       472      8     4k  cdev_cache",
++"    c8402318       64          8       236      4     4k  bdev_cache",
++"    c8402230       96         11       120      3     4k  mnt_cache",
++"    c8402148      480        817       848    106     4k  inode_cache",
++"    c8402060      128       1352      1470     49     4k  dentry_cache",
++"    c8403ee0       96        244       440     11     4k  filp",
++"    c8403df8     4096          0        12     12     4k  names_cache",
++"    c8403d10       96      14936     16000    400     4k  buffer_head",
++"    c8403c28      128         25       240      8     4k  mm_struct",
++"    c8403b40       64        393      1298     22     4k  vm_area_struct",
++"    c8403a58       64         30       472      8     4k  fs_cache",
++"    c8403970      416         30       135     15     4k  files_cache",
++"    c8403888     1312         32        99     33     4k  signal_act",
++"    c84037a0   131072          0         0      0   128k  size-131072(DMA)",
++"    c84036b8   131072          1         1      1   128k  size-131072",
++"    c84035d0    65536          0         0      0    64k  size-65536(DMA)",
++"    c84034e8    65536          0         0      0    64k  size-65536",
++"    c8403400    32768          0         0      0    32k  size-32768(DMA)",
++"    c8403318    32768          0         1      1    32k  size-32768",
++"    c8403230    16384          0         0      0    16k  size-16384(DMA)",
++"    c8403148    16384          0         0      0    16k  size-16384",
++"    c8403060     8192          0         0      0     8k  size-8192(DMA)",
++"    c8401ee0     8192          1         2      2     8k  size-8192",
++"    c8401df8     4096          0         0      0     4k  size-4096(DMA)",
++"    c8401d10     4096         30        30     30     4k  size-4096",
++"    c8401c28     2048          0         0      0     4k  size-2048(DMA)",
++"    c8401b40     2048         37       132     66     4k  size-2048",
++"    c8401a58     1024          0         0      0     4k  size-1024(DMA)",
++"    c8401970     1024        301       328     82     4k  size-1024",
++"    c8401888      512          0         0      0     4k  size-512(DMA)",
++"    c84017a0      512        141       168     21     4k  size-512",
++"    c84016b8      256          0         0      0     4k  size-256(DMA)",
++"    c84015d0      256         80       435     29     4k  size-256",
++"    c84014e8      128          0         0      0     4k  size-128(DMA)",
++"    c8401400      128        508       840     28     4k  size-128",
++"    c8401318       64          0         0      0     4k  size-64(DMA)",
++"    c8401230       64        978      1357     23     4k  size-64",
++"    c8401148       32          0         0      0     4k  size-32(DMA)",
++"    c8401060       32       1244      1808     16     4k  size-32",
+ 
+ " ",
+ "  Display all slab data in the \"arp_cache\" cache:\n",
+ "    %s> kmem -S arp_cache",
+-"    CACHE     NAME                OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE",
+-"    f79c2ee0 arp_cache                128          1        30      1     4k",
++"    CACHE     OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME",
++"    f79c2ee0      128          1        30      1     4k  arp_cache",
+ "    SLAB      MEMORY    TOTAL  ALLOCATED  FREE",
+ "    f729d000  f729d0a0     30          1    29",
+ "    FREE / [ALLOCATED]",
+@@ -6991,8 +6991,8 @@ char *help_kmem[] = {
+ " ",
+ "  Search the kmalloc() slab subsystem for address c3fbdb60:\n",
+ "    %s> kmem -s c3fbdb60",
+-"    CACHE     NAME                OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE",
+-"    c8402970 blkdev_requests           96      30208     37800    945     4k",
++"    CACHE     OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME",
++"    c8402970       96      30208     37800    945     4k  blkdev_requests",
+ "    SLAB      MEMORY    TOTAL  ALLOCATED  FREE",
+ "    c3fbd020  c3fbd0e0     40         40     0",
+ "    FREE / [ALLOCATED]",
+@@ -7000,8 +7000,8 @@ char *help_kmem[] = {
+ " ",
+ "  Make a generic search (no flags) for the same address c3fbdb60:\n",
+ "    %s> kmem c3fbdb60 ",
+-"    CACHE     NAME                OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE",
+-"    c8402970 blkdev_requests           96      30208     37800    945     4k",
++"    CACHE     OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME",
++"    c8402970       96      30208     37800    945     4k  blkdev_requests",
+ "    SLAB      MEMORY    TOTAL  ALLOCATED  FREE",
+ "    c3fbd020  c3fbd0e0     40         40     0 ",
+ "    FREE / [ALLOCATED]",
+diff --git a/memory.c b/memory.c
+index 81ed689..5bcf09e 100644
+--- a/memory.c
++++ b/memory.c
+@@ -172,7 +172,6 @@ static void dump_kmem_cache(struct meminfo *);
+ static void dump_kmem_cache_percpu_v1(struct meminfo *);
+ static void dump_kmem_cache_percpu_v2(struct meminfo *);
+ static void dump_kmem_cache_slub(struct meminfo *);
+-static void dump_kmem_cache_info_v2(struct meminfo *);
+ static void kmem_cache_list_common(void);
+ static ulong get_cpu_slab_ptr(struct meminfo *, int, ulong *);
+ static unsigned int oo_order(ulong);
+@@ -9379,7 +9378,7 @@ kmem_cache_init(void)
+ 
+ 	if (!strlen(kmem_cache_hdr)) 
+ 		sprintf(kmem_cache_hdr,
+-     "CACHE%sNAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE\n",
++     "CACHE%s OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE  NAME\n",
+ 			space(VADDR_PRLEN > 8 ? 12 : 4));
+ 
+ 	if (!strlen(free_inuse_hdr)) 
+@@ -9964,55 +9963,36 @@ ignore_cache(struct meminfo *si, char *name)
+ #define KMEM_SLAB_OVERLOAD_PAGE (8)
+ #define KMEM_SLAB_FREELIST      (9)
+ 
+-#define DUMP_KMEM_CACHE_INFO_V1() \
+-      {  \
+-	char b1[BUFSIZE]; \
+-	fprintf(fp, "%s %-18s  %8ld  ", \
+-		mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)), \
+-        	buf, si->size); \
+-        fprintf(fp, "%9ld  %8ld  %5ld   %3ldk\n", \
+-		vt->flags & PERCPU_KMALLOC_V1 ? \
+-		si->inuse - si->cpucached_cache : \
+-                si->inuse, si->num_slabs * si->c_num, \
+-                si->num_slabs, si->slabsize/1024); \
+-      }
+-
+-#define DUMP_KMEM_CACHE_INFO_V2()  dump_kmem_cache_info_v2(si) 
++#define DUMP_KMEM_CACHE_INFO()  dump_kmem_cache_info(si)
+ 
+ static void
+-dump_kmem_cache_info_v2(struct meminfo *si)
++dump_kmem_cache_info(struct meminfo *si)
+ {
+ 	char b1[BUFSIZE];
+-	char b2[BUFSIZE];
+-	int namelen, sizelen, spacelen;
+-
+-	fprintf(fp, "%s ",
+-		mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache))); 
+-
+-	namelen = strlen(si->curname);
+-	sprintf(b2, "%ld", si->size);
+-	sizelen = strlen(b2);
+-	spacelen = 0;
+-
+-	if (namelen++ > 18) {
+-		spacelen = 29 - namelen - sizelen;
+-		fprintf(fp, "%s%s%ld  ", si->curname,
+-			space(spacelen <= 0 ? 1 : spacelen), si->size); 
+-		if (spacelen > 0)
+-			spacelen = 1;
+-		sprintf(b1, "%c%dld  ", '%', 9 + spacelen - 1);
++	ulong objsize, allocated, total;
++
++	if (si->flags & SLAB_GATHER_FAILURE)
++		error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
++
++	objsize = (vt->flags & KMALLOC_SLUB) ? si->objsize : si->size;
++
++	fprintf(fp, "%s %8ld  ",
++		mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)),
++		objsize);
++
++	if (si->flags & SLAB_GATHER_FAILURE) {
++		fprintf(fp, "%9s  %8s  %5s  ", "?", "?", "?");
+ 	} else {
+-		fprintf(fp, "%-18s  %8ld  ", si->curname, si->size); 
+-		sprintf(b1, "%c%dld  ", '%', 9);
+-	}
++		allocated = (vt->flags & (PERCPU_KMALLOC_V1|PERCPU_KMALLOC_V2)) ?
++				si->inuse - si->cpucached_cache : si->inuse;
++		total = (vt->flags & KMALLOC_SLUB) ?
++				si->inuse + si->free : si->num_slabs * si->c_num;
+ 
+-        fprintf(fp, b1, vt->flags & (PERCPU_KMALLOC_V2) ?
+-                si->inuse - si->cpucached_cache : si->inuse); 
++		fprintf(fp, "%9ld  %8ld  %5ld  ",
++			allocated, total, si->num_slabs);
++	}
+ 
+-	fprintf(fp, "%8ld %s%5ld  %s%3ldk\n",
+-		si->num_slabs * si->c_num, 
+-		si->num_slabs < 100000 ? " " : "", si->num_slabs, 
+-		(si->slabsize/1024) < 1000 ? " " : "", si->slabsize/1024); 
++	fprintf(fp, "%4ldk  %s\n", si->slabsize/1024, si->curname);
+ }
+ 
+ #define DUMP_SLAB_INFO() \
+@@ -10152,7 +10132,7 @@ dump_kmem_cache(struct meminfo *si)
+ 			do_slab_chain(SLAB_GET_COUNTS, si);
+ 
+ 			if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) 
+-				DUMP_KMEM_CACHE_INFO_V1();
++				DUMP_KMEM_CACHE_INFO();
+ 
+ 			if (si->flags == GET_SLAB_PAGES) 
+ 				si->retval += (si->num_slabs * 
+@@ -10166,7 +10146,7 @@ dump_kmem_cache(struct meminfo *si)
+ 
+ 				if (si->found) {
+ 					fprintf(fp, "%s", kmem_cache_hdr);
+-					DUMP_KMEM_CACHE_INFO_V1();
++					DUMP_KMEM_CACHE_INFO();
+ 					fprintf(fp, "%s", slab_hdr);
+ 					DUMP_SLAB_INFO();
+ 
+@@ -10362,7 +10342,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
+ 		do_slab_chain_percpu_v1(SLAB_GET_COUNTS, si);
+ 
+ 		if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
+-			DUMP_KMEM_CACHE_INFO_V1();
++			DUMP_KMEM_CACHE_INFO();
+ 			if (CRASHDEBUG(3))
+ 				dump_struct("kmem_cache_s", si->cache, 0);
+ 		}
+@@ -10382,7 +10362,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
+ 
+ 			if (si->found) {
+ 				fprintf(fp, "%s", kmem_cache_hdr);
+-				DUMP_KMEM_CACHE_INFO_V1();
++				DUMP_KMEM_CACHE_INFO();
+ 				fprintf(fp, "%s", slab_hdr);
+         			gather_slab_cached_count(si);
+ 				DUMP_SLAB_INFO();
+@@ -10617,7 +10597,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
+ 			do_slab_chain_percpu_v2(SLAB_GET_COUNTS, si);
+ 
+ 		if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
+-			DUMP_KMEM_CACHE_INFO_V2();
++			DUMP_KMEM_CACHE_INFO();
+ 			if (CRASHDEBUG(3))
+ 				dump_struct("kmem_cache_s", si->cache, 0);
+ 		}
+@@ -10644,7 +10624,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
+ 
+ 			if (si->found) {
+ 				fprintf(fp, "%s", kmem_cache_hdr);
+-				DUMP_KMEM_CACHE_INFO_V2();
++				DUMP_KMEM_CACHE_INFO();
+ 				fprintf(fp, "%s", slab_hdr);
+         			gather_slab_cached_count(si);
+ 				DUMP_SLAB_INFO();
+@@ -18064,56 +18044,6 @@ kmem_cache_list_common(void)
+ 	FREEBUF(cache_list);
+ }
+ 
+-#define DUMP_KMEM_CACHE_INFO_SLUB()  dump_kmem_cache_info_slub(si)
+-
+-static void
+-dump_kmem_cache_info_slub(struct meminfo *si)
+-{
+-	char b1[BUFSIZE];
+-	char b2[BUFSIZE];
+-	int namelen, sizelen, spacelen;
+-
+-	if (si->flags & SLAB_GATHER_FAILURE)
+-		error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
+-
+-	fprintf(fp, "%s ",
+-		mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache))); 
+-
+-	namelen = strlen(si->curname);
+-	sprintf(b2, "%ld", si->objsize);
+-	sizelen = strlen(b2);
+-	spacelen = 0;
+-
+-	if (namelen++ > 18) {
+-		spacelen = 29 - namelen - sizelen;
+-		fprintf(fp, "%s%s%ld  ", si->curname,
+-			space(spacelen <= 0 ? 1 : spacelen), si->objsize); 
+-		if (spacelen > 0)
+-			spacelen = 1;
+-		if (si->flags & SLAB_GATHER_FAILURE)
+-			sprintf(b1, "%c%ds  ", '%', 9 + spacelen - 1);
+-		else
+-			sprintf(b1, "%c%dld  ", '%', 9 + spacelen - 1);
+-	} else {
+-		fprintf(fp, "%-18s  %8ld  ", si->curname, si->objsize); 
+-		if (si->flags & SLAB_GATHER_FAILURE)
+-			sprintf(b1, "%c%ds  ", '%', 9);
+-		else
+-			sprintf(b1, "%c%dld  ", '%', 9);
+-	}
+-
+-	if (si->flags & SLAB_GATHER_FAILURE) {
+-		fprintf(fp, b1, "?");
+-		fprintf(fp, "%8s  %5s  %4ldk\n",  
+-			"?", "?", si->slabsize/1024); 
+-	} else {
+-		fprintf(fp, b1, si->inuse);
+-		fprintf(fp, "%8ld  %5ld  %4ldk\n",  
+-			si->inuse + si->free,
+-			si->num_slabs, si->slabsize/1024); 
+-	}
+-}
+-
+ static void
+ dump_kmem_cache_slub(struct meminfo *si)
+ {
+@@ -18214,7 +18144,7 @@ dump_kmem_cache_slub(struct meminfo *si)
+ 		    !get_kmem_cache_slub_data(GET_SLUB_OBJECTS, si))
+ 			si->flags |= SLAB_GATHER_FAILURE;
+ 
+-		DUMP_KMEM_CACHE_INFO_SLUB();
++		DUMP_KMEM_CACHE_INFO();
+ 
+ 		if (si->flags & SLAB_GATHER_FAILURE) {
+ 			si->flags &= ~SLAB_GATHER_FAILURE;
+
+commit ba03b66cec24fc0033d4378be08f5f9a96cd4a91
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Aug 9 10:54:46 2018 -0400
+
+    Fix for the "files" and "net -s" commands when a task has an open
+    files count that exceeds 1024 (FD_SETSIZE) file descriptors.  Without
+    the patch, the commands may omit the display of open file descriptors.
+    (tan.hu@zte.com.cn)
+
+diff --git a/filesys.c b/filesys.c
+index 0ace8f4..47f5a24 100644
+--- a/filesys.c
++++ b/filesys.c
+@@ -2380,7 +2380,8 @@ open_files_dump(ulong task, int flags, struct reference *ref)
+ 	int max_fdset = 0;
+ 	int max_fds = 0;
+ 	ulong open_fds_addr;
+-	fd_set open_fds;
++	int open_fds_size;
++	ulong *open_fds;
+ 	ulong fd;
+ 	ulong file;
+ 	ulong value;
+@@ -2583,16 +2584,25 @@ open_files_dump(ulong task, int flags, struct reference *ref)
+ 		open_fds_addr = ULONG(files_struct_buf +
+ 			OFFSET(files_struct_open_fds));
+ 
++	open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;	
++	open_fds = (ulong *)GETBUF(open_fds_size);
++	if (!open_fds) {
++		if (fdtable_buf)
++			FREEBUF(fdtable_buf);
++		FREEBUF(files_struct_buf);
++		return;
++	}
++
+ 	if (open_fds_addr) {
+ 		if (VALID_MEMBER(files_struct_open_fds_init) && 
+ 		    (open_fds_addr == (files_struct_addr + 
+ 		    OFFSET(files_struct_open_fds_init)))) 
+ 			BCOPY(files_struct_buf + 
+ 			        OFFSET(files_struct_open_fds_init),
+-				&open_fds, sizeof(fd_set));
++				open_fds, open_fds_size);
+ 		else
+-			readmem(open_fds_addr, KVADDR, &open_fds,
+-				sizeof(fd_set), "fdtable open_fds",
++			readmem(open_fds_addr, KVADDR, open_fds,
++				open_fds_size, "fdtable open_fds",
+ 				FAULT_ON_ERROR);
+ 	} 
+ 
+@@ -2607,6 +2617,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
+ 		if (fdtable_buf)
+ 			FREEBUF(fdtable_buf);
+ 		FREEBUF(files_struct_buf);
++		FREEBUF(open_fds);
+ 		return;
+ 	}
+ 
+@@ -2617,11 +2628,11 @@ open_files_dump(ulong task, int flags, struct reference *ref)
+ 	j = 0;
+ 	for (;;) {
+ 		unsigned long set;
+-		i = j * __NFDBITS;
++		i = j * BITS_PER_LONG;
+ 		if (((max_fdset >= 0) && (i >= max_fdset)) || 
+ 		    (i >= max_fds))
+ 			 break;
+-		set = open_fds.__fds_bits[j++];
++		set = open_fds[j++];
+ 		while (set) {
+ 			if (set & 1) {
+         			readmem(fd + i*sizeof(struct file *), KVADDR, 
+@@ -2665,6 +2676,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
+ 	if (fdtable_buf)
+ 		FREEBUF(fdtable_buf);
+ 	FREEBUF(files_struct_buf);
++	FREEBUF(open_fds);
+ }
+ 
+ /*
+diff --git a/net.c b/net.c
+index 4199091..f08f22a 100644
+--- a/net.c
++++ b/net.c
+@@ -1373,7 +1373,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
+ 	int max_fdset = 0;
+ 	int max_fds = 0;
+ 	ulong open_fds_addr = 0;
+-	fd_set open_fds;
++	ulong *open_fds;
++	int open_fds_size;
+ 	ulong fd;
+ 	ulong file;
+ 	int i, j;
+@@ -1446,12 +1447,18 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
+             		sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
+ 	}
+ 
++	open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
++	open_fds = (ulong *)GETBUF(open_fds_size);
++	if (!open_fds)
++		return;
++
+ 	if (open_fds_addr) 
+-		readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
++		readmem(open_fds_addr, KVADDR, open_fds, open_fds_size,
+ 	               	"files_struct open_fds", FAULT_ON_ERROR);
+     	if (!open_fds_addr || !fd) { 
+ 		if (!NET_REFERENCE_CHECK(ref))
+ 			fprintf(fp, "No open sockets.\n");
++		FREEBUF(open_fds);
+         	return;
+ 	}
+ 
+@@ -1479,10 +1486,10 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
+     	j = 0;
+     	for (;;) {
+ 	        unsigned long set;
+-	        i = j * __NFDBITS;
++	        i = j * BITS_PER_LONG;
+ 	        if (((max_fdset >= 0) && (i >= max_fdset)) || (i >= max_fds))
+ 	            	break;
+-	        set = open_fds.__fds_bits[j++];
++	        set = open_fds[j++];
+ 	        while (set) {
+ 	            	if (set & 1) {
+ 		                readmem(fd + i*sizeof(struct file *), KVADDR, 
+@@ -1505,6 +1512,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
+ 
+ 	if (NET_REFERENCE_FOUND(ref))
+ 		fprintf(fp, "\n");
++
++	FREEBUF(open_fds);
+ }
+ 
+ 
+
+commit e9532aea6818b347bc0740f39efd4ec844cfb9b0
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Aug 9 11:20:26 2018 -0400
+
+    As an addendum to the new "kmem -[sS]" output format, align the slab
+    cache name string so that it is beneath the "NAME" header column when
+    the "kmem -I &lt;slab-cache>" option is used to ignore a slab cache,
+    or if the scan of the metadata of a slab cache enounters corruption.
+    Also remove a superfluous line from the "help kmem" description of
+    the "kmem -I" option.
+    (k-hagio@ab.jp.nec.com, anderson@redhat.com)
+
+diff --git a/help.c b/help.c
+index a189038..aeeb056 100644
+--- a/help.c
++++ b/help.c
+@@ -6495,7 +6495,6 @@ char *help_kmem[] = {
+ "            all slab cache names and addresses are listed.",
+ "   -I slab  when used with -s or -S, one or more slab cache names in a",
+ "            comma-separated list may be specified as slab caches to ignore.",
+-"            their hugepage size, total and free counts, and name.",
+ "        -g  displays the enumerator value of all bits in the page structure's",
+ "            \"flags\" field.",
+ "     flags  when used with -g, translates all bits in this hexadecimal page",
+diff --git a/memory.c b/memory.c
+index 5bcf09e..4790cf6 100644
+--- a/memory.c
++++ b/memory.c
+@@ -9963,6 +9963,9 @@ ignore_cache(struct meminfo *si, char *name)
+ #define KMEM_SLAB_OVERLOAD_PAGE (8)
+ #define KMEM_SLAB_FREELIST      (9)
+ 
++#define DUMP_KMEM_CACHE_TAG(addr, name, tag) \
++	fprintf(fp, "%lx %-43s  %s\n", addr, tag, name)
++
+ #define DUMP_KMEM_CACHE_INFO()  dump_kmem_cache_info(si)
+ 
+ static void
+@@ -10094,7 +10097,7 @@ dump_kmem_cache(struct meminfo *si)
+ 			goto next_cache;
+ 
+ 		if (ignore_cache(si, buf)) {
+-			fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
++			DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
+ 			goto next_cache;
+ 		}
+ 
+@@ -10303,7 +10306,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
+ 			goto next_cache;
+ 
+                 if (ignore_cache(si, buf)) {
+-                        fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
++                        DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
+                         goto next_cache;
+                 }
+ 
+@@ -10547,12 +10550,12 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
+ 			goto next_cache;
+ 
+                 if (ignore_cache(si, buf)) {
+-                        fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
++                        DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
+                         goto next_cache;
+                 }
+ 
+ 		if (bad_slab_cache(si->cache)) {
+-                        fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf);
++                        DUMP_KMEM_CACHE_TAG(si->cache, buf, "[INVALID/CORRUPTED]");
+                         goto next_cache;
+ 		}
+ 
+@@ -18109,8 +18112,7 @@ dump_kmem_cache_slub(struct meminfo *si)
+ 			fprintf(fp, "%s", kmem_cache_hdr);
+ 		}
+ 		if (ignore_cache(si, buf)) {
+-			fprintf(fp, "%lx %-18s [IGNORED]\n", 
+-				si->cache_list[i], buf);
++			DUMP_KMEM_CACHE_TAG(si->cache_list[i], buf, "[IGNORED]");
+ 			goto next_cache;
+ 		}
+ 
diff --git a/SOURCES/github_a89ec821_vmcoreinfo_plugin.patch b/SOURCES/github_a89ec821_vmcoreinfo_plugin.patch
new file mode 100644
index 0000000..0c79a31
--- /dev/null
+++ b/SOURCES/github_a89ec821_vmcoreinfo_plugin.patch
@@ -0,0 +1,193 @@
+commit a89ec821cb5dbb106cb58e8740f84c7e382c0140
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Feb 8 11:12:23 2019 -0500
+
+    For live system analysis where there is no vmcoreinfo ELF note
+    attached to /proc/kcore, or for dumpfile analysis where there is no
+    vmcoreinfo ELF note attached to the dumpfile, this patch sets the
+    internal pc->read_vmcoreinfo() function to a new plugin function
+    that reads the data directly from the live kernel or dumpfile.
+    Because the function is set much later during initialization than
+    if the ELF note is attached to /proc/kcore or the dumpfile, it may
+    not be available during very early session initialization.
+    (anderson@redhat.com)
+
+diff --git a/defs.h b/defs.h
+index 05f2d17..5841b1f 100644
+--- a/defs.h
++++ b/defs.h
+@@ -4872,6 +4872,7 @@ int clean_exit(int);
+ int untrusted_file(FILE *, char *);
+ char *readmem_function_name(void);
+ char *writemem_function_name(void);
++char *no_vmcoreinfo(const char *);
+ 
+ /*
+  *  cmdline.c
+diff --git a/kernel.c b/kernel.c
+index e512da5..9f5ba89 100644
+--- a/kernel.c
++++ b/kernel.c
+@@ -93,6 +93,8 @@ static void source_tree_init(void);
+ static ulong dump_audit_skb_queue(ulong);
+ static ulong __dump_audit(char *);
+ static void dump_audit(void);
++static char *vmcoreinfo_read_string(const char *);
++static void check_vmcoreinfo(void);
+ 
+ 
+ /*
+@@ -127,6 +129,8 @@ kernel_init()
+ 	kt->end = highest_bss_symbol();
+ 	if ((sp1 = kernel_symbol_search("_end")) && (sp1->value > kt->end)) 
+ 		kt->end = sp1->value;
++
++	check_vmcoreinfo();
+ 	
+ 	/*
+ 	 *  For the traditional (non-pv_ops) Xen architecture, default to writable 
+@@ -11117,3 +11121,84 @@ dump_audit(void)
+ 	if (!qlen)
+ 		error(INFO, "kernel audit log is empty\n");
+ }
++
++/*
++ * Reads a string value from the VMCOREINFO data stored in (live) memory.
++ *
++ * Returns a string (that has to be freed by the caller) that contains the
++ * value for key or NULL if the key has not been found.
++ */
++static char *
++vmcoreinfo_read_string(const char *key)
++{
++	char *buf, *value_string, *p1, *p2;
++	size_t value_length;
++	size_t vmcoreinfo_size;
++	ulong vmcoreinfo_data;
++	char keybuf[BUFSIZE];
++
++	buf = value_string = NULL;
++
++	switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
++	{
++	case TYPE_CODE_PTR:
++		get_symbol_data("vmcoreinfo_data", sizeof(vmcoreinfo_data), &vmcoreinfo_data);
++		break;
++	case TYPE_CODE_ARRAY:
++		vmcoreinfo_data = symbol_value("vmcoreinfo_data");
++		break;
++	default:
++		return NULL;
++	}
++
++	get_symbol_data("vmcoreinfo_size", sizeof(vmcoreinfo_size), &vmcoreinfo_size);
++
++	sprintf(keybuf, "%s=", key);
++
++	if ((buf = malloc(vmcoreinfo_size+1)) == NULL) {
++		error(INFO, "cannot malloc vmcoreinfo buffer\n");
++		goto err;
++	}
++
++	if (!readmem(vmcoreinfo_data, KVADDR, buf, vmcoreinfo_size,
++            "vmcoreinfo_data", RETURN_ON_ERROR|QUIET)) {
++		error(INFO, "cannot read vmcoreinfo_data\n");
++		goto err;
++	}
++
++	buf[vmcoreinfo_size] = '\n';
++
++	if ((p1 = strstr(buf, keybuf))) {
++		p2 = p1 + strlen(keybuf);
++		p1 = strstr(p2, "\n");
++		value_length = p1-p2;
++		value_string = calloc(value_length+1, sizeof(char));
++		strncpy(value_string, p2, value_length);
++		value_string[value_length] = NULLCHAR;
++	}
++err:
++	if (buf)
++		free(buf);
++
++	return value_string;
++}
++
++static void
++check_vmcoreinfo(void)
++{
++	if (!kernel_symbol_exists("vmcoreinfo_data") ||
++	    !kernel_symbol_exists("vmcoreinfo_size"))
++		return;
++
++	if (pc->read_vmcoreinfo == no_vmcoreinfo) {
++		switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
++		{
++		case TYPE_CODE_PTR:
++			pc->read_vmcoreinfo = vmcoreinfo_read_string;
++			break;
++		case TYPE_CODE_ARRAY:
++			pc->read_vmcoreinfo = vmcoreinfo_read_string;
++			break;
++		}
++	}
++}
+diff --git a/main.c b/main.c
+index 7248810..cd282cd 100644
+--- a/main.c
++++ b/main.c
+@@ -1,8 +1,8 @@
+ /* main.c - core analysis suite
+  *
+  * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
+- * Copyright (C) 2002-2018 David Anderson
+- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2002-2019 David Anderson
++ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -29,7 +29,6 @@ static void check_xen_hyper(void);
+ static void show_untrusted_files(void);
+ static void get_osrelease(char *);
+ static void get_log(char *);
+-static char *no_vmcoreinfo(const char *);
+ 
+ static struct option long_options[] = {
+         {"memory_module", required_argument, 0, 0},
+@@ -1950,7 +1949,7 @@ get_log(char *dumpfile)
+ }
+ 
+ 
+-static char *
++char *
+ no_vmcoreinfo(const char *unused)
+ {
+ 	return NULL;
+diff --git a/netdump.c b/netdump.c
+index d0179e0..5aeea6f 100644
+--- a/netdump.c
++++ b/netdump.c
+@@ -1,7 +1,7 @@
+ /* netdump.c 
+  *
+- * Copyright (C) 2002-2018 David Anderson
+- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2002-2019 David Anderson
++ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -1786,11 +1786,13 @@ vmcoreinfo_read_string(const char *key)
+ 		if (STREQ(key, "NUMBER(kimage_voffset)") && nd->arch_data) {
+ 			value = calloc(VADDR_PRLEN+1, sizeof(char));
+ 			sprintf(value, "%lx", nd->arch_data);
++			pc->read_vmcoreinfo = no_vmcoreinfo;
+ 			return value;
+ 		}
+ 		if (STREQ(key, "relocate") && nd->arch_data) {
+ 			value = calloc(VADDR_PRLEN+1, sizeof(char));
+ 			sprintf(value, "%lx", nd->arch_data);
++			pc->read_vmcoreinfo = no_vmcoreinfo;
+ 			return value;
+ 		}
+ 	}
diff --git a/SOURCES/github_ac5a7889_CONFIG_ARM64_PA_BITS.patch b/SOURCES/github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
new file mode 100644
index 0000000..2122183
--- /dev/null
+++ b/SOURCES/github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
@@ -0,0 +1,29 @@
+commit ac5a7889d31bb37aa0687110ecea08837f8a66a8
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Feb 8 10:48:30 2019 -0500
+
+    Support for configurable CONFIG_ARM64_PA_BITS values introduced
+    in kernel commit 982aa7c5f0861bf56b2412ca341a13f44c238ba4, titled
+    "arm64: add kconfig symbol to configure physical address size".
+    Without the patch, it is impossible to determine the value of
+    CONFIG_ARM64_PA_BITS, and will require a new MAX_PHYSMEM_BITS
+    vmcoreinfo entry to be exported.  This patch reads that entry
+    during intitialization.
+    (anderson@redhat.com)
+
+diff --git a/arm64.c b/arm64.c
+index 2308612..b4d9b13 100644
+--- a/arm64.c
++++ b/arm64.c
+@@ -362,7 +362,10 @@ arm64_init(int when)
+ 		arm64_calc_virtual_memory_ranges();
+ 		machdep->section_size_bits = _SECTION_SIZE_BITS;
+ 		if (!machdep->max_physmem_bits) {
+-			if (machdep->machspec->VA_BITS == 52)  /* guess */
++			if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
++				machdep->max_physmem_bits = atol(string);
++				free(string);
++			} else if (machdep->machspec->VA_BITS == 52)  /* guess */
+ 				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
+ 			else if (THIS_KERNEL_VERSION >= LINUX(3,17,0)) 
+ 				machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
diff --git a/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch b/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch
new file mode 100644
index 0000000..0d84189
--- /dev/null
+++ b/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch
@@ -0,0 +1,149 @@
+commit b9d76838372d1b4087bb506ce6da425afad68876
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Jun 7 13:20:16 2018 -0400
+
+    If /proc/kcore gets selected for the live memory source because
+    /dev/mem was configured with CONFIG_STRICT_DEVMEM, its ELF header
+    contents are not displayed by "help -[dD]", and are not displayed
+    when the crash session is invoked with -d<number>".  Without the
+    patch, the ELF contents are only displayed in those two situations
+    if "/proc/kcore" is explicitly entered on the crash command line.
+    (anderson@redhat.com)
+
+diff --git a/netdump.c b/netdump.c
+index 25683eb..1f3e26c 100644
+--- a/netdump.c
++++ b/netdump.c
+@@ -4334,11 +4334,8 @@ kcore_memory_dump(FILE *ofp)
+ 	Elf32_Phdr *lp32;
+ 	Elf64_Phdr *lp64;
+ 
+-	if (!(pkd->flags & KCORE_LOCAL))
+-		return FALSE;
+-
+ 	fprintf(ofp, "proc_kcore_data:\n");
+-	fprintf(ofp, "       flags: %lx (", nd->flags);
++	fprintf(ofp, "       flags: %x (", pkd->flags);
+ 	others = 0;
+ 	if (pkd->flags & KCORE_LOCAL)
+ 		fprintf(ofp, "%sKCORE_LOCAL", others++ ? "|" : "");
+commit c79a11fa10da94b71ddf341ec996c522fbd75237
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Jun 8 14:31:08 2018 -0400
+
+    If the default live memory source /dev/mem is determined to be
+    unusable because the kernel was configured with CONFIG_STRICT_DEVMEM,
+    the first memory read during session initialization will fail.  The
+    current behavior results in a readmem() error message, followed by two
+    notification messages that indicate that /dev/mem is restricted and
+    a switch to using /proc/kcore will be attempted; the readmem is
+    reattempted from /proc/kcore, and if successful, the session will
+    continue initialization.  With this patch, the behavior will change
+    such that if the switch to /proc/kcore and the reattempted readmem()
+    are successful, no messages will be displayed unless the crash
+    session is invoked with "crash -d&lt;number>".
+    (anderson@redhat.com)
+
+diff --git a/kernel.c b/kernel.c
+index 138a47f..3cd5bf1 100644
+--- a/kernel.c
++++ b/kernel.c
+@@ -882,7 +882,7 @@ cpu_maps_init(void)
+ {
+         int i, c, m, cpu, len;
+         char *buf;
+-        ulong *maskptr, addr;
++        ulong *maskptr, addr, error_handle;
+ 	struct mapinfo {
+ 		ulong cpu_flag;
+ 		char *name;
+@@ -902,8 +902,9 @@ cpu_maps_init(void)
+ 		if (!(addr = cpu_map_addr(mapinfo[m].name)))
+ 			continue;
+ 
++		error_handle = pc->flags & DEVMEM ? RETURN_ON_ERROR|QUIET : RETURN_ON_ERROR;
+ 		if (!readmem(addr, KVADDR, buf, len,
+-		    mapinfo[m].name, RETURN_ON_ERROR)) {
++		    mapinfo[m].name, error_handle)) {
+ 			error(WARNING, "cannot read cpu_%s_map\n",
+ 			      mapinfo[m].name);
+ 			continue;
+diff --git a/memory.c b/memory.c
+index 82f9cbf..2f568d5 100644
+--- a/memory.c
++++ b/memory.c
+@@ -2243,9 +2243,11 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
+ 				error(INFO, READ_ERRMSG, memtype_string(memtype, 0), addr, type);
+ 			if ((pc->flags & DEVMEM) && (kt->flags & PRE_KERNEL_INIT) &&
+ 			    !(error_handle & NO_DEVMEM_SWITCH) && devmem_is_restricted() && 
+-			    switch_to_proc_kcore())
++			    switch_to_proc_kcore()) {
++				error_handle &= ~QUIET;
+ 				return(readmem(addr, memtype, bufptr, size,
+ 					type, error_handle));
++			}
+ 			goto readmem_error;
+ 
+ 		case PAGE_EXCLUDED:
+@@ -2457,7 +2459,7 @@ devmem_is_restricted(void)
+ 		    QUIET|RETURN_ON_ERROR|NO_DEVMEM_SWITCH))
+ 			restricted = TRUE;
+ 
+-		if (restricted)
++		if (restricted && CRASHDEBUG(1))
+ 			error(INFO, 
+  	    		    "this kernel may be configured with CONFIG_STRICT_DEVMEM,"
+ 			    " which\n       renders /dev/mem unusable as a live memory "
+@@ -2472,9 +2474,10 @@ switch_to_proc_kcore(void)
+ {
+ 	close(pc->mfd);
+ 
+-	if (file_exists("/proc/kcore", NULL))
+-		error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n");
+-	else
++	if (file_exists("/proc/kcore", NULL)) {
++		if (CRASHDEBUG(1))
++			error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n");
++	} else
+ 		return FALSE;
+ 
+ 	if ((pc->mfd = open("/proc/kcore", O_RDONLY)) < 0) {
+diff --git a/ppc64.c b/ppc64.c
+index 0b04187..0dd8a2a 100644
+--- a/ppc64.c
++++ b/ppc64.c
+@@ -1,7 +1,7 @@
+ /* ppc64.c -- core analysis suite
+  *
+- * Copyright (C) 2004-2015,2017 David Anderson
+- * Copyright (C) 2004-2015,2017 Red Hat, Inc. All rights reserved.
++ * Copyright (C) 2004-2015,2018 David Anderson
++ * Copyright (C) 2004-2015,2018 Red Hat, Inc. All rights reserved.
+  * Copyright (C) 2004, 2006 Haren Myneni, IBM Corporation
+  *
+  * This program is free software; you can redistribute it and/or modify
+@@ -343,8 +343,9 @@ ppc64_init(int when)
+ 
+ 		if (symbol_exists("vmemmap_populate")) {
+ 			if (symbol_exists("vmemmap")) {
+-				get_symbol_data("vmemmap", sizeof(void *),
+-					&machdep->machspec->vmemmap_base);
++				readmem(symbol_value("vmemmap"), KVADDR,
++					&machdep->machspec->vmemmap_base,
++					sizeof(void *), "vmemmap", QUIET|FAULT_ON_ERROR);
+ 			} else
+ 				machdep->machspec->vmemmap_base =
+ 					VMEMMAP_REGION_ID << REGION_SHIFT;
+diff --git a/x86_64.c b/x86_64.c
+index 54b6539..e01082b 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -356,7 +356,7 @@ x86_64_init(int when)
+ 			machdep->flags |= RANDOMIZED;
+ 			readmem(symbol_value("page_offset_base"), KVADDR,
+ 				&machdep->machspec->page_offset, sizeof(ulong),
+-				"page_offset_base", FAULT_ON_ERROR);
++				"page_offset_base", QUIET|FAULT_ON_ERROR);
+ 			machdep->kvbase = machdep->machspec->page_offset;
+ 			machdep->identity_map_base = machdep->machspec->page_offset;
+ 		}
diff --git a/SOURCES/github_c5f45d6c.patch b/SOURCES/github_c5f45d6c.patch
new file mode 100644
index 0000000..c242be1
--- /dev/null
+++ b/SOURCES/github_c5f45d6c.patch
@@ -0,0 +1,239 @@
+commit c5f45d6cdbe7f01314857a75b2feef25b22adaaa
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Oct 11 13:28:39 2018 -0400
+
+    Address several Coverity Scan "RESOURCE_LEAK" issues in the following
+    top-level source files: cmdline.c, kvmdump.c, lkcd_v8.c, xendump.c,
+    symbols.c, unwind_x86_32_64.c, va_server.c and va_server_v1.c.
+    (anderson@redhat.com)
+
+diff --git a/cmdline.c b/cmdline.c
+index c0a9f4f..cf3e150 100644
+--- a/cmdline.c
++++ b/cmdline.c
+@@ -1318,8 +1318,10 @@ is_shell_script(char *s)
+         if ((fd = open(s, O_RDONLY)) < 0) 
+                 return FALSE;
+         
+-        if (isatty(fd)) 
++        if (isatty(fd)) {
++                close(fd);
+                 return FALSE;
++	}
+         
+         if (read(fd, interp, 2) != 2) {
+                 close(fd);
+diff --git a/kvmdump.c b/kvmdump.c
+index 622619c..4db96bd 100644
+--- a/kvmdump.c
++++ b/kvmdump.c
+@@ -846,8 +846,10 @@ kvmdump_mapfile_exists(void)
+ 
+ 	sprintf(filename, "%s.map", pc->dumpfile);
+ 
+-	if (!file_exists(filename, &stat) || !S_ISREG(stat.st_mode))
++	if (!file_exists(filename, &stat) || !S_ISREG(stat.st_mode)) {
++		free(filename);
+ 		return FALSE;
++	}
+ 
+ 	if (is_kvmdump_mapfile(filename)) {
+ 		pc->kvmdump_mapfile = filename;
+diff --git a/lkcd_v8.c b/lkcd_v8.c
+index 1322250..3b355e0 100644
+--- a/lkcd_v8.c
++++ b/lkcd_v8.c
+@@ -184,6 +184,7 @@ lkcd_dump_init_v8_arch(dump_header_t *dh)
+ 
+ 	memcpy(&dump_header_asm_v8, &arch_hdr, sizeof(dump_header_asm_t));
+ 
++	free(hdr_buf);
+ 	return 0;
+ 
+ err:
+diff --git a/symbols.c b/symbols.c
+index b54b8c0..fb9cd1b 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -3862,12 +3862,10 @@ is_bfd_format(char *filename)
+ #else
+         struct bfd *bfd;
+ #endif
+-        char **matching;
+-
+         if ((bfd = bfd_openr(filename, NULL)) == NULL) 
+                 return FALSE;
+         
+-        if (!bfd_check_format_matches(bfd, bfd_object, &matching)) {
++        if (!bfd_check_format_matches(bfd, bfd_object, NULL)) {
+                 bfd_close(bfd);
+                 return FALSE;
+         }
+diff --git a/unwind_x86_32_64.c b/unwind_x86_32_64.c
+index c62f92f..c7c30d6 100644
+--- a/unwind_x86_32_64.c
++++ b/unwind_x86_32_64.c
+@@ -819,6 +819,7 @@ try_eh_frame:
+ 				error(WARNING, "cannot read %s data from %s\n",
+ 			        	is_ehframe ? ".eh_frame" : ".debug_frame", pc->namelist);
+ 			free(unwind_table);
++			close(fd);
+ 			return;
+ 		}
+ 
+diff --git a/va_server.c b/va_server.c
+index d96287a..96c2b5c 100644
+--- a/va_server.c
++++ b/va_server.c
+@@ -313,20 +313,27 @@ int read_map(char *crash_file)
+ 	ret = fseek(vas_file_p, (long)0, SEEK_SET);
+ 	if(ret == -1) {
+ 		printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
++		free(hdr);
+ 		free(disk_hdr);
+ 		return -1;
+ 	}
+ 	items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
+ 	if(items != Page_Size) {
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 	if(disk_hdr->magic[0] != CRASH_MAGIC) {
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 	ret = fseek(vas_file_p, (long)((disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
+ 
+ 	if(ret == -1) {
+ 		printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 
+@@ -338,10 +345,13 @@ int read_map(char *crash_file)
+ 		      vas_file_p);
+ 	if(items != disk_hdr->map_blocks) {
+ 		printf("unable to read map entries, err = %d\n", errno);
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 
+ 	vas_map_base = hdr;
++	free(disk_hdr);
+ 	return 0;
+ }
+ 
+diff --git a/va_server_v1.c b/va_server_v1.c
+index 1924946..88a2a5a 100644
+--- a/va_server_v1.c
++++ b/va_server_v1.c
+@@ -253,7 +253,7 @@ u_long vas_find_end_v1(void)
+ }
+ int read_maps_v1(char *crash_file)
+ {
+-	int *cur_entry_p;
++	int *cur_entry_p, *cp;
+ 	int ret, items, blk_pos;
+ 
+ 	cur_entry_p = (int *)malloc(Page_Size);
+@@ -266,25 +266,32 @@ int read_maps_v1(char *crash_file)
+ 	vas_file_p = fopen(crash_file, "r");
+ 	if(vas_file_p == (FILE *)0) {
+ 		printf("read_maps: bad ret from fopen for %s: %s\n", crash_file, strerror(errno));
++		free(cur_entry_p);
+ 		return -1;
+ 	}
+ 	ret = fseek(vas_file_p, (long)0, SEEK_SET);
+ 	if(ret == -1) {
+ 		printf("read_maps: unable to fseek in  %s, errno = %d\n", crash_file, ferror(vas_file_p));
++		free(cur_entry_p);
+ 		return -1;
+ 	}	
+ 	items = fread((void *)cur_entry_p, 1, Page_Size, vas_file_p);
+ 	if(items != Page_Size) {
+ 		printf("read_maps: unable to read header from %s, errno = %d\n", crash_file, ferror(vas_file_p));
++		free(cur_entry_p);
+ 		return -1;
+ 	}
+ 	ret = -1;
+-	while ((blk_pos = *cur_entry_p++)) {
+-		if (read_map_v1(blk_pos))
++	cp = cur_entry_p;
++	while ((blk_pos = *cp++)) {
++		if (read_map_v1(blk_pos)) {
++			free(cur_entry_p);
+ 			return -1;
++		}
+ 		ret = 0;
+ 	}
+ 
++	free(cur_entry_p);
+ 	return ret;
+ }
+ 
+@@ -308,21 +315,28 @@ int read_map_v1(int blk_pos)
+ 	ret = fseek(vas_file_p, (long)(blk_pos*Page_Size), SEEK_SET);
+ 	if(ret == -1) {
+ 		console("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
++		free(hdr);
+ 		free(disk_hdr);
+ 		return -1;
+ 	}
+ 	items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
+ 	if(items != Page_Size) {
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 	if(disk_hdr->magic[0] != CRASH_MAGIC) {
+ 		console("va_server: bad magic 0x%lx\n", disk_hdr->magic[0]);
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 	ret = fseek(vas_file_p, (long)((blk_pos + disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
+ 
+ 	if(ret == -1) {
+ 		printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 
+@@ -338,6 +352,8 @@ int read_map_v1(int blk_pos)
+ 		      vas_file_p);
+ 	if(items != hdr->map_entries) {
+ 		printf("unable to read map entries, err = %d\n", errno);
++		free(hdr);
++		free(disk_hdr);
+ 		return -1;
+ 	}
+ 
+diff --git a/xendump.c b/xendump.c
+index 4bd59b5..70cf261 100644
+--- a/xendump.c
++++ b/xendump.c
+@@ -2775,8 +2775,10 @@ xc_core_dump_elfnote(off_t sh_offset, size_t sh_size, int store)
+ 		index += sizeof(struct elfnote) + elfnote->descsz;
+ 	}
+ 
+-	if (!store)
++	if (!store) {
++		free(notes_buffer);
+ 		return;
++	}
+ 
+ 	if (elfnote_header) {
+ 		xd->xc_core.header.xch_magic = elfnote_header->xch_magic;
+@@ -2798,6 +2800,7 @@ xc_core_dump_elfnote(off_t sh_offset, size_t sh_size, int store)
+ 		xd->xc_core.format_version = format_version->version;
+ 	}
+ 
++	free(notes_buffer);
+ }
+ 
+ /*
diff --git a/SOURCES/github_ced52552_dev-p_offsets.patch b/SOURCES/github_ced52552_dev-p_offsets.patch
new file mode 100644
index 0000000..f8ba626
--- /dev/null
+++ b/SOURCES/github_ced52552_dev-p_offsets.patch
@@ -0,0 +1,41 @@
+commit ced5255233447cc0810965b683657409f798c4a2
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue Oct 2 11:18:09 2018 -0400
+
+    As an addendum to the "dev -p" patch above, add the new structure
+    member offsets for display by the "help -o" option.
+    (anderson@redhat.com)
+
+diff --git a/symbols.c b/symbols.c
+index cb2174b..bb8a8f4 100644
+--- a/symbols.c
++++ b/symbols.c
+@@ -9692,6 +9692,28 @@ dump_offset_table(char *spec, ulong makestruct)
+         fprintf(fp, "                pci_bus_number: %ld\n",
+         	OFFSET(pci_bus_number));
+ 
++        fprintf(fp, "                   pci_dev_dev: %ld\n",
++        	OFFSET(pci_dev_dev));
++        fprintf(fp, "              pci_dev_hdr_type: %ld\n",
++        	OFFSET(pci_dev_hdr_type));
++        fprintf(fp, "        pci_dev_pcie_flags_reg: %ld\n",
++        	OFFSET(pci_dev_pcie_flags_reg));
++        fprintf(fp, "                  pci_bus_node: %ld\n",
++        	OFFSET(pci_bus_node));
++        fprintf(fp, "               pci_bus_devices: %ld\n",
++        	OFFSET(pci_bus_devices));
++        fprintf(fp, "                   pci_bus_dev: %ld\n",
++        	OFFSET(pci_bus_dev));
++        fprintf(fp, "              pci_bus_children: %ld\n",
++        	OFFSET(pci_bus_children));
++        fprintf(fp, "                pci_bus_parent: %ld\n",
++        	OFFSET(pci_bus_parent));
++        fprintf(fp, "                  pci_bus_self: %ld\n",
++        	OFFSET(pci_bus_self));
++        fprintf(fp, "                   device_kobj: %ld\n",
++        	OFFSET(device_kobj));
++        fprintf(fp, "                  kobject_name: %ld\n",
++        	OFFSET(kobject_name));
+ 
+         fprintf(fp, "         resource_entry_t_from: %ld\n",
+         	OFFSET(resource_entry_t_from));
diff --git a/SOURCES/github_f3a53059.patch b/SOURCES/github_f3a53059.patch
new file mode 100644
index 0000000..f28387c
--- /dev/null
+++ b/SOURCES/github_f3a53059.patch
@@ -0,0 +1,89 @@
+commit f3a5305947077a65aea8091b05cdb542cea0d61a
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Wed Oct 24 16:25:43 2018 -0400
+
+    Modify the x86_64 "bt" behavior when a legitimate exception RIP value
+    cannot be referenced symbolically, such as when the exception occurs
+    while running in seccomp BPF filter code.  Without the patch, the
+    exception frame register dump is preceded by "[exception RIP: unknown
+    or invalid address]", and then followed by "bt: WARNING: possibly
+    bogus exception frame".  With the patch applied, the translation of
+    the exception RIP will show "[exception RIP: no symbolic reference]",
+    and there will be no warning message.
+    (anderson@redhat.com)
+
+diff --git a/x86_64.c b/x86_64.c
+index 345122c..d145f96 100644
+--- a/x86_64.c
++++ b/x86_64.c
+@@ -3259,6 +3259,18 @@ x86_64_in_alternate_stack(int cpu, ulong
+ 	return FALSE;
+ }
+ 
++static char *
++x86_64_exception_RIP_message(struct bt_info *bt, ulong rip)
++{
++	physaddr_t phys;
++	
++	if (IS_VMALLOC_ADDR(rip) && 
++	    machdep->kvtop(bt->tc, rip, &phys, 0))
++		return ("no symbolic reference");
++ 
++	return ("unknown or invalid address");
++}
++
+ #define STACK_TRANSITION_ERRMSG_E_I_P \
+ "cannot transition from exception stack to IRQ stack to current process stack:\n    exception stack pointer: %lx\n          IRQ stack pointer: %lx\n      process stack pointer: %lx\n         current stack base: %lx\n" 
+ #define STACK_TRANSITION_ERRMSG_E_P \
+@@ -3370,7 +3382,7 @@ x86_64_low_budget_back_trace_cmd(struct
+ 				fprintf(ofp, (*gdb_output_radix == 16) ?
+ 					"+0x%lx" : "+%ld", offset);
+ 		} else
+-			fprintf(ofp, "unknown or invalid address");
++			fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, bt->instptr));
+ 		fprintf(ofp, "]\n");
+ 		if (KVMDUMP_DUMPFILE())
+ 			kvmdump_display_regs(bt->tc->processor, ofp);
+@@ -4458,9 +4470,9 @@ x86_64_exception_frame(ulong flags, ulon
+ 						    (*gdb_output_radix == 16) ? 
+ 						    "+0x%lx" : "+%ld", 
+ 						    offset);
+-				} else 
+-					fprintf(ofp, 
+-						"unknown or invalid address");
++				} else
++					fprintf(ofp, "%s", 
++						x86_64_exception_RIP_message(bt, rip));
+ 				fprintf(ofp, "]\n");
+ 			}
+ 		} else if (!(cs & 3)) {
+@@ -4472,7 +4484,7 @@ x86_64_exception_frame(ulong flags, ulon
+ 						"+0x%lx" : "+%ld", offset);
+ 				bt->eframe_ip = rip;
+ 			} else
+-                		fprintf(ofp, "unknown or invalid address");
++				fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, rip));
+ 			fprintf(ofp, "]\n");
+ 		}
+ 		fprintf(ofp, "    RIP: %016lx  RSP: %016lx  RFLAGS: %08lx\n", 
+@@ -4616,6 +4628,7 @@ x86_64_eframe_verify(struct bt_info *bt,
+ 	int estack;
+ 	struct syment *sp;
+ 	ulong offset, exception;
++	physaddr_t phys;
+ 
+ 	if ((rflags & RAZ_MASK) || !(rflags & 0x2))
+ 		return FALSE;
+@@ -4682,6 +4695,12 @@ x86_64_eframe_verify(struct bt_info *bt,
+ 			return TRUE;
+ 	}
+ 
++	if ((cs == 0x10) && kvaddr) {
++                if (IS_KVADDR(rsp) && IS_VMALLOC_ADDR(rip) && 
++		    machdep->kvtop(bt->tc, rip, &phys, 0))
++			return TRUE;
++	}
++
+         if ((cs == 0x33) && (ss == 0x2b)) {
+                 if (IS_UVADDR(rip, bt->tc) && IS_UVADDR(rsp, bt->tc))
+                         return TRUE;
diff --git a/SOURCES/github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch b/SOURCES/github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
new file mode 100644
index 0000000..2b3d324
--- /dev/null
+++ b/SOURCES/github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
@@ -0,0 +1,499 @@
+commit 5fe78861ea1589084f6a2956a6ff63677c9269e1
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Fri Sep 7 16:05:52 2018 -0400
+
+    Commit 3db3d3992d781c1e42587d2d2bf81e785408e0c2 in crash-7.1.8 was
+    aimed at making the PPC64 "bt" command work for dumpfiles saved
+    with the FADUMP facility, but it introduced a bit of unwarranted
+    complexity in "bt" command processing.  Reworked the "bt" command
+    processing for PPC64 arch to make it a little less compilated and
+    also to print symbols for NIP and LR registers in exception frames.
+    Without the patch, "bt" on non-panic active tasks may fail with
+    the message "bt: invalid kernel virtual address: <address>
+    type: Regs NIP value".
+    (hbathini@linux.ibm.com)
+
+diff --git a/ppc64.c b/ppc64.c
+index f5d0dac..03fecd3 100644
+--- a/ppc64.c
++++ b/ppc64.c
+@@ -2093,15 +2093,10 @@ ppc64_print_stack_entry(int frame,
+ 					lr);
+ 				return;
+ 			}
+-			if (req->pc != lr) {
+-				fprintf(fp, "\n%s[Link Register] ", 
+-					frame < 10 ? " " : "");
+-				fprintf(fp, "[%lx] %s at %lx",
+-					req->sp, lrname, lr);
+-			}
+ 			req->ra = lr;
+ 		}
+-		if (!req->name || STREQ(req->name,lrname)) 
++		if (!req->name || STREQ(req->name, lrname) ||
++		    !is_kernel_text(req->pc))
+ 			fprintf(fp, "  (unreliable)");
+ 		
+ 		fprintf(fp, "\n"); 
+@@ -2219,6 +2214,22 @@ ppc64_print_regs(struct ppc64_pt_regs *regs)
+         fprintf(fp, "    Syscall Result: %016lx\n", regs->result);
+ }
+ 
++static void ppc64_print_nip_lr(struct ppc64_pt_regs *regs, int print_lr)
++{
++	char buf[BUFSIZE];
++	char *sym_buf;
++
++	sym_buf = value_to_symstr(regs->nip, buf, 0);
++	if (sym_buf[0] != NULLCHAR)
++		fprintf(fp, " [NIP  : %s]\n", sym_buf);
++
++	if (print_lr) {
++		sym_buf = value_to_symstr(regs->link, buf, 0);
++		if (sym_buf[0] != NULLCHAR)
++			fprintf(fp, " [LR   : %s]\n", sym_buf);
++	}
++}
++
+ /*
+  * Print the exception frame information
+  */
+@@ -2231,6 +2242,59 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
+ 
+ 	fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap);
+ 	ppc64_print_regs(regs);
++	ppc64_print_nip_lr(regs, 1);
++}
++
++/*
++ * For vmcore typically saved with KDump or FADump, get SP and IP values
++ * from the saved ptregs.
++ */
++static int
++ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
++{
++	struct ppc64_pt_regs *pt_regs;
++	unsigned long unip;
++
++	pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
++	if (!pt_regs || !pt_regs->gpr[1]) {
++		/*
++		 * Not collected regs. May be the corresponding CPU not
++		 * responded to an IPI in case of KDump OR f/w has not
++		 * not provided the register info in case of FADump.
++		 */
++		fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
++			bt_in->task);
++		return FALSE;
++	}
++	*ksp = pt_regs->gpr[1];
++	if (IS_KVADDR(*ksp)) {
++		readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
++			FAULT_ON_ERROR);
++		*nip = unip;
++	} else {
++		if (IN_TASK_VMA(bt_in->task, *ksp))
++			fprintf(fp, "%0lx: Task is running in user space\n",
++				bt_in->task);
++		else
++			fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
++				bt_in->task, *ksp);
++		*nip = pt_regs->nip;
++	}
++
++	if (bt_in->flags &&
++	((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)))
++		return TRUE;
++
++	/*
++	 * Print the collected regs for the active task
++	 */
++	ppc64_print_regs(pt_regs);
++	if (!IS_KVADDR(*ksp))
++		return FALSE;
++
++	ppc64_print_nip_lr(pt_regs, (unip != pt_regs->link) ? 1 : 0);
++
++	return TRUE;
+ }
+ 
+ /*
+@@ -2239,7 +2303,7 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
+ static int
+ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+ {
+-	int i;
++	int i, ret, panic_task;
+ 	char *sym;
+ 	ulong *up;
+ 	struct bt_info bt_local, *bt;
+@@ -2251,11 +2315,29 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+ 	struct ppc64_pt_regs *pt_regs;
+ 	struct syment *sp;
+ 
+-        bt = &bt_local;
+-        BCOPY(bt_in, bt, sizeof(struct bt_info));
+-        ms = machdep->machspec;
++	bt = &bt_local;
++	BCOPY(bt_in, bt, sizeof(struct bt_info));
++	ms = machdep->machspec;
++	ur_nip = ur_ksp = 0;
++
++	panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
+ 
+ 	check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE;
++	if (panic_task && bt->machdep) {
++		pt_regs = (struct ppc64_pt_regs *)bt->machdep;
++		ur_nip = pt_regs->nip;
++		ur_ksp = pt_regs->gpr[1];
++	} else if ((pc->flags & KDUMP) ||
++		   ((pc->flags & DISKDUMP) &&
++		    (*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
++		/*
++		 * For the KDump or FADump vmcore, use SP and IP values
++		 * that are saved in ptregs.
++		 */
++		ret = ppc64_vmcore_stack_frame(bt_in, nip, ksp);
++		if (ret)
++			return TRUE;
++	}
+ 
+ 	if (bt->task != tt->panic_task) {
+ 		char cpu_frozen = FALSE;
+@@ -2385,38 +2467,14 @@ retry:
+ 		check_intrstack = FALSE;
+ 		goto retry;
+ 	}
+-
+ 	/*
+-	 * We didn't find what we were looking for, so try to use
+-	 * the SP and IP values saved in ptregs.
++	 *  We didn't find what we were looking for, so just use what was
++	 *  passed in the ELF header.
+ 	 */
+-	pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+-	if (!pt_regs || !pt_regs->gpr[1]) {
+-		/*
+-		 * Not collected regs. May be the corresponding CPU did not
+-		 * respond to an IPI.
+-		 */
+-		if (CRASHDEBUG(1))
+-			fprintf(fp, "%0lx: GPR1(SP) register value not saved\n",
+-				bt_in->task);
+-	} else {
+-		*ksp = pt_regs->gpr[1];
+-		if (IS_KVADDR(*ksp)) {
+-			readmem(*ksp+16, KVADDR, nip, sizeof(ulong),
+-				"Regs NIP value", FAULT_ON_ERROR);
+-			ppc64_print_regs(pt_regs);
+-			return TRUE;
+-		} else {
+-			if (IN_TASK_VMA(bt_in->task, *ksp))
+-				fprintf(fp, "%0lx: Task is running in user space\n",
+-					bt_in->task);
+-			else
+-				fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+-					bt_in->task, *ksp);
+-			*nip = pt_regs->nip;
+-			ppc64_print_regs(pt_regs);
+-			return FALSE;
+-		}
++	if (ur_nip && ur_ksp) {
++		*nip = ur_nip;
++		*ksp = ur_ksp;
++		return TRUE;
+ 	}
+ 
+         console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic task\n");
+commit 7e3936895386ea6e85a6dc01bc5027f8133d12bb
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Mon Sep 17 14:33:08 2018 -0400
+
+    An addendum to crash commit 5fe78861ea1589084f6a2956a6ff63677c9269e1,
+    this patch for the PPC64 "bt" command prevents an invalid error
+    message from being displayed when an active non-panic task is
+    interrupted while running in user space.  Without the patch, the
+    command correctly indicates "Task is running in user space", dumps
+    the user-space exception frame, but then prints the invalid error
+    message "bt: invalid kernel virtual address: ffffffffffffff90 type:
+    Regs NIP value".
+    (anderson@redhat.com)
+
+diff --git a/ppc64.c b/ppc64.c
+index 03fecd3..8badcde 100644
+--- a/ppc64.c
++++ b/ppc64.c
+@@ -2254,6 +2254,7 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+ {
+ 	struct ppc64_pt_regs *pt_regs;
+ 	unsigned long unip;
++	int in_user_space = FALSE;
+ 
+ 	pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+ 	if (!pt_regs || !pt_regs->gpr[1]) {
+@@ -2272,10 +2273,11 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+ 			FAULT_ON_ERROR);
+ 		*nip = unip;
+ 	} else {
+-		if (IN_TASK_VMA(bt_in->task, *ksp))
++		if (IN_TASK_VMA(bt_in->task, *ksp)) {
+ 			fprintf(fp, "%0lx: Task is running in user space\n",
+ 				bt_in->task);
+-		else
++			in_user_space = TRUE;
++		} else
+ 			fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+ 				bt_in->task, *ksp);
+ 		*nip = pt_regs->nip;
+@@ -2289,6 +2291,8 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+ 	 * Print the collected regs for the active task
+ 	 */
+ 	ppc64_print_regs(pt_regs);
++	if (in_user_space)
++		return TRUE;
+ 	if (!IS_KVADDR(*ksp))
+ 		return FALSE;
+ 
+commit 599a6579aa916df7800f8e889d68e4287e4520dd
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Thu Sep 27 14:14:31 2018 -0400
+
+    With Linux 4.19-rc1 commit 7d4340bb92a9df78e6e28152f3dd89d9bd82146b,
+    titled "powerpc/mm: Increase MAX_PHYSMEM_BITS to 128TB with
+    SPARSEMEM_VMEMMAP config", the PPC64 MAX_PHYSMEM_BITS value has
+    been bumped up to 47.  The appropriate update has been made in
+    this patch.
+    (hbathini@linux.ibm.com)
+
+diff --git a/defs.h b/defs.h
+index 80c61ef..5b64bb7 100644
+--- a/defs.h
++++ b/defs.h
+@@ -4054,6 +4054,7 @@ struct efi_memory_desc_t {
+ #define _SECTION_SIZE_BITS	24
+ #define _MAX_PHYSMEM_BITS	44
+ #define _MAX_PHYSMEM_BITS_3_7   46
++#define _MAX_PHYSMEM_BITS_4_19  47
+ 
+ #endif /* PPC64 */
+ 
+diff --git a/ppc64.c b/ppc64.c
+index 8badcde..ee2f76f 100644
+--- a/ppc64.c
++++ b/ppc64.c
+@@ -554,7 +554,10 @@ ppc64_init(int when)
+ 			ppc64_vmemmap_init();
+ 
+ 		machdep->section_size_bits = _SECTION_SIZE_BITS;
+-		if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
++		if ((machdep->flags & VMEMMAP) &&
++		    (THIS_KERNEL_VERSION >= LINUX(4,19,0)))
++			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
++		else if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
+ 			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_7;
+ 		else
+ 			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+
+
+commit 72cc0cba8a6cab14ca0961dff062d0384d307ce5
+Author: Dave Anderson <anderson@redhat.com>
+Date:   Tue Oct 2 10:56:28 2018 -0400
+
+    Fix for the PPC64 "bt" command to recognize when a thread is running
+    in OPAL firmware.  Without the patch, the "bt" command indicates
+    <task-address>: Invalid Stack Pointer <OPAL-firmware-address>"
+    (hbathini@linux.ibm.com)
+
+--- a/defs.h
++++ b/defs.h
+@@ -5934,6 +5934,12 @@ struct ppc64_elf_prstatus {
+ 
+ #ifdef PPC64
+ 
++struct ppc64_opal {
++	uint64_t base;
++	uint64_t entry;
++	uint64_t size;
++};
++
+ struct ppc64_vmemmap {
+         unsigned long phys;
+         unsigned long virt;
+@@ -5984,6 +5990,7 @@ struct machine_specific {
+ 	ulong _page_accessed;
+ 	int (*is_kvaddr)(ulong);
+ 	int (*is_vmaddr)(ulong);
++	struct ppc64_opal opal;
+ };
+ 
+ void ppc64_init(int);
+@@ -6001,6 +6008,7 @@ void ppc64_dump_machdep_table(ulong);
+  * in the kernel is also 0x40.
+  */
+ #define RADIX_MMU       (0x40)
++#define OPAL_FW         (0x80)
+ 
+ #define REGION_SHIFT       (60UL)
+ #define REGION_ID(addr)    (((unsigned long)(addr)) >> REGION_SHIFT)
+--- a/ppc64.c
++++ b/ppc64.c
+@@ -65,8 +65,26 @@ static ulong hugepage_dir(ulong pte);
+ static ulong pgd_page_vaddr_l4(ulong pgd);
+ static ulong pud_page_vaddr_l4(ulong pud);
+ static ulong pmd_page_vaddr_l4(ulong pmd);
++static int is_opal_context(ulong sp, ulong nip);
+ void opalmsg(void);
+ 
++static int is_opal_context(ulong sp, ulong nip)
++{
++	uint64_t opal_start, opal_end;
++
++	if (!(machdep->flags & OPAL_FW))
++		return FALSE;
++
++	opal_start = machdep->machspec->opal.base;
++	opal_end   = opal_start + machdep->machspec->opal.size;
++
++	if (((sp >= opal_start) && (sp < opal_end)) ||
++	    ((nip >= opal_start) && (nip < opal_end)))
++		return TRUE;
++
++	return FALSE;
++}
++
+ static inline int is_hugepage(ulong pte)
+ {
+ 	if ((machdep->flags & BOOK3E) ||
+@@ -241,6 +259,7 @@ struct machine_specific book3e_machine_s
+ 	.is_vmaddr = book3e_is_vmaddr,
+ };
+ 
++#define SKIBOOT_BASE			0x30000000
+ 
+ /*
+  *  Do all necessary machine-specific setup here.  This is called several
+@@ -362,6 +381,16 @@ ppc64_init(int when)
+ 			struct machine_specific *m = machdep->machspec;
+ 
+ 			/*
++			 * To determine if the kernel was running on OPAL based platform,
++			 * use struct opal, which is populated with relevant values.
++			 */
++			if (symbol_exists("opal")) {
++				get_symbol_data("opal", sizeof(struct ppc64_opal), &(m->opal));
++				if (m->opal.base == SKIBOOT_BASE)
++					machdep->flags |= OPAL_FW;
++			}
++
++			/*
+ 			 * On Power ISA 3.0 based server processors, a kernel can
+ 			 * run with radix MMU or standard MMU. Set the flag,
+ 			 * if it is radix MMU.
+@@ -712,6 +741,8 @@ ppc64_dump_machdep_table(ulong arg)
+ 		fprintf(fp, "%sSWAP_ENTRY_L4", others++ ? "|" : "");
+ 	if (machdep->flags & RADIX_MMU)
+ 		fprintf(fp, "%sRADIX_MMU", others++ ? "|" : "");
++	if (machdep->flags & OPAL_FW)
++		fprintf(fp, "%sOPAL_FW", others++ ? "|" : "");
+         fprintf(fp, ")\n");
+ 
+ 	fprintf(fp, "             kvbase: %lx\n", machdep->kvbase);
+@@ -2257,7 +2288,11 @@ ppc64_vmcore_stack_frame(struct bt_info
+ {
+ 	struct ppc64_pt_regs *pt_regs;
+ 	unsigned long unip;
+-	int in_user_space = FALSE;
++	/*
++	 * TRUE: task is running in a different context (userspace, OPAL..)
++	 * FALSE: task is probably running in kernel space.
++	 */
++	int out_of_context = FALSE;
+ 
+ 	pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+ 	if (!pt_regs || !pt_regs->gpr[1]) {
+@@ -2270,20 +2305,25 @@ ppc64_vmcore_stack_frame(struct bt_info
+ 			bt_in->task);
+ 		return FALSE;
+ 	}
++
+ 	*ksp = pt_regs->gpr[1];
+ 	if (IS_KVADDR(*ksp)) {
+ 		readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
+ 			FAULT_ON_ERROR);
+ 		*nip = unip;
+ 	} else {
++		*nip = pt_regs->nip;
+ 		if (IN_TASK_VMA(bt_in->task, *ksp)) {
+ 			fprintf(fp, "%0lx: Task is running in user space\n",
+ 				bt_in->task);
+-			in_user_space = TRUE;
++			out_of_context = TRUE;
++		} else if (is_opal_context(*ksp, *nip)) {
++			fprintf(fp, "%0lx: Task is running in OPAL (firmware) context\n",
++				bt_in->task);
++			out_of_context = TRUE;
+ 		} else
+ 			fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+ 				bt_in->task, *ksp);
+-		*nip = pt_regs->nip;
+ 	}
+ 
+ 	if (bt_in->flags &&
+@@ -2294,7 +2334,8 @@ ppc64_vmcore_stack_frame(struct bt_info
+ 	 * Print the collected regs for the active task
+ 	 */
+ 	ppc64_print_regs(pt_regs);
+-	if (in_user_space)
++
++	if (out_of_context)
+ 		return TRUE;
+ 	if (!IS_KVADDR(*ksp))
+ 		return FALSE;
+@@ -2828,7 +2869,6 @@ ppc64_get_smp_cpus(void)
+  */
+ #define SKIBOOT_CONSOLE_DUMP_START	0x31000000
+ #define SKIBOOT_CONSOLE_DUMP_SIZE	0x100000
+-#define SKIBOOT_BASE			0x30000000
+ #define ASCII_UNLIMITED ((ulong)(-1) >> 1)
+ 
+ void
+@@ -2841,10 +2881,6 @@ opalmsg(void)
+ 		uint64_t u64;
+ 		uint64_t limit64;
+ 	};
+-	struct opal {
+-		unsigned long long base;
+-		unsigned long long entry;
+-	} opal;
+ 	int i, a;
+ 	size_t typesz;
+ 	void *location;
+@@ -2856,25 +2892,13 @@ opalmsg(void)
+ 	long count = SKIBOOT_CONSOLE_DUMP_SIZE;
+ 	ulonglong addr = SKIBOOT_CONSOLE_DUMP_START;
+ 
++	if (!(machdep->flags & OPAL_FW))
++		error(FATAL, "dump was not captured on OPAL based system");
++
+ 	if (CRASHDEBUG(4))
+ 		fprintf(fp, "<addr: %llx count: %ld (%s)>\n",
+ 				addr, count, "PHYSADDR");
+ 
+-	/*
+-	 * OPAL based platform check
+-	 * struct opal of BSS section and hence default value will be ZERO(0)
+-	 * opal_init() in the kernel initializes this structure based on
+-	 * the platform. Use it as a key to determine whether the dump
+-	 * was taken on an OPAL based system or not.
+-	 */
+-	if (symbol_exists("opal")) {
+-		get_symbol_data("opal", sizeof(struct opal), &opal);
+-		if (opal.base != SKIBOOT_BASE)
+-			error(FATAL, "dump was captured on non-PowerNV machine");
+-	} else {
+-		error(FATAL, "dump was captured on non-PowerNV machine");
+-	}
+-
+ 	BZERO(&mem, sizeof(struct memloc));
+ 	lost = typesz = per_line = 0;
+ 	location = NULL;
diff --git a/SOURCES/lzo_snappy.patch b/SOURCES/lzo_snappy.patch
new file mode 100644
index 0000000..61af0cc
--- /dev/null
+++ b/SOURCES/lzo_snappy.patch
@@ -0,0 +1,22 @@
+--- crash-7.1.5/diskdump.c.orig
++++ crash-7.1.5/diskdump.c
+@@ -23,6 +23,8 @@
+  * GNU General Public License for more details.
+  */
+ 
++#define LZO
++#define SNAPPY
+ #include "defs.h"
+ #include "diskdump.h"
+ #include "xen_dom0.h"
+--- crash-7.1.5/Makefile.orig
++++ crash-7.1.5/Makefile
+@@ -228,7 +228,7 @@ all: make_configure
+ gdb_merge: force
+ 	@if [ ! -f ${GDB}/README ]; then \
+ 	  make --no-print-directory gdb_unzip; fi
+-	@echo "${LDFLAGS} -lz -ldl -rdynamic" > ${GDB}/gdb/mergelibs
++	@echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic" > ${GDB}/gdb/mergelibs
+ 	@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
+ 	@rm -f ${PROGRAM}
+ 	@if [ ! -f ${GDB}/config.status ]; then \
diff --git a/SOURCES/rhel8_build.patch b/SOURCES/rhel8_build.patch
new file mode 100644
index 0000000..33bdb99
--- /dev/null
+++ b/SOURCES/rhel8_build.patch
@@ -0,0 +1,32 @@
+--- crash-7.2.3/Makefile.orig
++++ crash-7.2.3/Makefile
+@@ -198,7 +198,7 @@ GDB_FLAGS=
+ # TARGET_CFLAGS will be configured automatically by configure
+ TARGET_CFLAGS=
+ 
+-CRASH_CFLAGS=-g -D${TARGET} ${TARGET_CFLAGS} ${GDB_FLAGS} ${CFLAGS}
++CRASH_CFLAGS=-g -D${TARGET} ${TARGET_CFLAGS} ${GDB_FLAGS} ${CFLAGS} ${CPPFLAGS} -fPIE
+ 
+ GPL_FILES=COPYING3
+ TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package crash.8 \
+@@ -228,7 +228,7 @@ all: make_configure
+ gdb_merge: force
+ 	@if [ ! -f ${GDB}/README ]; then \
+ 	  make --no-print-directory gdb_unzip; fi
+-	@echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic" > ${GDB}/gdb/mergelibs
++	@echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic -Wl,-z,now -fpie" > ${GDB}/gdb/mergelibs
+ 	@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
+ 	@rm -f ${PROGRAM}
+ 	@if [ ! -f ${GDB}/config.status ]; then \
+--- crash-7.2.3/configure.c.orig
++++ crash-7.2.3/configure.c
+@@ -780,7 +780,8 @@ build_configure(struct supported_gdb_ver
+                         fprintf(fp2, "%s\n", sp->GDB);
+                         sprintf(target_data.gdb_version, "%s", &sp->GDB[4]);
+ 		} else if (strncmp(buf, "LDFLAGS=", strlen("LDFLAGS=")) == 0) {
+-                       	fprintf(fp2, "LDFLAGS=%s\n", ldflags ? ldflags : "");
++			if (ldflags)
++                       		fprintf(fp2, "LDFLAGS=%s\n", ldflags ? ldflags : "");
+ 		} else
+ 			fprintf(fp2, "%s", buf);
+ 
diff --git a/SOURCES/rhel8_ppc64_max_physmem_bits.patch b/SOURCES/rhel8_ppc64_max_physmem_bits.patch
new file mode 100644
index 0000000..28cd4cf
--- /dev/null
+++ b/SOURCES/rhel8_ppc64_max_physmem_bits.patch
@@ -0,0 +1,15 @@
+--- crash-7.2.3/ppc64.c.orig
++++ crash-7.2.3/ppc64.c
+@@ -583,8 +583,11 @@ ppc64_init(int when)
+ 			ppc64_vmemmap_init();
+ 
+ 		machdep->section_size_bits = _SECTION_SIZE_BITS;
++
++#define is_RHEL8() (strstr(kt->proc_version, ".el8."))
++
+ 		if ((machdep->flags & VMEMMAP) &&
+-		    (THIS_KERNEL_VERSION >= LINUX(4,19,0)))
++		    ((THIS_KERNEL_VERSION >= LINUX(4,19,0)) || is_RHEL8()))
+ 			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
+ 		else if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
+ 			machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_7;
diff --git a/SPECS/crash.spec b/SPECS/crash.spec
new file mode 100644
index 0000000..8a25125
--- /dev/null
+++ b/SPECS/crash.spec
@@ -0,0 +1,617 @@
+#
+# crash core analysis suite
+#
+Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
+Name: crash
+Version: 7.2.3
+Release: 18%{?dist}
+License: GPLv3
+Group: Development/Debuggers
+Source: http://people.redhat.com/anderson/crash-%{version}.tar.gz
+URL: http://people.redhat.com/anderson
+ExclusiveOS: Linux
+ExclusiveArch: %{ix86} ia64 x86_64 ppc ppc64 s390 s390x %{arm} aarch64 ppc64le
+Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n)
+BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel
+Requires: binutils
+Patch0: lzo_snappy.patch
+Patch1: github_46d21219_to_9446958f.patch
+Patch2: github_95daa11b.patch
+Patch3: github_b9d76838_c79a11fa_proc_kcore.patch
+Patch4: github_1926150e_ppc64_stacksize.patch
+Patch5: github_28fa7bd0_to_02efd083.patch
+Patch6: github_9b494b70_to_eb823b79.patch
+Patch7: github_a10917ba_to_e9532aea.patch
+Patch8: rhel8_build.patch
+Patch9: github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
+Patch10: github_3141bba9.patch
+Patch11: github_c5f45d6c.patch
+Patch12: github_f3a53059.patch
+Patch13: github_64dad6d0.patch
+Patch14: rhel8_ppc64_max_physmem_bits.patch
+Patch15: github_27a6ebd0_dev-p.patch
+Patch16: github_ced52552_dev-p_offsets.patch
+Patch17: github_361f050e_dev-d.patch
+Patch18: github_0f65ae0c_readline.patch
+Patch19: github_6b93714b_cmdline.patch
+Patch20: github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
+Patch21: github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
+Patch22: github_a89ec821_vmcoreinfo_plugin.patch
+Patch23: github_2f57a96c_files-c-p.patch
+
+%description
+The core analysis suite is a self-contained tool that can be used to
+investigate either live systems, kernel core dumps created from the
+netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch
+offered by Mission Critical Linux, or the LKCD kernel patch.
+
+%package devel
+Requires: %{name} = %{version}, zlib-devel lzo-devel snappy-devel
+Summary: kernel crash analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
+Group: Development/Debuggers
+
+%description devel
+The core analysis suite is a self-contained tool that can be used to
+investigate either live systems, kernel core dumps created from the
+netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch
+offered by Mission Critical Linux, or the LKCD kernel patch.
+
+%prep
+%setup -n %{name}-%{version} -q
+%patch0 -p1 -b lzo_snappy.patch
+%patch1 -p1 -b github_46d21219_to_9446958f.patch
+%patch2 -p1 -b github_95daa11b.patch
+%patch3 -p1 -b github_b9d76838_c79a11fa_proc_kcore.patch
+%patch4 -p1 -b github_1926150e_ppc64_stacksize.patch
+%patch5 -p1 -b github_28fa7bd0_to_02efd083.patch
+%patch6 -p1 -b github_9b494b70_to_eb823b79.patch
+%patch7 -p1 -b github_a10917ba_to_e9532aea.patch
+%patch8 -p1 -b rhel8_build.patch
+%patch9 -p1 -b github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
+%patch10 -p1 -b github_3141bba9.patch 
+%patch11 -p1 -b github_c5f45d6c.patch
+%patch12 -p1 -b github_f3a53059.patch
+%patch13 -p1 -b github_64dad6d0.patch
+%patch14 -p1 -b rhel8_ppc64_max_physmem_bits.patch
+%patch15 -p1 -b github_27a6ebd0_dev-p.patch
+%patch16 -p1 -b github_ced52552_dev-p_offsets.patch
+%patch17 -p1 -b github_361f050e_dev-d.patch
+%patch18 -p1 -b github_0f65ae0c_readline.patch
+%patch19 -p1 -b github_6b93714b_cmdline.patch
+%patch20 -p1 -b github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
+%patch21 -p1 -b github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
+%patch22 -p1 -b github_a89ec821_vmcoreinfo_plugin.patch
+%patch23 -p1 -b github_2f57a96c_files-c-p.patch
+
+%build
+make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}"
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_bindir}
+make DESTDIR=%{buildroot} install
+mkdir -p %{buildroot}%{_mandir}/man8
+cp -p crash.8 %{buildroot}%{_mandir}/man8/crash.8
+mkdir -p %{buildroot}%{_includedir}/crash
+chmod 0644 defs.h
+cp -p defs.h %{buildroot}%{_includedir}/crash
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/crash
+%{_mandir}/man8/crash.8*
+%doc README COPYING3
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/*
+
+%changelog
+* Thu Feb 14 2019 Dave Anderson <anderson@redhat.com> - 7.2.3-18
+- Fix "files -c" and "files -p" options
+  Resolves: rhbz#1673285
+
+* Mon Feb 11 2019 Dave Anderson <anderson@redhat.com> - 7.2.3-17
+- Support for CONFIG_ARM64_USER_VA_BITS_52 and CONFIG_ARM64_PA_BITS=52
+  Resolves: rhbz#1670099
+
+* Tue Jan  8 2019 Dave Anderson <anderson@redhat.com> - 7.2.3-16
+- Resurrect "dev -p" option.
+- Fix "dev -[dD]" options to account for request_queue.in_flight[] removal.
+  Resolves: rhbz#1662039
+- Command line input fixes
+  Resolves: rhbz#1664061
+
+* Thu Dec 13 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-15
+- Increase ppc64 MAX_PHYSMEM_BITS to match 4.18.0-35.el8 kernel backport
+  Resolves: rhbz#1658628
+
+* Thu Nov 29 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-14
+- Fix for ARM64 "ps -s" memory allocation failure
+  Resolves: rhbz#1654582
+
+* Thu Oct 25 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-13
+- Change "bt" warnings when exception RIP is legitimate mapped address
+  Resolves: rhbz#1642221
+
+* Mon Oct 15 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-12
+- Address covscan issues
+  Resolves: rhbz#1602466
+- Fix for x86_64 5-level pagetable vmalloc range expansion
+  Resolves: rhbz#1637125
+
+* Wed Oct  4 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-11
+- Fix ppc64 backtrace issues
+  Resolves: rhbz#1633525
+
+* Wed Sep 19 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-10
+- Address annocheck build issues
+  Resolves: rhbz#1624101
+ 
+* Thu Aug  9 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-9
+- Fix for live system (/proc/kcore) access when KALSR is in effect
+  Resolves: rhbz#1611916
+
+* Mon Jul 16 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-8
+- Rebase to github commits 9b494b70_to_eb823b79
+  Resolves: rhbz#1563495
+
+* Fri Jun 22 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-7
+- Rebase to github commits 28fa7bd0 to 02efd083
+  Resolves: rhbz#1590751
+  Resolves: rhbz#1592746
+
+* Tue Jun 12 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-6
+- github commit 1926150e: fix ppc64/ppc6le stacksize calculation
+
+* Fri Jun  8 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-5
+- Remove /dev/mem readmem error message and /proc/kcore switch messages 
+  Resolves: rhbz#1585944
+
+* Fri Jun  1 2018 Dave Anderson <anderson@redhat.com> - 7.2.3-4
+- Rebase to latest upstream sources
+
+* Tue Nov 21 2017 Dave Anderson <anderson@redhat.com> - 7.2.0-2
+- Rebase to github commits da9bd35a to e2efacdd
+  Resolves: rhbz#1497316
+
+* Wed Nov  1 2017 Dave Anderson <anderson@redhat.com> - 7.2.0-1
+- Rebase to upstream version 7.2.0
+- Rebase to github commits da9bd35a_to_e2efacdd.patch
+  Resolves: rhbz#1497316
+- ppc64le: fix for "WARNING: cannot access vmalloc'd module memory"
+  Resolves: rhbz#1485391
+- Support for analyzing an SADUMP crash dump if KASLR is enabled
+  Resolves: rhbz#1504467
+
+* Wed May  3 2017 Dave Anderson <anderson@redhat.com> - 7.1.9-2
+- Rebase to github commits 87179026 to ad3b8476
+  Resolves: rhbz#1393534
+- Prohibit native gdb disassemble command when KASLR
+  Resolves: rhbz#1445649
+
+* Mon Apr 24 2017 Dave Anderson <anderson@redhat.com> - 7.1.9-1
+- Rebase to upstream version 7.1.9
+  Resolves: rhbz#1393534
+- Fix gdb "set scope" option for KASLR kernels.
+  Resolves: rhbz#1440725
+- Fix for the determination of the x86_64 "phys_base" value when it is
+  not passed in the VMCOREINFO data of ELF vmcores
+  Resolves: rhbz#1439170
+
+* Wed Mar  8 2017 Dave Anderson <anderson@redhat.com> - 7.1.8-2
+- mod [-sS] command may erroneously reassign module symbol addresses
+  Resolves: rhbz#1430091
+
+* Fri Feb 24 2017 Dave Anderson <anderson@redhat.com> - 7.1.8-1
+- Rebase to upstream version 7.1.8
+  Resolves: rhbz#1393534
+- POWER9 - Power ISA 3.0 related support for crash utility
+  Resolves: rhbz#1368711
+- crash package update - ppc64/ppc64le
+  Resolves: rhbz#1384944
+- exception RIP: unknown or invalid address
+  Resolves: rhbz#1350457
+- Crash does not always parse correctly the modules symbol tables
+  Resolves: rhbz#1360415
+- ARM64: crash live system from: WARNING: cannot read linux_banner string
+  Resolves: rhbz#1392007
+- kmem: invalid structure member offset: page_count
+  Resolves: rhbz#1392011
+- Kernel address space randomization [KASLR] support 
+  Resolves: rhbz#1392658
+- invalid structure size: tnt
+  Resolves: rhbz#1420653
+
+* Wed Sep 14 2016 Dave Anderson <anderson@redhat.com> - 7.1.5-2
+- Fix for kernel module symbol gathering when the ordering of module
+  symbol name strings does not match the order of the kernel_symbol
+  structures.
+- Resolves: rhbz#1375130
+
+* Thu Apr 28 2016 Dave Anderson <anderson@redhat.com> - 7.1.5-1
+- Rebase to upstream version 7.1.5
+  Resolves: rhbz#1292566
+- Decode clflushopt instruction
+  Resolves: rhbz#1262479
+- Support AArch64 QEMU generated dumps 
+  Resolves: rhbz#1299873
+- crash: zero-size memory allocation (aarch64) 
+  Resolves: rhbz#1312738
+
+* Tue Apr  5 2016 Dave Anderson <anderson@redhat.com> - 7.1.2-4
+- crash: fails to read excluded pages by default on sadump-related format
+  Resolves: rhbz#1304260
+
+* Mon Nov 23 2015 Dave Anderson <anderson@redhat.com> - 7.1.2-3
+- crash fails to read or wrongly reads some parts of memory in sadump vmcore format
+  Resolves: rhbz#1282997
+
+* Tue Aug  4 2015 Dave Anderson <anderson@redhat.com> - 7.1.2-2
+- Fix "kmem -s <address>", "bt -F[F]", and "rd -S[S]" options in kernels 
+  configured with CONFIG_SLUB having multiple-page slabs.
+  Resolves: rhbz#1244003
+- Fix for SIGSEGV generated by "bt -[f|F]" in ARM64 kernels.
+  Resolves: rhbz#1248859
+ 
+* Mon Jul 13 2015 Dave Anderson <anderson@redhat.com> - 7.1.2-1
+- Rebase to upstream version 7.1.2
+  Resolves: rhbz#1207696
+- Fix several ppc64 backtrace issues
+  Resolves: rhbz#1235447 
+
+* Fri Jun 05 2015 Dave Anderson <anderson@redhat.com> - 7.1.1-2
+- ARM64 backtrace enhancements
+  Resolves: rhbz#1227508
+
+* Thu May 28 2015 Dave Anderson <anderson@redhat.com> - 7.1.1-1
+- Rebase to upstream version 7.1.1
+  Resolves: rhbz#1207696
+- Display s390x vector registers from a kernel dump.
+  Resolves: rhbz#1182161
+- Fix date displayed on initial system banner and by the "sys" command on ARM64.
+  Resolves: rhbz#1223044
+- Fix ARM64 page size calculation on 4.1 and later kernels.
+  Resolves: rhbz#1222645
+
+* Tue Apr 21 2015 Dave Anderson <anderson@redhat.com> - 7.0.9-6
+- Calculate ARM64 virtual memory layout based upon struct page size 
+  Resolves: rhbz#1204941
+
+* Tue Apr  7 2015 Dave Anderson <anderson@redhat.com> - 7.0.9-5
+- Support new sadump format that can represent more than 16 TB physical memory space
+  Resolves: rhbz#1182383
+
+* Mon Jan 26 2015 Dave Anderson <anderson@redhat.com> - 7.0.9-4
+  Fix ppc64 "bt" command for active tasks in compressed kdumps.
+  Resolves: rhbz#1184401
+
+* Mon Jan 12 2015 Dave Anderson <anderson@redhat.com> - 7.0.9-3
+  Fix "bt" command mislabeling errors.
+  Resolves: rhbz#1179476
+
+* Mon Dec 08 2014 Dave Anderson <anderson@redhat.com> - 7.0.9-2
+- Use registers from QEMU-generated ELF and compressed kdump headers 
+  for active task backtraces.
+- Resolves: rhbz#1169555
+
+* Fri Nov 14 2014 Dave Anderson <anderson@redhat.com> - 7.0.9-1
+- Rebase to upstream version 7.0.9.
+- Resolves: rhbz#1110513
+
+* Tue Sep 23 2014 Dave Anderson <anderson@redhat.com> - 7.0.8-2
+- Fix ps performance patch regression on live systems.
+- Resolves: rhbz#1134177
+- Minor build-related fixes for ppc64le.
+- Resolves: rhbz#1123991
+
+* Fri Sep 12 2014 Dave Anderson <anderson@redhat.com> - 7.0.8-1
+- Rebase to upstream version 7.0.8.
+- Resolves: rhbz#1110513
+- Fix to calculate the physical base address of dumpfiles created
+  by a "virsh dump" of an OVMF guest.
+- Resolves: rhbz#1080698
+- Support for aarch64 architecture.
+- Resolves: rhbz#1110551
+- Fix to prevent crash from spinning endlessly on a corrupted/truncated
+  dumpfile whose bitmap data is not wholly contained within the file.
+- Resolves: rhbz#1114088
+- Support for ppc64le architecture.
+- Resolves: rhbz#1123991
+
+* Tue Jan 28 2014 Daniel Mach <dmach@redhat.com> - 7.0.2-6
+- Mass rebuild 2014-01-24
+
+* Fri Jan 24 2014 Dave Anderson <anderson@redhat.com> - 7.0.2-5
+- Fix for a missing kernel-mode exception frame dump by the x86_64 
+  "bt" command if a page fault was generated by a bogus RIP.
+- Resolves: rhbz#1057353
+- Fix for the x86_64 "bt" command to prevent an unwarranted message
+  indicating "WARNING: possibly bogus exception frame" generated
+  from a blocked kernel thread that was in the process of exec'ing
+  a user process via the call_usermodehelper() facility.
+- Resolves: rhbz#1057357
+
+* Fri Jan 10 2014 Dave Anderson <anderson@redhat.com> - 7.0.2-4
+- Fixes for "kmem -S" command for CONFIG_SLUB.
+- Resolves: rhbz#1045591
+- Increase S390X NR_CPUS
+- Resolves: rhbz#1051156
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 7.0.2-3
+- Mass rebuild 2013-12-27
+
+* Tue Oct 29 2013 Dave Anderson <anderson@redhat.com> - 7.0.2-2
+- Compressed kdump 46-bit physical memory support
+  Resolves: rhbz#1015250
+- Fix incorrect backtrace for dumps taken with "virsh dump --memory-only"
+  Resolves: rhbz#1020469
+- Fix cpu number display on systems with more than 254 cpus
+  Resolves: rhbz#1020536
+
+* Wed Sep 04 2013 Dave Anderson <anderson@redhat.com> - 7.0.2-1
+- Update to latest upstream release
+- Fix for ppc64 embedded gdb NULL pointer translation sigsegv
+- Fix for bt -F failure
+
+* Fri Jul 26 2013 Dave Anderson <anderson@redhat.com> - 7.0.1-4
+- Add lzo-devel and snappy-devel to crash-devel Requires line
+
+* Tue Jul 23 2013 Dave Anderson <anderson@redhat.com> - 7.0.1-3
+- Build with snappy compression support
+
+* Tue Jul  9 2013 Dave Anderson <anderson@redhat.com> - 7.0.1-2
+- Fix for ppc64 Linux 3.10 vmalloc/user-space virtual address translation
+
+* Tue Jun 18 2013 Dave Anderson <anderson@redhat.com> - 7.0.1-1
+- Update to latest upstream release
+- Build with LZO support
+
+* Tue Apr  9 2013 Dave Anderson <anderson@redhat.com> - 6.1.6-1
+- Update to latest upstream release
+
+* Tue Feb 19 2013 Dave Anderson <anderson@redhat.com> - 6.1.4-1
+- Update to latest upstream release
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.1.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Wed Jan  9 2013 Dave Anderson <anderson@redhat.com> - 6.1.2-1
+- Update to latest upstream release
+
+* Tue Nov 27 2012 Dave Anderson <anderson@redhat.com> - 6.1.1-1
+- Update to latest upstream release
+
+* Mon Sep  1 2012 Dave Anderson <anderson@redhat.com> - 6.1.0-1
+- Add ppc to ExclusiveArch list
+- Update to latest upstream release
+
+* Tue Aug 21 2012 Dave Anderson <anderson@redhat.com> - 6.0.9-1
+- Update to latest upstream release
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 6.0.8-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Mon Jul  1 2012 Dave Anderson <anderson@redhat.com> - 6.0.8-1
+- Update to latest upstream release.
+- Replace usage of "struct siginfo" with "siginfo_t".
+
+* Mon Apr 30 2012 Dave Anderson <anderson@redhat.com> - 6.0.6-1
+- Update to latest upstream release
+
+* Mon Mar 26 2012 Dave Anderson <anderson@redhat.com> - 6.0.5-1
+- Update to latest upstream release
+
+* Wed Jan  4 2012 Dave Anderson <anderson@redhat.com> - 6.0.2-1
+- Update to latest upstream release
+
+* Wed Oct 26 2011 Dave Anderson <anderson@redhat.com> - 6.0.0-1
+- Update to latest upstream release
+
+* Tue Sep 20 2011 Dave Anderson <anderson@redhat.com> - 5.1.8-1
+- Update to latest upstream release
+- Additional fixes for gcc-4.6 -Werror compile failures for ARM architecture.
+
+* Thu Sep  1 2011 Dave Anderson <anderson@redhat.com> - 5.1.7-2
+- Fixes for gcc-4.6 -Werror compile failures for ARM architecture.
+
+* Wed Aug 17 2011 Dave Anderson <anderson@redhat.com> - 5.1.7-1
+- Update to latest upstream release
+- Fixes for gcc-4.6 -Werror compile failures for ppc64/ppc.
+
+* Tue May 31 2011 Peter Robinson <pbrobinson@gmail.com> - 5.1.5-1
+- Update to latest upstream release
+- Add ARM to the Exclusive arch
+
+* Wed Feb 25 2011 Dave Anderson <anderson@redhat.com> - 5.1.2-2
+- Fixes for gcc-4.6 -Werror compile failures in gdb module.  
+
+* Wed Feb 23 2011 Dave Anderson <anderson@redhat.com> - 5.1.2-1
+- Upstream version.
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.0.6-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Tue Jul 20 2010 Dave Anderson <anderson@redhat.com> - 5.0.6-2
+- Bump version.
+
+* Tue Jul 20 2010 Dave Anderson <anderson@redhat.com> - 5.0.6-1
+- Update to upstream version.
+
+* Fri Sep 11 2009 Dave Anderson <anderson@redhat.com> - 4.0.9-2
+  Bump version.
+
+* Fri Sep 11 2009 Dave Anderson <anderson@redhat.com> - 4.0.9-1
+- Update to upstream release, which allows the removal of the 
+  Revision tag workaround, the crash-4.0-8.11-dwarf3.patch and 
+  the crash-4.0-8.11-optflags.patch
+
+* Sun Aug 05 2009 Lubomir Rintel <lkundrak@v3.sk> - 4.0.8.11-2
+- Fix reading of dwarf 3 DW_AT_data_member_location
+- Use proper compiler flags
+
+* Wed Aug 05 2009 Lubomir Rintel <lkundrak@v3.sk> - 4.0.8.11-1
+- Update to later upstream release
+- Fix abuse of Revision tag
+
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.0-9.7.2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.0-8.7.2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Thu Feb 19 2009 Dave Anderson <anderson@redhat.com> - 4.0-7.7.2
+- Replace exclusive arch i386 with ix86.
+
+* Thu Feb 19 2009 Dave Anderson <anderson@redhat.com> - 4.0-7.7.1
+- Updates to this file per crash merge review
+- Update to upstream version 4.0-7.7.  Full changelog viewable in:
+    http://people.redhat.com/anderson/crash.changelog.html
+
+* Tue Jul 15 2008 Tom "spot" Callaway <tcallawa@redhat.com> 4.0-7
+- fix license tag
+
+* Tue Apr 29 2008 Dave Anderson <anderson@redhat.com> - 4.0-6.3
+- Added crash-devel subpackage
+- Updated crash.patch to match upstream version 4.0-6.3
+
+* Wed Feb 20 2008 Dave Anderson <anderson@redhat.com> - 4.0-6.0.5
+- Second attempt at addressing the GCC 4.3 build, which failed due
+  to additional ptrace.h includes in the lkcd vmdump header files.
+
+* Wed Feb 20 2008 Dave Anderson <anderson@redhat.com> - 4.0-6.0.4
+- First attempt at addressing the GCC 4.3 build, which failed on x86_64
+  because ptrace-abi.h (included by ptrace.h) uses the "u32" typedef,
+  which relies on <asm/types.h>, and include/asm-x86_64/types.h
+  does not not typedef u32 as done in include/asm-x86/types.h.
+
+* Mon Feb 18 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 4.0-6.0.3
+- Autorebuild for GCC 4.3
+
+* Wed Jan 23 2008 Dave Anderson <anderson@redhat.com> - 4.0-5.0.3
+- Updated crash.patch to match upstream version 4.0-5.0.
+
+* Wed Aug 29 2007 Dave Anderson <anderson@redhat.com> - 4.0-4.6.2
+- Updated crash.patch to match upstream version 4.0-4.6.
+
+* Wed Sep 13 2006 Dave Anderson <anderson@redhat.com> - 4.0-3.3
+- Updated crash.patch to match upstream version 4.0-3.3.
+- Support for x86_64 relocatable kernels.  BZ #204557
+
+* Mon Aug  7 2006 Dave Anderson <anderson@redhat.com> - 4.0-3.1
+- Updated crash.patch to match upstream version 4.0-3.1.
+- Added kdump reference to description.
+- Added s390 and s390x to ExclusiveArch list.  BZ #199125
+- Removed LKCD v1 pt_regs references for s390/s390x build.
+- Removed LKCD v2_v3 pt_regs references for for s390/s390x build.
+
+* Fri Jul 14 2006 Jesse Keating <jkeating@redhat.com> - 4.0-3
+- rebuild
+
+* Mon May 15 2006 Dave Anderson <anderson@redhat.com> - 4.0-2.26.4
+- Updated crash.patch such that <asm/page.h> is not #include'd
+  by s390_dump.c; IBM did not make the file s390[s] only; BZ #192719
+
+* Mon May 15 2006 Dave Anderson <anderson@redhat.com> - 4.0-2.26.3
+- Updated crash.patch such that <asm/page.h> is not #include'd
+  by vas_crash.h; only ia64 build complained; BZ #191719
+
+* Mon May 15 2006 Dave Anderson <anderson@redhat.com> - 4.0-2.26.2
+- Updated crash.patch such that <asm/segment.h> is not #include'd
+  by lkcd_x86_trace.c; also for BZ #191719
+
+* Mon May 15 2006 Dave Anderson <anderson@redhat.com> - 4.0-2.26.1
+- Updated crash.patch to bring it up to 4.0-2.26, which should 
+  address BZ #191719 - "crash fails to build in mock"
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 4.0-2.18.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Wed Jan 04 2006 Dave Anderson <anderson@redhat.com> 4.0-2.18
+- Updated source package to crash-4.0.tar.gz, and crash.patch
+  to bring it up to 4.0-2.18.
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Thu Mar 03 2005 Dave Anderson <anderson@redhat.com> 3.10-13
+- Compiler error- and warning-related fixes for gcc 4 build.
+- Update to enhance x86 and x86_64 gdb disassembly output so as to
+  symbolically display call targets from kernel module text without
+  requiring module debuginfo data.
+- Fix hole where an ia64 vmcore could be mistakenly accepted as a
+  usable dumpfile on an x86_64 machine, leading eventually to a
+  non-related error message.
+* Wed Mar 02 2005 Dave Anderson <anderson@redhat.com> 3.10-12
+- rebuild (gcc 4)
+* Thu Feb 10 2005 Dave Anderson <anderson@redhat.com> 3.10-9
+- Updated source package to crash-3.10.tar.gz, containing
+  IBM's final ppc64 processor support for RHEL4
+- Fixes potential "bt -a" hang on dumpfile where netdump IPI interrupted
+  an x86 process while executing the instructions just after it had entered
+  the kernel for a syscall, but before calling the handler.  BZ #139437
+- Update to handle backtraces in dumpfiles generated on IA64 with the
+  INIT switch (functionality intro'd in RHEL3-U5 kernel).  BZ #139429
+- Fix for handling ia64 and x86_64 machines booted with maxcpus=1 on
+  an SMP kernel.  BZ #139435
+- Update to handle backtraces in dumpfiles generated on x86_64 from the
+  NMI exception stack (functionality intro'd in RHEL3-U5 kernel).
+- "kmem -[sS]" beefed up to more accurately verify slab cache chains
+  and report errors found.
+- Fix for ia64 INIT switch-generated backtrace handling when
+  init_handler_platform() is inlined into ia64_init_handler();
+  properly handles both RHEL3 and RHEL4 kernel patches.
+  BZ #138350
+- Update to enhance ia64 gdb disassembly output so as to
+  symbolically display call targets from kernel module
+  text without requiring module debuginfo data.
+
+* Wed Jul 14 2004 Dave Anderson <anderson@redhat.com> 3.8-5
+- bump release for fc3
+
+* Tue Jul 13 2004 Dave Anderson <anderson@redhat.com> 3.8-4
+- Fix for gcc 3.4.x/gdb issue where vmlinux was mistakenly presumed non-debug 
+
+* Fri Jun 25 2004 Dave Anderson <anderson@redhat.com> 3.8-3
+- remove (harmless) error message during ia64 diskdump invocation when
+  an SMP system gets booted with maxcpus=1
+- several 2.6 kernel specific updates
+
+* Thu Jun 17 2004 Dave Anderson <anderson@redhat.com> 3.8-2
+- updated source package to crash-3.8.tar.gz 
+- diskdump support
+- x86_64 processor support 
+
+* Mon Sep 22 2003 Dave Anderson <anderson@redhat.com> 3.7-5
+- make bt recovery code start fix-up only upon reaching first faulting frame
+
+* Fri Sep 19 2003 Dave Anderson <anderson@redhat.com> 3.7-4
+- fix "bt -e" and bt recovery code to recognize new __KERNEL_CS and DS
+
+* Wed Sep 10 2003 Dave Anderson <anderson@redhat.com> 3.7-3
+- patch to recognize per-cpu GDT changes that redefine __KERNEL_CS and DS
+
+* Wed Sep 10 2003 Dave Anderson <anderson@redhat.com> 3.7-2
+- patches for netdump active_set determination and slab info gathering 
+
+* Wed Aug 20 2003 Dave Anderson <anderson@redhat.com> 3.7-1
+- updated source package to crash-3.7.tar.gz
+
+* Wed Jul 23 2003 Dave Anderson <anderson@redhat.com> 3.6-1
+- removed Packager, Distribution, and Vendor tags
+- updated source package to crash-3.6.tar.gz 
+
+* Fri Jul 18 2003 Jay Fenlason <fenlason@redhat.com> 3.5-2
+- remove ppc from arch list, since it doesn't work with ppc64 kernels
+- remove alpha from the arch list since we don't build it any more
+
+* Fri Jul 18 2003 Matt Wilson <msw@redhat.com> 3.5-1
+- use %%defattr(-,root,root)
+
+* Tue Jul 15 2003 Jay Fenlason <fenlason@redhat.com>
+- Updated spec file as first step in turning this into a real RPM for taroon.
+- Wrote man page.