Blame SOURCES/github_105a3e13_to_b5c2359f.patch

145e27
commit 105a3e13167665dde5d3c12bf76ef9c916e82d0e
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Thu Oct 10 14:07:22 2019 -0400
145e27
145e27
    Fix for Linux 5.4-rc1 and later kernels that contain commit
145e27
    688fcbfc06e4fdfbb7e1d5a942a1460fe6379d2d, titled "mm/vmalloc:
145e27
    modify struct vmap_area to reduce its size".  Without the
145e27
    patch "kmem -v" will display nothing; other architectures
145e27
    that utilize the vmap_area_list to determine the base of
145e27
    mapped/vmalloc address space will fail.
145e27
    (anderson@redhat.com)
145e27
145e27
diff --git a/memory.c b/memory.c
145e27
index 3a8b998..fe82fac 100644
145e27
--- a/memory.c
145e27
+++ b/memory.c
145e27
@@ -401,9 +401,10 @@ vm_init(void)
145e27
 	STRUCT_SIZE_INIT(vmap_area, "vmap_area");
145e27
 	if (VALID_MEMBER(vmap_area_va_start) &&
145e27
 	    VALID_MEMBER(vmap_area_va_end) &&
145e27
-	    VALID_MEMBER(vmap_area_flags) &&
145e27
 	    VALID_MEMBER(vmap_area_list) &&
145e27
 	    VALID_MEMBER(vmap_area_vm) &&
145e27
+	    (VALID_MEMBER(vmap_area_flags) || 
145e27
+		(OFFSET(vmap_area_vm) == MEMBER_OFFSET("vmap_area", "purge_list"))) &&
145e27
 	    kernel_symbol_exists("vmap_area_list"))
145e27
 		vt->flags |= USE_VMAP_AREA;
145e27
 
145e27
@@ -8742,7 +8743,7 @@ static void
145e27
 dump_vmap_area(struct meminfo *vi)
145e27
 {
145e27
 	int i, cnt;
145e27
-	ulong start, end, vm_struct, flags;
145e27
+	ulong start, end, vm_struct, flags, vm;
145e27
 	struct list_data list_data, *ld;
145e27
 	char *vmap_area_buf; 
145e27
 	ulong size, pcheck, count, verified; 
145e27
@@ -8790,9 +8791,15 @@ dump_vmap_area(struct meminfo *vi)
145e27
 		readmem(ld->list_ptr[i], KVADDR, vmap_area_buf,
145e27
                         SIZE(vmap_area), "vmap_area struct", FAULT_ON_ERROR); 
145e27
 
145e27
-		flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags));
145e27
-		if (flags != VM_VM_AREA)
145e27
-			continue;
145e27
+		if (VALID_MEMBER(vmap_area_flags)) {
145e27
+			flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags));
145e27
+			if (flags != VM_VM_AREA)
145e27
+				continue;
145e27
+		} else {
145e27
+			vm = ULONG(vmap_area_buf + OFFSET(vmap_area_vm));
145e27
+			if (!vm)
145e27
+				continue;
145e27
+		}
145e27
 		start = ULONG(vmap_area_buf + OFFSET(vmap_area_va_start));
145e27
 		end = ULONG(vmap_area_buf + OFFSET(vmap_area_va_end));
145e27
 		vm_struct = ULONG(vmap_area_buf + OFFSET(vmap_area_vm));
145e27
145e27
commit 82ce13bceb1082a7c53c1bda71e17ca9c2a5cbc4
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Fri Oct 11 11:14:28 2019 -0400
145e27
145e27
    Fix for Linux 5.4-rc1 and later kernels that contain commit/merge
145e27
    e0703556644a531e50b5dc61b9f6ea83af5f6604, titled "Merge tag 'modules-
145e27
    for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux
145e27
    which introduces symbol namespaces.  Without the patch, and depending
145e27
    upon the architecture:
145e27
     (1) the kernel module symbol list will contain garbage entries
145e27
     (2) the session fails during session initialization with a dump of
145e27
         the internal buffer allocation stats followed by the message
145e27
         "crash: cannot allocate any more memory!"
145e27
     (3) the session fails during session initialization with a
145e27
         segmentation violation.
145e27
    (anderson@redhat.com)
145e27
145e27
diff --git a/defs.h b/defs.h
145e27
index 32bd147..502e7c2 100644
145e27
--- a/defs.h
145e27
+++ b/defs.h
145e27
@@ -2694,6 +2694,7 @@ struct symbol_table_data {
145e27
 	ulong saved_command_line_vmlinux;
145e27
 	ulong pti_init_vmlinux;
145e27
 	ulong kaiser_init_vmlinux;
145e27
+	int kernel_symbol_type;
145e27
 };
145e27
 
145e27
 /* flags for st */
145e27
diff --git a/symbols.c b/symbols.c
145e27
index 3ce8692..7af5e69 100644
145e27
--- a/symbols.c
145e27
+++ b/symbols.c
145e27
@@ -1607,39 +1607,100 @@ union kernel_symbol {
145e27
 		unsigned long value;
145e27
 		const char *name;
145e27
 	} v1;
145e27
-	/* kernel 4.19 introduced relative symbol positionning */
145e27
+	/* kernel 4.19 introduced relative symbol positioning */
145e27
 	struct kernel_symbol_v2 {
145e27
 		int value_offset;
145e27
 		int name_offset;
145e27
 	} v2;
145e27
+	/* kernel 5.4 introduced symbol namespaces */
145e27
+	struct kernel_symbol_v3 {
145e27
+		int value_offset;
145e27
+		int name_offset;
145e27
+		int namespace_offset;
145e27
+	} v3;
145e27
+	struct kernel_symbol_v4 {
145e27
+		unsigned long value;
145e27
+		const char *name;
145e27
+		const char *namespace;
145e27
+	} v4;
145e27
 };
145e27
 
145e27
+static size_t
145e27
+kernel_symbol_type_init(void)
145e27
+{
145e27
+	if (MEMBER_EXISTS("kernel_symbol", "value") &&
145e27
+	    MEMBER_EXISTS("kernel_symbol", "name")) {
145e27
+		if (MEMBER_EXISTS("kernel_symbol", "namespace")) {
145e27
+			st->kernel_symbol_type = 4;
145e27
+			return (sizeof(struct kernel_symbol_v4));
145e27
+		} else {
145e27
+			st->kernel_symbol_type = 1;
145e27
+			return (sizeof(struct kernel_symbol_v1));
145e27
+		}
145e27
+	}
145e27
+	if (MEMBER_EXISTS("kernel_symbol", "value_offset") &&
145e27
+	    MEMBER_EXISTS("kernel_symbol", "name_offset")) {
145e27
+		if (MEMBER_EXISTS("kernel_symbol", "namespace_offset")) {
145e27
+			st->kernel_symbol_type = 3;
145e27
+			return (sizeof(struct kernel_symbol_v3));
145e27
+		} else {
145e27
+			st->kernel_symbol_type = 2;
145e27
+			return (sizeof(struct kernel_symbol_v2));
145e27
+		}
145e27
+	}
145e27
+
145e27
+	error(FATAL, "kernel_symbol data structure has changed\n");
145e27
+
145e27
+	return 0;
145e27
+}
145e27
+
145e27
 static ulong
145e27
 modsym_name(ulong syms, union kernel_symbol *modsym, int i)
