Blame SOURCES/github_105a3e13_to_b5c2359f.patch

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