145e27
 {
145e27
-	if (VALID_MEMBER(kernel_symbol_value))
145e27
+	switch (st->kernel_symbol_type)
145e27
+	{
145e27
+	case 1:
145e27
 		return (ulong)modsym->v1.name;
145e27
+	case 2:
145e27
+		return (syms + i * sizeof(struct kernel_symbol_v2) +
145e27
+			offsetof(struct kernel_symbol_v2, name_offset) +
145e27
+			modsym->v2.name_offset);
145e27
+	case 3:
145e27
+		return (syms + i * sizeof(struct kernel_symbol_v3) +
145e27
+			offsetof(struct kernel_symbol_v3, name_offset) +
145e27
+			modsym->v3.name_offset);
145e27
+	case 4:
145e27
+		return (ulong)modsym->v4.name;
145e27
+	}
145e27
 
145e27
-	return syms + i * sizeof(struct kernel_symbol_v2) +
145e27
-		offsetof(struct kernel_symbol_v2, name_offset) +
145e27
-		modsym->v2.name_offset;
145e27
+	return 0;
145e27
 }
145e27
 
145e27
 static ulong
145e27
 modsym_value(ulong syms, union kernel_symbol *modsym, int i)
145e27
 {
145e27
-	if (VALID_MEMBER(kernel_symbol_value))
145e27
+	switch (st->kernel_symbol_type)
145e27
+	{
145e27
+	case 1:
145e27
 		return (ulong)modsym->v1.value;
145e27
+	case 2:
145e27
+		return (syms + i * sizeof(struct kernel_symbol_v2) +
145e27
+			offsetof(struct kernel_symbol_v2, value_offset) +
145e27
+			modsym->v2.value_offset);
145e27
+	case 3:
145e27
+		return (syms + i * sizeof(struct kernel_symbol_v3) +
145e27
+			offsetof(struct kernel_symbol_v3, value_offset) +
145e27
+			modsym->v3.value_offset);
145e27
+	case 4:
145e27
+		return (ulong)modsym->v4.value;
145e27
+	}
145e27
 
145e27
-	return syms + i * sizeof(struct kernel_symbol_v2) +
145e27
-		offsetof(struct kernel_symbol_v2, value_offset) +
145e27
-		modsym->v2.value_offset;
145e27
+	return 0;
145e27
 }
145e27
 
145e27
 void
145e27
 store_module_symbols_v2(ulong total, int mods_installed)
145e27
 {
145e27
-
145e27
         int i, m;
145e27
         ulong mod, mod_next; 
145e27
 	char *mod_name;
145e27
@@ -1675,12 +1736,7 @@ store_module_symbols_v2(ulong total, int mods_installed)
145e27
 		  "re-initialization of module symbols not implemented yet!\n");
145e27
 	}
145e27
 
145e27
-	MEMBER_OFFSET_INIT(kernel_symbol_value, "kernel_symbol", "value");
145e27
-	if (VALID_MEMBER(kernel_symbol_value)) {
145e27
-		kernel_symbol_size = sizeof(struct kernel_symbol_v1);
145e27
-	} else {
145e27
-		kernel_symbol_size = sizeof(struct kernel_symbol_v2);
145e27
-	}
145e27
+	kernel_symbol_size = kernel_symbol_type_init();
145e27
 
145e27
         if ((st->ext_module_symtable = (struct syment *)
145e27
              calloc(total, sizeof(struct syment))) == NULL)
145e27
@@ -3418,6 +3474,8 @@ dump_symbol_table(void)
145e27
 		fprintf(fp, "\n");
145e27
 	} else
145e27
 		fprintf(fp, "(none)\n");
145e27
+
145e27
+	fprintf(fp, "  kernel_symbol_type: v%d\n", st->kernel_symbol_type);
145e27
 }
145e27
 
145e27
 
145e27
145e27
commit c1ac656508ad064ef0ef222acb73621ae0bf4f00
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Tue Oct 15 11:21:55 2019 -0400
145e27
145e27
    Fix for the "timer -r" option on Linux 5.4-rc1 and later kernels
145e27
    that contain commit 511885d7061eda3eb1faf3f57dcc936ff75863f1, titled
145e27
    "lib/timerqueue: Rely on rbtree semantics for next timer".  Without
145e27
    the patch, the option fails with the following error "timer: invalid
145e27
    structure member offset: timerqueue_head_next".
145e27
    (k-hagio@ab.jp.nec.com)
145e27
145e27
diff --git a/defs.h b/defs.h
145e27
index 502e7c2..efa40b9 100644
145e27
--- a/defs.h
145e27
+++ b/defs.h
145e27
@@ -2073,6 +2073,8 @@ struct offset_table {                    /* stash of commonly-used offsets */
145e27
 	long cpu_context_save_r7;
145e27
 	long dentry_d_sb;
145e27
 	long device_private_knode_class;
145e27
+	long timerqueue_head_rb_root;
145e27
+	long rb_root_cached_rb_leftmost;
145e27
 };
145e27
 
145e27
 struct size_table {         /* stash of commonly-used sizes */
145e27
diff --git a/kernel.c b/kernel.c
145e27
index 375e1b4..c4cb001 100644
145e27
--- a/kernel.c
145e27
+++ b/kernel.c
145e27
@@ -783,7 +783,13 @@ kernel_init()
145e27
 		MEMBER_OFFSET_INIT(timerqueue_node_expires, 
145e27
 			"timerqueue_node", "expires");
145e27
 		MEMBER_OFFSET_INIT(timerqueue_node_node, 
145e27
-			"timerqueue_node_node", "node");
145e27
+			"timerqueue_node", "node");
145e27
+		if (INVALID_MEMBER(timerqueue_head_next)) {
145e27
+			MEMBER_OFFSET_INIT(timerqueue_head_rb_root,
145e27
+				"timerqueue_head", "rb_root");
145e27
+			MEMBER_OFFSET_INIT(rb_root_cached_rb_leftmost,
145e27
+				"rb_root_cached", "rb_leftmost");
145e27
+		}
145e27
 	}
145e27
 	MEMBER_OFFSET_INIT(hrtimer_softexpires, "hrtimer", "_softexpires");
145e27
 	MEMBER_OFFSET_INIT(hrtimer_function, "hrtimer", "function");
145e27
@@ -7647,11 +7653,17 @@ next_one:
145e27
 		readmem((ulong)(base + OFFSET(hrtimer_clock_base_first)),
145e27
 			KVADDR,	&curr, sizeof(curr), "hrtimer_clock_base first",
145e27
 			FAULT_ON_ERROR);
145e27
-	else
145e27
+	else if (VALID_MEMBER(timerqueue_head_next))
145e27
 		readmem((ulong)(base + OFFSET(hrtimer_clock_base_active) +
145e27
 				OFFSET(timerqueue_head_next)),
145e27
 			KVADDR, &curr, sizeof(curr), "hrtimer_clock base",
145e27
 			FAULT_ON_ERROR);
145e27
+	else
145e27
+		readmem((ulong)(base + OFFSET(hrtimer_clock_base_active) +
145e27
+				OFFSET(timerqueue_head_rb_root) +
145e27
+				OFFSET(rb_root_cached_rb_leftmost)),
145e27
+			KVADDR, &curr, sizeof(curr),
145e27
+			"hrtimer_clock_base active", FAULT_ON_ERROR);
145e27
 
145e27
 	while (curr && i < next) {
145e27
 		curr = rb_next(curr);
145e27
diff --git a/symbols.c b/symbols.c
145e27
index 7af5e69..eb88ca1 100644
145e27
--- a/symbols.c
145e27
+++ b/symbols.c
145e27
@@ -10032,6 +10032,8 @@ dump_offset_table(char *spec, ulong makestruct)
145e27
                 OFFSET(rb_node_rb_left));
145e27
         fprintf(fp, "              rb_node_rb_right: %ld\n",
145e27
                 OFFSET(rb_node_rb_right));
145e27
+        fprintf(fp, "    rb_root_cached_rb_leftmost: %ld\n",
145e27
+                OFFSET(rb_root_cached_rb_leftmost));
145e27
 
145e27
 	fprintf(fp, "            x8664_pda_pcurrent: %ld\n",
145e27
 		OFFSET(x8664_pda_pcurrent));
145e27
@@ -10388,6 +10390,8 @@ dump_offset_table(char *spec, ulong makestruct)
145e27
 		OFFSET(hrtimer_function));
145e27
 	fprintf(fp, "          timerqueue_head_next: %ld\n",
145e27
 		OFFSET(timerqueue_head_next));
145e27
+	fprintf(fp, "       timerqueue_head_rb_root: %ld\n",
145e27
+		OFFSET(timerqueue_head_rb_root));
145e27
 	fprintf(fp, "       timerqueue_node_expires: %ld\n",
145e27
 		OFFSET(timerqueue_node_expires));
145e27
 	fprintf(fp, "          timerqueue_node_node: %ld\n",
145e27
145e27
commit e13fe8ba5a0b9c54edea103a309e9879784d9b94
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Tue Oct 15 16:29:30 2019 -0400
145e27
145e27
    Fix for a "[-Wstringop-truncation]" compiler warning emitted when
145e27
    symbols.c is built in a Fedora Rawhide environment with gcc-9.0.1
145e27
    or later.
145e27
    (anderson@redhat.com)
145e27
145e27
diff --git a/symbols.c b/symbols.c
145e27
index eb88ca1..55199fc 100644
145e27
--- a/symbols.c
145e27
+++ b/symbols.c
145e27
@@ -8174,8 +8174,10 @@ parse_for_member_extended(struct datatype_member *dm,
145e27
 		 */
145e27
 
145e27
 		if (current && p && (p - p1 < BUFSIZE)) {
145e27
-			strncpy(current->field_name, p1, p - p1);
145e27
+//			strncpy(current->field_name, p1, p - p1);  (NOTE: gcc-9.0.1 emits [-Wstringop-truncation] warning)
145e27
 			current->field_len = p - p1;
145e27
+			memcpy(current->field_name, p1, current->field_len);
145e27
+			current->field_name[current->field_len] = '\0';
145e27
 		}
145e27
 
145e27
 		if ( p && (*s_e != '{' || (*s_e == '{' && buf[len] == '}') )) {
145e27
145e27
commit 9937878cce2fc049283d833685cb939caca462ca
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Thu Oct 17 12:00:23 2019 -0400
145e27
145e27
    Fix for the "kmem -n" option on Linux-5.4-rc1 and later kernels that
145e27
    contain commit b6c88d3b9d38f9448e0fcf44847a075ea81d5ca2, titled
145e27
    "drivers/base/memory.c: don't store end_section_nr in memory blocks".
145e27
    Without the patch, the command option fails with the error message
145e27
    "kmem: invalid structure member offset: memory_block_end_section_nr".
145e27
    (msys.mizuma@gmail.com)
145e27
145e27
diff --git a/help.c b/help.c
145e27
index a5218a7..cfd46c3 100644
145e27
--- a/help.c
145e27
+++ b/help.c
145e27
@@ -7177,7 +7177,7 @@ char *help_kmem[] = {
145e27
 "     6  ffff88003d4d90c0  ffffea0000000000  ffffea0000c00000   PM   196608",
145e27
 "     7  ffff88003d4d90e0  ffffea0000000000  ffffea0000e00000   PM   229376",
145e27
 "    ",
145e27
-"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE          SECTIONS",
145e27
+"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE          START_SECTION_NO",
145e27
 "     ffff88003a707c00  memory0          0 - 7ffffff  ONLINE         0",
145e27
 "     ffff88003a6e0000  memory1    8000000 - fffffff  ONLINE         1",
145e27
 "     ffff88003a6e1000  memory2   10000000 - 17ffffff ONLINE         2",
145e27
diff --git a/memory.c b/memory.c
145e27
index fe82fac..0a79838 100644
145e27
--- a/memory.c
145e27
+++ b/memory.c
145e27
@@ -17402,20 +17402,18 @@ fill_memory_block_name(ulong memblock, char *name)
145e27
 }
145e27
 
145e27
 static void
145e27
-fill_memory_block_srange(ulong start_sec, ulong end_sec, char *srange)
145e27
+fill_memory_block_srange(ulong start_sec, char *srange)
145e27
 {
145e27
 	memset(srange, 0, sizeof(*srange) * BUFSIZE);
145e27
 
145e27
-	if (start_sec == end_sec)
145e27
-		sprintf(srange, "%lu", start_sec);
145e27
-	else
145e27
-		sprintf(srange, "%lu-%lu", start_sec, end_sec);
145e27
+	sprintf(srange, "%lu", start_sec);
145e27
 }
145e27
 
145e27
 static void
145e27
 print_memory_block(ulong memory_block)
145e27
 {
145e27
-	ulong start_sec, end_sec, start_pfn, end_pfn, nid;
145e27
+	ulong start_sec, end_sec, nid;
145e27
+	ulong memblock_size, mbs, start_addr, end_addr;
145e27
 	char statebuf[BUFSIZE];
145e27
 	char srangebuf[BUFSIZE];
145e27
 	char name[BUFSIZE];
145e27
@@ -17430,15 +17428,25 @@ print_memory_block(ulong memory_block)
145e27
 	readmem(memory_block + OFFSET(memory_block_start_section_nr), KVADDR,
145e27
 		&start_sec, sizeof(void *), "memory_block start_section_nr",
145e27
 		FAULT_ON_ERROR);
145e27
-	readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
145e27
-		&end_sec, sizeof(void *), "memory_block end_section_nr",
145e27
-		FAULT_ON_ERROR);
145e27
 
145e27
-	start_pfn = section_nr_to_pfn(start_sec);
145e27
-	end_pfn = section_nr_to_pfn(end_sec + 1);
145e27
+	start_addr = pfn_to_phys(section_nr_to_pfn(start_sec));
145e27
+
145e27
+	if (symbol_exists("memory_block_size_probed")) {
145e27
+		memblock_size = symbol_value("memory_block_size_probed");
145e27
+		readmem(memblock_size, KVADDR,
145e27
+			&mbs, sizeof(ulong), "memory_block_size_probed",
145e27
+			FAULT_ON_ERROR);
145e27
+		end_addr = start_addr + mbs - 1;
145e27
+	} else {
145e27
+	        readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
145e27
+			&end_sec, sizeof(void *), "memory_block end_section_nr",
145e27
+			FAULT_ON_ERROR);
145e27
+		end_addr = pfn_to_phys(section_nr_to_pfn(end_sec + 1)) - 1;
145e27
+	}
145e27
+
145e27
 	fill_memory_block_state(memory_block, statebuf);
145e27
 	fill_memory_block_name(memory_block, name);
145e27
-	fill_memory_block_srange(start_sec, end_sec, srangebuf);
145e27
+	fill_memory_block_srange(start_sec, srangebuf);
145e27
 
145e27
 	if (MEMBER_EXISTS("memory_block", "nid")) {
145e27
 		readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
145e27
@@ -17448,9 +17456,9 @@ print_memory_block(ulong memory_block)
145e27
 			MKSTR(memory_block)),
145e27
 			mkstring(buf2, 12, CENTER, name),
145e27
 			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
145e27
-			MKSTR(pfn_to_phys(start_pfn))),
145e27
+			MKSTR(start_addr)),
145e27
 			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
145e27
-			MKSTR(pfn_to_phys(end_pfn) - 1)),
145e27
+			MKSTR(end_addr)),
145e27
 			mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
145e27
 			MKSTR(nid)),
145e27
 			mkstring(buf6, strlen("CANCEL_OFFLINE"), LJUST,
145e27
@@ -17462,9 +17470,9 @@ print_memory_block(ulong memory_block)
145e27
 			MKSTR(memory_block)),
145e27
 			mkstring(buf2, 10, CENTER, name),
145e27
 			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
145e27
-			MKSTR(pfn_to_phys(start_pfn))),
145e27
+			MKSTR(start_addr)),
145e27
 			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
145e27
-			MKSTR(pfn_to_phys(end_pfn) - 1)),
145e27
+			MKSTR(end_addr)),
145e27
 			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST,
145e27
 			statebuf),
145e27
 			mkstring(buf6, 12, LJUST, srangebuf));
145e27
@@ -17552,14 +17560,14 @@ dump_memory_blocks(int initialize)
145e27
 			mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, "PHYSICAL RANGE"),
145e27
 			mkstring(buf4, strlen("NODE"), CENTER, "NODE"),
145e27
 			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
145e27
-			mkstring(buf6, 12, LJUST, "SECTIONS"));
145e27
+			mkstring(buf6, 12, LJUST, "START_SECTION_NO"));
145e27
 	else
145e27
 		sprintf(mb_hdr, "\n%s %s %s     %s %s\n",
145e27
 			mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
145e27
 			mkstring(buf2, 10, CENTER, "NAME"),
145e27
 			mkstring(buf3, PADDR_PRLEN*2, CENTER, "PHYSICAL RANGE"),
145e27
 			mkstring(buf4, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
145e27
-			mkstring(buf5, 12, LJUST, "SECTIONS"));
145e27
+			mkstring(buf5, 12, LJUST, "START_SECTION_NO"));
145e27
 	fprintf(fp, "%s", mb_hdr);
145e27
 
145e27
 	for (i = 0; i < klistcnt; i++) {
145e27
145e27
commit 1f9e0ac5d0b43004639e304f718177ff4c82343b
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Sat Oct 19 16:43:16 2019 -0400
145e27
145e27
    Fix for Linux 4.19.5 and later 4.19-based x86_64 kernels which
145e27
    are NOT configured with CONFIG_RANDOMIZE_BASE and have backported
145e27
    kernel commit d52888aa2753e3063a9d3a0c9f72f94aa9809c15, titled
145e27
    "x86/mm: Move LDT remap out of KASLR region on 5-level paging",
145e27
    which modified the 4-level and 5-level paging PAGE_OFFSET values.
145e27
    Without this patch, the crash session fails during initialization
145e27
    with the error message "crash: seek error: kernel virtual address:
145e27
    <address> type: "tss_struct ist array".
145e27
    (anderson@redhat.com)
145e27
145e27
diff --git a/x86_64.c b/x86_64.c
145e27
index d57b602..c7967bd 100644
145e27
--- a/x86_64.c
145e27
+++ b/x86_64.c
145e27
@@ -382,7 +382,7 @@ x86_64_init(int when)
145e27
 
145e27
 	case POST_GDB:
145e27
 		if (!(machdep->flags & RANDOMIZED) &&
145e27
-		    ((THIS_KERNEL_VERSION >= LINUX(4,20,0)) || 
145e27
+		    ((THIS_KERNEL_VERSION >= LINUX(4,19,5)) || 
145e27
 		    ((THIS_KERNEL_VERSION >= LINUX(4,14,84)) && 
145e27
 		     (THIS_KERNEL_VERSION < LINUX(4,15,0))))) {
145e27
 			machdep->machspec->page_offset = machdep->flags & VM_5LEVEL ?
145e27
145e27
commit 1d2bc0c65792d15f94ebfd97c22da620b74634fa
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Mon Oct 21 11:46:01 2019 -0400
145e27
145e27
    Additional fix for the "kmem -n" option on Linux-5.4-rc1 and later
145e27
    kernels that contain commit b6c88d3b9d38f9448e0fcf44847a075ea81d5ca2,
145e27
    titled "drivers/base/memory.c: don't store end_section_nr in memory
145e27
    blocks".  The initial fix only addressed the x86_64 architecture;
145e27
    this incremental patch addresses the other architectures.
145e27
    (msys.mizuma@gmail.com)
145e27
145e27
diff --git a/help.c b/help.c
145e27
index cfd46c3..2b2285b 100644
145e27
--- a/help.c
145e27
+++ b/help.c
145e27
@@ -7177,15 +7177,15 @@ char *help_kmem[] = {
145e27
 "     6  ffff88003d4d90c0  ffffea0000000000  ffffea0000c00000   PM   196608",
145e27
 "     7  ffff88003d4d90e0  ffffea0000000000  ffffea0000e00000   PM   229376",
145e27
 "    ",
145e27
-"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE          START_SECTION_NO",
145e27
-"     ffff88003a707c00  memory0          0 - 7ffffff  ONLINE         0",
145e27
-"     ffff88003a6e0000  memory1    8000000 - fffffff  ONLINE         1",
145e27
-"     ffff88003a6e1000  memory2   10000000 - 17ffffff ONLINE         2",
145e27
-"     ffff88003a6e1400  memory3   18000000 - 1fffffff ONLINE         3",
145e27
-"     ffff88003a6e1800  memory4   20000000 - 27ffffff ONLINE         4",
145e27
-"     ffff88003a6e0400  memory5   28000000 - 2fffffff ONLINE         5",
145e27
-"     ffff88003a6e0800  memory6   30000000 - 37ffffff ONLINE         6",
145e27
-"     ffff88003a6e0c00  memory7   38000000 - 3fffffff ONLINE         7",
145e27
+"       MEM_BLOCK        NAME     PHYSICAL RANGE      STATE   START_SECTION_NO",
145e27
+"     ffff88003a707c00  memory0          0 -  7ffffff ONLINE  0",
145e27
+"     ffff88003a6e0000  memory1    8000000 -  fffffff ONLINE  1",
145e27
+"     ffff88003a6e1000  memory2   10000000 - 17ffffff ONLINE  2",
145e27
+"     ffff88003a6e1400  memory3   18000000 - 1fffffff ONLINE  3",
145e27
+"     ffff88003a6e1800  memory4   20000000 - 27ffffff ONLINE  4",
145e27
+"     ffff88003a6e0400  memory5   28000000 - 2fffffff ONLINE  5",
145e27
+"     ffff88003a6e0800  memory6   30000000 - 37ffffff ONLINE  6",
145e27
+"     ffff88003a6e0c00  memory7   38000000 - 3fffffff ONLINE  7",
145e27
 
145e27
 "\n  Translate a page structure's flags field contents:\n",
145e27
 "    %s> kmem -g 4080",
145e27
diff --git a/memory.c b/memory.c
145e27
index 0a79838..f36685b 100644
145e27
--- a/memory.c
145e27
+++ b/memory.c
145e27
@@ -17401,6 +17401,23 @@ fill_memory_block_name(ulong memblock, char *name)
145e27
 	read_string(value, name, BUFSIZE-1);
145e27
 }
145e27
 
145e27
+static void
145e27
+fill_memory_block_parange(ulong saddr, ulong eaddr, char *parange)
145e27
+{
145e27
+	char buf1[BUFSIZE];
145e27
+	char buf2[BUFSIZE];
145e27
+
145e27
+	memset(parange, 0, sizeof(*parange) * BUFSIZE);
145e27
+
145e27
+	if (eaddr == ULLONG_MAX)
145e27
+		sprintf(parange, "%s",
145e27
+			mkstring(buf1, PADDR_PRLEN*2 + 3, CENTER|LONG_HEX, MKSTR(saddr)));
145e27
+	else
145e27
+		sprintf(parange, "%s - %s",
145e27
+			mkstring(buf1, PADDR_PRLEN, RJUST|LONG_HEX, MKSTR(saddr)),
145e27
+			mkstring(buf2, PADDR_PRLEN, RJUST|LONG_HEX, MKSTR(eaddr)));
145e27
+}
145e27
+
145e27
 static void
145e27
 fill_memory_block_srange(ulong start_sec, char *srange)
145e27
 {
145e27
@@ -17413,14 +17430,13 @@ static void
145e27
 print_memory_block(ulong memory_block)
145e27
 {
145e27
 	ulong start_sec, end_sec, nid;
145e27
-	ulong memblock_size, mbs, start_addr, end_addr;
145e27
+	ulong memblock_size, mbs, start_addr, end_addr = ULLONG_MAX;
145e27
 	char statebuf[BUFSIZE];
145e27
 	char srangebuf[BUFSIZE];
145e27
+	char parangebuf[BUFSIZE];
145e27
 	char name[BUFSIZE];
145e27
 	char buf1[BUFSIZE];
145e27
 	char buf2[BUFSIZE];
145e27
-	char buf3[BUFSIZE];
145e27
-	char buf4[BUFSIZE];
145e27
 	char buf5[BUFSIZE];
145e27
 	char buf6[BUFSIZE];
145e27
 	char buf7[BUFSIZE];
145e27
@@ -17437,7 +17453,7 @@ print_memory_block(ulong memory_block)
145e27
 			&mbs, sizeof(ulong), "memory_block_size_probed",
145e27
 			FAULT_ON_ERROR);
145e27
 		end_addr = start_addr + mbs - 1;
145e27
-	} else {
145e27
+	} else if (MEMBER_EXISTS("memory_block", "end_section_nr")) {
145e27
 	        readmem(memory_block + OFFSET(memory_block_end_section_nr), KVADDR,
145e27
 			&end_sec, sizeof(void *), "memory_block end_section_nr",
145e27
 			FAULT_ON_ERROR);
145e27
@@ -17446,34 +17462,29 @@ print_memory_block(ulong memory_block)
145e27
 
145e27
 	fill_memory_block_state(memory_block, statebuf);
145e27
 	fill_memory_block_name(memory_block, name);
145e27
+	fill_memory_block_parange(start_addr, end_addr, parangebuf);
145e27
 	fill_memory_block_srange(start_sec, srangebuf);
145e27
 
145e27
 	if (MEMBER_EXISTS("memory_block", "nid")) {
145e27
 		readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
145e27
 			sizeof(void *), "memory_block nid", FAULT_ON_ERROR);
145e27
-		fprintf(fp, " %s %s %s - %s %s %s %s\n",
145e27
+		fprintf(fp, " %s %s %s %s  %s %s\n",
145e27
 			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
145e27
 			MKSTR(memory_block)),
145e27
 			mkstring(buf2, 12, CENTER, name),
145e27
-			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
145e27
-			MKSTR(start_addr)),
145e27
-			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
145e27
-			MKSTR(end_addr)),
145e27
+			parangebuf,
145e27
 			mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
145e27
 			MKSTR(nid)),
145e27
-			mkstring(buf6, strlen("CANCEL_OFFLINE"), LJUST,
145e27
+			mkstring(buf6, strlen("OFFLINE"), LJUST,
145e27
 			statebuf),
145e27
 			mkstring(buf7, 12, LJUST, srangebuf));
145e27
 	} else
145e27
-		fprintf(fp, " %s %s %s - %s %s %s\n",
145e27
+		fprintf(fp, " %s %s %s  %s %s\n",
145e27
 			mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
145e27
 			MKSTR(memory_block)),
145e27
 			mkstring(buf2, 10, CENTER, name),
145e27
-			mkstring(buf3, PADDR_PRLEN, RJUST|LONG_HEX,
145e27
-			MKSTR(start_addr)),
145e27
-			mkstring(buf4, PADDR_PRLEN, LJUST|LONG_HEX,
145e27
-			MKSTR(end_addr)),
145e27
-			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST,
145e27
+			parangebuf,
145e27
+			mkstring(buf5, strlen("OFFLINE"), LJUST,
145e27
 			statebuf),
145e27
 			mkstring(buf6, 12, LJUST, srangebuf));
145e27
 }
145e27
@@ -17537,6 +17548,7 @@ dump_memory_blocks(int initialize)
145e27
 	int klistcnt, i;
145e27
 	struct list_data list_data;
145e27
 	char mb_hdr[BUFSIZE];
145e27
+	char paddr_hdr[BUFSIZE];
145e27
 	char buf1[BUFSIZE];
145e27
 	char buf2[BUFSIZE];
145e27
 	char buf3[BUFSIZE];
145e27
@@ -17553,20 +17565,26 @@ dump_memory_blocks(int initialize)
145e27
 
145e27
 	init_memory_block(&list_data, &klistcnt, &klistbuf);
145e27
 
145e27
+	if ((symbol_exists("memory_block_size_probed")) ||
145e27
+	    (MEMBER_EXISTS("memory_block", "end_section_nr")))
145e27
+		sprintf(paddr_hdr, "%s", "PHYSICAL RANGE");
145e27
+	else
145e27
+		sprintf(paddr_hdr, "%s", "PHYSICAL START");
145e27
+
145e27
 	if (MEMBER_EXISTS("memory_block", "nid"))
145e27
-		sprintf(mb_hdr, "\n%s %s %s     %s %s %s\n",
145e27
+		sprintf(mb_hdr, "\n%s %s   %s   %s  %s %s\n",
145e27
 			mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
145e27
 			mkstring(buf2, 10, CENTER, "NAME"),
145e27
-			mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, "PHYSICAL RANGE"),
145e27
+			mkstring(buf3, PADDR_PRLEN*2 + 2, CENTER, paddr_hdr),
145e27
 			mkstring(buf4, strlen("NODE"), CENTER, "NODE"),
145e27
-			mkstring(buf5, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
145e27
+			mkstring(buf5, strlen("OFFLINE"), LJUST, "STATE"),
145e27
 			mkstring(buf6, 12, LJUST, "START_SECTION_NO"));
145e27
 	else
145e27
-		sprintf(mb_hdr, "\n%s %s %s     %s %s\n",
145e27
+		sprintf(mb_hdr, "\n%s %s   %s    %s %s\n",
145e27
 			mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "MEM_BLOCK"),
145e27
 			mkstring(buf2, 10, CENTER, "NAME"),
145e27
-			mkstring(buf3, PADDR_PRLEN*2, CENTER, "PHYSICAL RANGE"),
145e27
-			mkstring(buf4, strlen("CANCEL_OFFLINE"), LJUST, "STATE"),
145e27
+			mkstring(buf3, PADDR_PRLEN*2, CENTER, paddr_hdr),
145e27
+			mkstring(buf4, strlen("OFFLINE"), LJUST, "STATE"),
145e27
 			mkstring(buf5, 12, LJUST, "START_SECTION_NO"));
145e27
 	fprintf(fp, "%s", mb_hdr);
145e27
 
145e27
145e27
commit 869f3b24fc3f1dd236b58e1cff86fb4e68da76cf
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Tue Oct 22 16:42:57 2019 -0400
145e27
145e27
    In the unlikely event that the panic task in a dumpfile cannot be
145e27
    determined by the normal means, scan the kernel log buffer for panic
145e27
    keywords, and if found, generate the panic task from the CPU number
145e27
    that is specified following the panic message.
145e27
    (chenqiwu@xiaomi.com)
145e27
145e27
diff --git a/task.c b/task.c
145e27
index 829c794..8dd2b96 100644
145e27
--- a/task.c
145e27
+++ b/task.c
145e27
@@ -48,6 +48,9 @@ static void show_tgid_list(ulong);
145e27
 static int compare_start_time(const void *, const void *);
145e27
 static int start_time_timespec(void);
145e27
 static ulonglong convert_start_time(ulonglong, ulonglong);
145e27
+static ulong search_panic_task_by_cpu(char *);
145e27
+static ulong search_panic_task_by_keywords(char *, int *);
145e27
+static ulong get_log_panic_task(void);
145e27
 static ulong get_dumpfile_panic_task(void);
145e27
 static ulong get_active_set_panic_task(void);
145e27
 static void populate_panic_threads(void);
145e27
@@ -132,6 +135,23 @@ static struct sched_policy_info {
145e27
 	{ ULONG_MAX,		NULL }
145e27
 };
145e27
 
145e27
+enum PANIC_TASK_FOUND_RESULT {
145e27
+	FOUND_NO_PANIC_KEYWORD,
145e27
+	FOUND_PANIC_KEYWORD,
145e27
+	FOUND_PANIC_TASK
145e27
+};
145e27
+
145e27
+const char *panic_keywords[] = {
145e27
+	"Unable to handle kernel",
145e27
+	"BUG: unable to handle kernel",
145e27
+	"Kernel BUG at",
145e27
+	"kernel BUG at",
145e27
+	"Bad mode in",
145e27
+	"Oops",
145e27
+	"Kernel panic",
145e27
+	NULL,
145e27
+};
145e27
+
145e27
 /*
145e27
  *  Figure out how much space will be required to hold the task context
145e27
  *  data, malloc() it, and call refresh_task_table() to fill it up.
145e27
@@ -6116,8 +6136,8 @@ get_panic_ksp(struct bt_info *bt, ulong *ksp)
145e27
 
145e27
 /*
145e27
  *  Look for kcore's storage information for the system's panic state.
145e27
- *  If it's not there (somebody else's dump format?), look through all the
145e27
- *  stack traces for evidence of panic. 
145e27
+ *  If it's not there (somebody else's dump format?), look through all
145e27
+ *  the stack traces or the log buffer for evidence of panic.
145e27
  */
145e27
 static ulong
145e27
 get_panic_context(void)
145e27
@@ -6321,6 +6341,13 @@ get_panicmsg(char *buf)
145e27
 			break;
145e27
 		}
145e27
 	}
145e27
+	rewind(pc->tmpfile);
145e27
+	while (!msg_found && fgets(buf, BUFSIZE, pc->tmpfile)) {
145e27
+		if (strstr(buf, "Bad mode in ")) {
145e27
+			msg_found = TRUE;
145e27
+			break;
145e27
+		}
145e27
+	}
145e27
 
145e27
         close_tmpfile();
145e27
 
145e27
@@ -7401,6 +7428,8 @@ panic_search(void)
145e27
 
145e27
 	close_tmpfile();
145e27
 
145e27
+	pc->curcmd = pc->program_name;
145e27
+
145e27
 	if (!found && (dietask > (NO_TASK+1)) && task_has_cpu(dietask, NULL)) {
145e27
 		lasttask = dietask;
145e27
 		found = TRUE;
145e27
@@ -7410,9 +7439,16 @@ panic_search(void)
145e27
 		error(WARNING, "multiple active tasks have called die\n\n");
145e27
 
145e27
 	if (CRASHDEBUG(1) && found)
145e27
-		error(INFO, "panic_search: %lx (via foreach bt)\n", 
145e27
+		error(INFO, "panic_search: %lx (via foreach bt)\n",
145e27
 			lasttask);
145e27
 
145e27
+	if (!found) {
145e27
+		if (CRASHDEBUG(1))
145e27
+			error(INFO, "panic_search: failed (via foreach bt)\n");
145e27
+		if ((lasttask = get_log_panic_task()))
145e27
+			found = TRUE;
145e27
+	}
145e27
+
145e27
 found_panic_task:
145e27
 	populate_panic_threads();
145e27
 
145e27
@@ -7430,11 +7466,114 @@ found_panic_task:
145e27
 	} 
145e27
 
145e27
 	if (CRASHDEBUG(1))
145e27
-		error(INFO, "panic_search: failed (via foreach bt)\n");
145e27
+		error(INFO, "panic_search: failed\n");
145e27
 
145e27
 	return NULL;
145e27
 }
145e27
 
145e27
+static ulong
145e27
+search_panic_task_by_cpu(char *buf)
145e27
+{
145e27
+	int crashing_cpu;
145e27
+	char *p1, *p2;
145e27
+	ulong task = NO_TASK;
145e27
+
145e27
+	p1 = NULL;
145e27
+
145e27
+	if ((p1 = strstr(buf, "CPU: ")))
145e27
+		p1 += strlen("CPU: ");
145e27
+	else if (STRNEQ(buf, "CPU "))
145e27
+		p1 = buf + strlen("CPU ");
145e27
+
145e27
+	if (p1) {
145e27
+		p2 = p1;
145e27
+		while (!whitespace(*p2) && (*p2 != '\n'))
145e27
+			p2++;
145e27
+		*p2 = NULLCHAR;
145e27
+		crashing_cpu = dtol(p1, RETURN_ON_ERROR, NULL);
145e27
+		if ((crashing_cpu >= 0) && in_cpu_map(ONLINE_MAP, crashing_cpu)) {
145e27
+			task = tt->active_set[crashing_cpu];
145e27
+			if (CRASHDEBUG(1))
145e27
+				error(WARNING,
145e27
+					"get_log_panic_task: active_set[%d]: %lx\n",
145e27
+					crashing_cpu, tt->active_set[crashing_cpu]);
145e27
+		}
145e27
+	}
145e27
+	return task;
145e27
+}
145e27
+
145e27
+static ulong
145e27
+search_panic_task_by_keywords(char *buf, int *found_flag)
145e27
+{
145e27
+	char *p;
145e27
+	int i = 0;
145e27
+	ulong task;
145e27
+
145e27
+	while (panic_keywords[i]) {
145e27
+		if ((p = strstr(buf, panic_keywords[i]))) {
145e27
+			if ((task = search_panic_task_by_cpu(p))) {
145e27
+				*found_flag = FOUND_PANIC_TASK;
145e27
+				return task;
145e27
+			} else {
145e27
+				*found_flag = FOUND_PANIC_KEYWORD;
145e27
+				return NO_TASK;
145e27
+			}
145e27
+		}
145e27
+		i++;
145e27
+	}
145e27
+	*found_flag = FOUND_NO_PANIC_KEYWORD;
145e27
+	return NO_TASK;
145e27
+}
145e27
+
145e27
+/*
145e27
+ *   Search for the panic task by seeking panic keywords from kernel log buffer.
145e27
+ *   The panic keyword is generally followed by printing out the stack trace info
145e27
+ *   of the panicking task.  We can determine the panic task by finding the first
145e27
+ *   instance of "CPU: " or "CPU " following the panic keywords.
145e27
+ */
145e27
+static ulong
145e27
+get_log_panic_task(void)
145e27
+{
145e27
+	int found_flag = FOUND_NO_PANIC_KEYWORD;
145e27
+	int found_panic_keyword = FALSE;
145e27
+	ulong task = NO_TASK;
145e27
+	char buf[BUFSIZE];
145e27
+
145e27
+	if (!get_active_set())
145e27
+		goto fail;
145e27
+
145e27
+	BZERO(buf, BUFSIZE);
145e27
+	open_tmpfile();
145e27
+	dump_log(SHOW_LOG_TEXT);
145e27
+	rewind(pc->tmpfile);
145e27
+	while (fgets(buf, BUFSIZE, pc->tmpfile)) {
145e27
+		if (!found_panic_keyword) {
145e27
+			task = search_panic_task_by_keywords(buf, &found_flag);
145e27
+			switch (found_flag) {
145e27
+				case FOUND_PANIC_TASK:
145e27
+					goto found_panic_task;
145e27
+				case FOUND_PANIC_KEYWORD:
145e27
+					found_panic_keyword = TRUE;
145e27
+					continue;
145e27
+				default:
145e27
+					continue;
145e27
+			}
145e27
+		} else {
145e27
+			task = search_panic_task_by_cpu(buf);
145e27
+			if (task)
145e27
+				goto found_panic_task;
145e27
+		}
145e27
+	}
145e27
+
145e27
+found_panic_task:
145e27
+	close_tmpfile();
145e27
+fail:
145e27
+	if (CRASHDEBUG(1) && !task)
145e27
+		 error(WARNING, "cannot determine the panic task from kernel log buffer\n");
145e27
+
145e27
+	return task;
145e27
+}
145e27
+
145e27
 /*
145e27
  *   Get the panic task from the appropriate dumpfile handler.
145e27
  */
145e27
145e27
commit 6a466f8afbb0dcdf4ddc5ef37aec6d343c2636c6
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Mon Nov 4 11:56:28 2019 -0500
145e27
145e27
    Adjust a crash-7.1.8 patch for support of /proc/kcore as the live
145e27
    memory source in Linux 4.8 and later x86_64 kernels configured with
145e27
    CONFIG_RANDOMIZE_BASE, which randomizes the unity-mapping PAGE_OFFSET
145e27
    value.  Since the problem only arises before the determination of the
145e27
    randomized PAGE_OFFSET value, restrict the patch such that it only
145e27
    takes effect during session initialization.
145e27
    (anderson@redhat.com)
145e27
145e27
diff --git a/netdump.c b/netdump.c
145e27
index 55b64e6..fdaecf3 100644
145e27
--- a/netdump.c
145e27
+++ b/netdump.c
145e27
@@ -4269,7 +4269,8 @@ read_proc_kcore(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
145e27
 		 *  If KASLR, the PAGE_OFFSET may be unknown early on, so try
145e27
 		 *  the (hopefully) mapped kernel address first.
145e27
 		 */
145e27
-		if ((pc->curcmd_flags & MEMTYPE_KVADDR) && (kvaddr != addr)) {
145e27
+		if (!(pc->flags & RUNTIME) &&
145e27
+		    (pc->curcmd_flags & MEMTYPE_KVADDR) && (kvaddr != addr)) {
145e27
 			pc->curcmd_flags &= ~MEMTYPE_KVADDR;
145e27
 			for (i = 0; i < pkd->segments; i++) {
145e27
 				lp64 = pkd->load64 + i;
145e27
145e27
commit c0bbd8fae4271159aee9e643350781909484c92f
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Fri Nov 8 14:00:56 2019 -0500
145e27
145e27
    Add support for extended numbering support in ELF dumpfiles to handle
145e27
    more than PN_XNUM (0xffff) program headers.  If the real number of
145e27
    program header table entries is equal to or greater than PN_XNUM, the
145e27
    e_phnum field of the ELF header is set to PN_XNUM, and the actual
145e27
    number is set in the sh_info field of the section header at index 0.
145e27
    (k-hagio@ab.jp.nec.com)
145e27
145e27
diff --git a/netdump.c b/netdump.c
145e27
index fdaecf3..3ced87c 100644
145e27
--- a/netdump.c
145e27
+++ b/netdump.c
145e27
@@ -28,12 +28,13 @@ static struct vmcore_data *nd = &vmcore_data;
145e27
 static struct proc_kcore_data proc_kcore_data = { 0 };
145e27
 static struct proc_kcore_data *pkd = &proc_kcore_data;
145e27
 static void netdump_print(char *, ...);
145e27
-static size_t resize_elf_header(int, char *, char **, ulong);
145e27
+static size_t resize_elf_header(int, char *, char **, char **, ulong);
145e27
 static void dump_Elf32_Ehdr(Elf32_Ehdr *);
145e27
 static void dump_Elf32_Phdr(Elf32_Phdr *, int);
145e27
 static size_t dump_Elf32_Nhdr(Elf32_Off offset, int);
145e27
 static void dump_Elf64_Ehdr(Elf64_Ehdr *);
145e27
 static void dump_Elf64_Phdr(Elf64_Phdr *, int);
145e27
+static void dump_Elf64_Shdr(Elf64_Shdr *shdr);
145e27
 static size_t dump_Elf64_Nhdr(Elf64_Off offset, int);
145e27
 static void get_netdump_regs_32(struct bt_info *, ulong *, ulong *);
145e27
 static void get_netdump_regs_ppc(struct bt_info *, ulong *, ulong *);
145e27
@@ -116,7 +117,7 @@ is_netdump(char *file, ulong source_query)
145e27
 	Elf32_Phdr *load32;
145e27
 	Elf64_Ehdr *elf64;
145e27
 	Elf64_Phdr *load64;
145e27
-	char *eheader;
145e27
+	char *eheader, *sect0;
145e27
 	char buf[BUFSIZE];
145e27
 	size_t size, len, tot;
145e27
         Elf32_Off offset32;
145e27
@@ -330,7 +331,8 @@ is_netdump(char *file, ulong source_query)
145e27
 			goto bailout;
145e27
 	}
145e27
 
145e27
-	if (!(size = resize_elf_header(fd, file, &eheader, format)))
145e27
+	sect0 = NULL;
145e27
+	if (!(size = resize_elf_header(fd, file, &eheader, &sect0, format)))
145e27
 		goto bailout;
145e27
 
145e27
 	nd->ndfd = fd;
145e27
@@ -372,7 +374,17 @@ is_netdump(char *file, ulong source_query)
145e27
 	case KDUMP_ELF64:
145e27
                 nd->header_size = size;
145e27
                 nd->elf64 = (Elf64_Ehdr *)&nd->elf_header[0];
145e27
-		nd->num_pt_load_segments = nd->elf64->e_phnum - 1;
145e27
+
145e27
+		/*
145e27
+		 * Extended Numbering support
145e27
+		 * See include/uapi/linux/elf.h and elf(5) for more information
145e27
+		 */
145e27
+		if (nd->elf64->e_phnum == PN_XNUM) {
145e27
+			nd->sect0_64 = (Elf64_Shdr *)sect0;
145e27
+			nd->num_pt_load_segments = nd->sect0_64->sh_info - 1;
145e27
+		} else
145e27
+			nd->num_pt_load_segments = nd->elf64->e_phnum - 1;
145e27
+
145e27
                 if ((nd->pt_load_segments = (struct pt_load_segment *)
145e27
                     malloc(sizeof(struct pt_load_segment) *
145e27
                     nd->num_pt_load_segments)) == NULL) {
145e27
@@ -432,7 +444,8 @@ bailout:
145e27
  */
145e27
 
145e27
 static size_t
145e27
-resize_elf_header(int fd, char *file, char **eheader_ptr, ulong format)
145e27
+resize_elf_header(int fd, char *file, char **eheader_ptr, char **sect0_ptr,
145e27
+		ulong format)
145e27
 {
145e27
 	int i;
145e27
 	char buf[BUFSIZE];
145e27
@@ -462,7 +475,44 @@ resize_elf_header(int fd, char *file, char **eheader_ptr, ulong format)
145e27
 
145e27
 	case NETDUMP_ELF64:
145e27
 	case KDUMP_ELF64:
145e27
-		num_pt_load_segments = elf64->e_phnum - 1;
145e27
+		/*
145e27
+		 * Extended Numbering support
145e27
+		 * See include/uapi/linux/elf.h and elf(5) for more information
145e27
+		 */
145e27
+		if (elf64->e_phnum == PN_XNUM) {
145e27
+			Elf64_Shdr *shdr64;
145e27
+
145e27
+			shdr64 = (Elf64_Shdr *)malloc(sizeof(*shdr64));
145e27
+			if (!shdr64) {
145e27
+				fprintf(stderr,
145e27
+				    "cannot malloc a section header buffer\n");
145e27
+				return 0;
145e27
+			}
145e27
+			if (FLAT_FORMAT()) {
145e27
+				if (!read_flattened_format(fd, elf64->e_shoff,
145e27
+				    shdr64, elf64->e_shentsize))
145e27
+					return 0;
145e27
+			} else {
145e27
+				if (lseek(fd, elf64->e_shoff, SEEK_SET) !=
145e27
+				    elf64->e_shoff) {
145e27
+					sprintf(buf, "%s: section header lseek",
145e27
+						file);
145e27
+					perror(buf);
145e27
+					return 0;
145e27
+				}
145e27
+				if (read(fd, shdr64, elf64->e_shentsize) !=
145e27
+				    elf64->e_shentsize) {
145e27
+					sprintf(buf, "%s: section header read",
145e27
+						file);
145e27
+					perror(buf);
145e27
+					return 0;
145e27
+				}
145e27
+			}
145e27
+			num_pt_load_segments = shdr64->sh_info - 1;
145e27
+			*sect0_ptr = (char *)shdr64;
145e27
+		} else
145e27
+			num_pt_load_segments = elf64->e_phnum - 1;
145e27
+
145e27
 		header_size = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) +
145e27
 			(sizeof(Elf64_Phdr) * num_pt_load_segments);
145e27
 		break;
145e27
@@ -1168,6 +1218,7 @@ netdump_memory_dump(FILE *fp)
145e27
 	netdump_print("                  elf64: %lx\n", nd->elf64);
145e27
 	netdump_print("                notes64: %lx\n", nd->notes64);
145e27
 	netdump_print("                 load64: %lx\n", nd->load64);
145e27
+	netdump_print("               sect0_64: %lx\n", nd->sect0_64);
145e27
 	netdump_print("            nt_prstatus: %lx\n", nd->nt_prstatus);
145e27
 	netdump_print("            nt_prpsinfo: %lx\n", nd->nt_prpsinfo);
145e27
 	netdump_print("          nt_taskstruct: %lx\n", nd->nt_taskstruct);
145e27
@@ -1252,6 +1303,8 @@ netdump_memory_dump(FILE *fp)
145e27
 		dump_Elf64_Phdr(nd->notes64, ELFREAD);
145e27
                 for (i = 0; i < nd->num_pt_load_segments; i++)
145e27
 			dump_Elf64_Phdr(nd->load64 + i, ELFREAD);
145e27
+		if (nd->sect0_64)
145e27
+			dump_Elf64_Shdr(nd->sect0_64);
145e27
         	offset64 = nd->notes64->p_offset;
145e27
         	for (tot = 0; tot < nd->notes64->p_filesz; tot += len) {
145e27
                 	if (!(len = dump_Elf64_Nhdr(offset64, ELFREAD)))
145e27
@@ -1763,6 +1816,32 @@ dump_Elf64_Phdr(Elf64_Phdr *prog, int store_pt_load_data)
145e27
 	netdump_print("                p_align: %lld\n", prog->p_align);
145e27
 }
145e27
 
145e27
+static void
145e27
+dump_Elf64_Shdr(Elf64_Shdr *shdr)
145e27
+{
145e27
+	netdump_print("Elf64_Shdr:\n");
145e27
+	netdump_print("                sh_name: %x\n", shdr->sh_name);
145e27
+	netdump_print("                sh_type: %x ", shdr->sh_type);
145e27
+	switch (shdr->sh_type)
145e27
+	{
145e27
+	case SHT_NULL:
145e27
+		netdump_print("(SHT_NULL)\n");
145e27
+		break;
145e27
+	default:
145e27
+		netdump_print("\n");
145e27
+		break;
145e27
+	}
145e27
+	netdump_print("               sh_flags: %lx\n", shdr->sh_flags);
145e27
+	netdump_print("                sh_addr: %lx\n", shdr->sh_addr);
145e27
+	netdump_print("              sh_offset: %lx\n", shdr->sh_offset);
145e27
+	netdump_print("                sh_size: %lx\n", shdr->sh_size);
145e27
+	netdump_print("                sh_link: %x\n", shdr->sh_link);
145e27
+	netdump_print("                sh_info: %x (%u)\n", shdr->sh_info,
145e27
+		shdr->sh_info);
145e27
+	netdump_print("           sh_addralign: %lx\n", shdr->sh_addralign);
145e27
+	netdump_print("             sh_entsize: %lx\n", shdr->sh_entsize);
145e27
+}
145e27
+
145e27
 /*
145e27
  * VMCOREINFO
145e27
  *
145e27
diff --git a/netdump.h b/netdump.h
145e27
index ad1fc77..7fa04f7 100644
145e27
--- a/netdump.h
145e27
+++ b/netdump.h
145e27
@@ -61,6 +61,7 @@ struct vmcore_data {
145e27
         Elf64_Ehdr *elf64;
145e27
         Elf64_Phdr *notes64;
145e27
         Elf64_Phdr *load64;
145e27
+        Elf64_Shdr *sect0_64;
145e27
         void *nt_prstatus;
145e27
         void *nt_prpsinfo;
145e27
         void *nt_taskstruct;
145e27
145e27
commit b5c2359f9f7347a2efa4896fa134dbf128601ca8
145e27
Author: Dave Anderson <anderson@redhat.com>
145e27
Date:   Fri Nov 8 14:32:53 2019 -0500
145e27
145e27
    Fix for a "warning: large integer implicitly truncated to unsigned
145e27
    type [-Woverflow]" compiler message generated on 32-bit architectures
145e27
    as a result of the "Additional fix for the kmem -n option" patch
145e27
    above.
145e27
    (anderson@redhat.com)
145e27
145e27
diff --git a/memory.c b/memory.c
145e27
index f36685b..4f7b6a0 100644
145e27
--- a/memory.c
145e27
+++ b/memory.c
145e27
@@ -17430,7 +17430,7 @@ static void
145e27
 print_memory_block(ulong memory_block)
145e27
 {
145e27
 	ulong start_sec, end_sec, nid;
145e27
-	ulong memblock_size, mbs, start_addr, end_addr = ULLONG_MAX;
145e27
+	ulong memblock_size, mbs, start_addr, end_addr = (ulong)ULLONG_MAX;
145e27
 	char statebuf[BUFSIZE];
145e27
 	char srangebuf[BUFSIZE];
145e27
 	char parangebuf[BUFSIZE];