1486 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			1486 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| commit 5cbb2fd8c20c46793095522059b1efc8232df926
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Wed Nov 13 11:29:14 2019 -0500
 | |
| 
 | |
|     Add support for handling openSUSE vmlinux files which will be shipped
 | |
|     in .xz compressed format.  Without the patch, only gzip and bzip2
 | |
|     formats are supported.
 | |
|     (jirislaby@gmail.com)
 | |
| 
 | |
| diff --git a/symbols.c b/symbols.c
 | |
| index 55199fc..7e1bca7 100644
 | |
| --- a/symbols.c
 | |
| +++ b/symbols.c
 | |
| @@ -3655,6 +3655,7 @@ is_compressed_kernel(char *file, char **tmp)
 | |
|  
 | |
|  #define GZIP  (1)
 | |
|  #define BZIP2 (2)
 | |
| +#define XZ    (3)
 | |
|  
 | |
|  #define FNAME (1 << 3)
 | |
|  
 | |
| @@ -3704,6 +3705,19 @@ is_compressed_kernel(char *file, char **tmp)
 | |
|  		type = BZIP2;
 | |
|  	}
 | |
|  
 | |
| +	if (!memcmp(header, "\xfd""7zXZ", 6)) {
 | |
| +		if (!STRNEQ(basename(file), "vmlinux") &&
 | |
| +		    !(st->flags & FORCE_DEBUGINFO)) {
 | |
| +			error(INFO, "%s: compressed file name does not start "
 | |
| +			    "with \"vmlinux\"\n", file);
 | |
| +			error(CONT, 
 | |
| +			    "Use \"-f %s\" on command line to override.\n\n",
 | |
| +				file);
 | |
| +			return FALSE;
 | |
| +		}
 | |
| +		type = XZ;
 | |
| +	}
 | |
| +
 | |
|  	if (!type)
 | |
|  		return FALSE;
 | |
|  
 | |
| @@ -3739,6 +3753,12 @@ is_compressed_kernel(char *file, char **tmp)
 | |
|  			"/bin/bunzip2" : "/usr/bin/bunzip2",
 | |
|  			file, tempname);
 | |
|  		break;
 | |
| +	case XZ:
 | |
| +		sprintf(command, "%s -c %s > %s", 
 | |
| +			file_exists("/bin/unxz", NULL) ?
 | |
| +			"/bin/unxz" : "/usr/bin/unxz",
 | |
| +			file, tempname);
 | |
| +		break;
 | |
|  	}
 | |
|  	if (system(command) < 0) {
 | |
|  		please_wait_done();
 | |
| 
 | |
| commit babd7ae62d4e8fd6f93fd30b88040d9376522aa3
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Fri Nov 15 09:55:34 2019 -0500
 | |
| 
 | |
|     Fix for the determination of the ARM64 page size on Linux 4.4 and
 | |
|     earlier kernels that do not have vmcoreinfo data.  Without the patch,
 | |
|     the crash session fails during initialization with the error message
 | |
|     "crash: "cannot determine page size".
 | |
|     (chenqiwu@xiaomi.com)
 | |
| 
 | |
| diff --git a/arm64.c b/arm64.c
 | |
| index 5ee5f1a..af7147d 100644
 | |
| --- a/arm64.c
 | |
| +++ b/arm64.c
 | |
| @@ -179,17 +179,16 @@ arm64_init(int when)
 | |
|  
 | |
|  		}
 | |
|  
 | |
| +		/*
 | |
| +		 * This code section will only be executed if the kernel is
 | |
| +		 * earlier than Linux 4.4 (if there is no vmcoreinfo)
 | |
| +		 */
 | |
|  		if (!machdep->pagesize &&
 | |
|  		    kernel_symbol_exists("swapper_pg_dir") &&
 | |
|  		    kernel_symbol_exists("idmap_pg_dir")) {
 | |
| -			if (kernel_symbol_exists("tramp_pg_dir"))
 | |
| -				value = symbol_value("tramp_pg_dir");
 | |
| -			else if (kernel_symbol_exists("reserved_ttbr0"))
 | |
| -				value = symbol_value("reserved_ttbr0");
 | |
| -			else
 | |
| -				value = symbol_value("swapper_pg_dir");
 | |
| +			value = symbol_value("swapper_pg_dir") -
 | |
| +				symbol_value("idmap_pg_dir");
 | |
|  
 | |
| -			value -= symbol_value("idmap_pg_dir");
 | |
|  			/*
 | |
|  			 * idmap_pg_dir is 2 pages prior to 4.1,
 | |
|  			 * and 3 pages thereafter.  Only 4K and 64K 
 | |
| 
 | |
| commit bfd9a651f9426d86250295ac875d7e33d8de2a97
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Tue Nov 19 10:19:55 2019 -0500
 | |
| 
 | |
|     Determine the ARM64 kernel's "vabits_actual" value by reading the
 | |
|     new TCR_EL1.T1SZ vmcoreinfo entry.
 | |
|     (bhsharma@redhat.com)
 | |
| 
 | |
| diff --git a/arm64.c b/arm64.c
 | |
| index af7147d..0834913 100644
 | |
| --- a/arm64.c
 | |
| +++ b/arm64.c
 | |
| @@ -3856,8 +3856,17 @@ arm64_calc_VA_BITS(void)
 | |
|  		} else if (ACTIVE())
 | |
|  			error(FATAL, "cannot determine VA_BITS_ACTUAL: please use /proc/kcore\n");
 | |
|  		else {
 | |
| -			if ((string = pc->read_vmcoreinfo("NUMBER(VA_BITS_ACTUAL)"))) {
 | |
| -				value = atol(string);
 | |
| +			if ((string = pc->read_vmcoreinfo("NUMBER(tcr_el1_t1sz)"))) {
 | |
| +				/* See ARMv8 ARM for the description of
 | |
| +				 * TCR_EL1.T1SZ and how it can be used
 | |
| +				 * to calculate the vabits_actual
 | |
| +				 * supported by underlying kernel.
 | |
| +				 *
 | |
| +				 * Basically:
 | |
| +				 * vabits_actual = 64 - T1SZ;
 | |
| +				 */
 | |
| +				value = 64 - strtoll(string, NULL, 0);
 | |
| +				fprintf(fp,  "vmcoreinfo : vabits_actual: %ld\n", value);
 | |
|  				free(string);
 | |
|  				machdep->machspec->VA_BITS_ACTUAL = value;
 | |
|  				machdep->machspec->VA_BITS = value;
 | |
| 
 | |
| commit f1c71de4ef66508108c5929e79e21a85b147787b
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Wed Nov 20 11:59:00 2019 -0500
 | |
| 
 | |
|     Fix to determine the ARM64 kernel's "vabits_actual" value from the
 | |
|     ELF header of a dumpfile created with the "snap.so" extension module.
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/netdump.c b/netdump.c
 | |
| index 3ced87c..406416a 100644
 | |
| --- a/netdump.c
 | |
| +++ b/netdump.c
 | |
| @@ -1887,7 +1887,7 @@ vmcoreinfo_read_string(const char *key)
 | |
|  			sprintf(value, "%ld", nd->arch_data2 & 0xffffffff);
 | |
|  			return value;
 | |
|  		}
 | |
| -		if (STREQ(key, "NUMBER(VA_BITS_ACTUAL)") && nd->arch_data2) {
 | |
| +		if (STREQ(key, "NUMBER(tcr_el1_t1sz)") && nd->arch_data2) {
 | |
|  			value = calloc(VADDR_PRLEN+1, sizeof(char));
 | |
|  			sprintf(value, "%lld", ((ulonglong)nd->arch_data2 >> 32) & 0xffffffff);
 | |
|  			pc->read_vmcoreinfo = no_vmcoreinfo;
 | |
| 
 | |
| commit b259940b228cc7025904f9b7372348b56f73a4d2
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Thu Nov 21 09:27:52 2019 -0500
 | |
| 
 | |
|     Fix two typos in the examples section of the "help bt" display, which
 | |
|     mistakenly show "bf -f" and "bf -FF" instead of "bt -f" and "bt -FF".
 | |
|     (austindh.kim@gmail.com)
 | |
| 
 | |
| diff --git a/help.c b/help.c
 | |
| index 2b2285b..eed249b 100644
 | |
| --- a/help.c
 | |
| +++ b/help.c
 | |
| @@ -2117,7 +2117,7 @@ char *help_bt[] = {
 | |
|  "  The following three examples show the difference in the display of",
 | |
|  "  the same stack frame's contents using -f, -F, and -FF:",
 | |
|  "  ",
 | |
| -"    %s> bf -f",
 | |
| +"    %s> bt -f",
 | |
|  "    ...",
 | |
|  "     #4 [ffff810072b47f10] vfs_write at ffffffff800789d8",
 | |
|  "        ffff810072b47f18: ffff81007e020380 ffff81007e2c2880 ",
 | |
| @@ -2133,7 +2133,7 @@ char *help_bt[] = {
 | |
|  "        ffff810072b47f38: 00002b141825d000 sys_write+69   ",
 | |
|  "     #5 [ffff810072b47f40] sys_write at ffffffff80078f75",
 | |
|  "    ...",
 | |
| -"    %s> bf -FF",
 | |
| +"    %s> bt -FF",
 | |
|  "    ...",
 | |
|  "     #4 [ffff810072b47f10] vfs_write at ffffffff800789d8",
 | |
|  "        ffff810072b47f18: [ffff81007e020380:files_cache] [ffff81007e2c2880:filp]",
 | |
| 
 | |
| commit 5171ef5a7e85805f61ef98b15801da06648a8e39
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Fri Nov 22 13:39:40 2019 -0500
 | |
| 
 | |
|     Similar to ARM64, the X86_64, PPC64 and S390x architectures will use
 | |
|     the exported value of MAX_PHYSMEM_BITS from the vmcoreinfo data as
 | |
|     the preferred method if it is available.
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/ppc64.c b/ppc64.c
 | |
| index 0936551..f368bf8 100644
 | |
| --- a/ppc64.c
 | |
| +++ b/ppc64.c
 | |
| @@ -225,6 +225,13 @@ static int ppc64_is_vmaddr(ulong addr)
 | |
|  static int set_ppc64_max_physmem_bits(void)
 | |
|  {
 | |
|  	int dimension;
 | |
| +	char *string;
 | |
| +
 | |
| +	if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
 | |
| +		machdep->max_physmem_bits = atol(string);
 | |
| +		free(string);
 | |
| +		return 0;
 | |
| +	}
 | |
|  
 | |
|  	get_array_length("mem_section", &dimension, 0);
 | |
|  
 | |
| diff --git a/s390x.c b/s390x.c
 | |
| index 0055890..4a1a466 100644
 | |
| --- a/s390x.c
 | |
| +++ b/s390x.c
 | |
| @@ -240,6 +240,13 @@ static int
 | |
|  set_s390x_max_physmem_bits(void)
 | |
|  {
 | |
|  	int array_len, dimension;
 | |
| +	char *string;
 | |
| +
 | |
| +	if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
 | |
| +		machdep->max_physmem_bits = atol(string);
 | |
| +		free(string);
 | |
| +		return TRUE;
 | |
| +	}
 | |
|  
 | |
|  	machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_OLD;
 | |
|  
 | |
| diff --git a/x86_64.c b/x86_64.c
 | |
| index c7967bd..a4138ed 100644
 | |
| --- a/x86_64.c
 | |
| +++ b/x86_64.c
 | |
| @@ -665,7 +665,10 @@ x86_64_init(int when)
 | |
|  		}
 | |
|  		machdep->section_size_bits = _SECTION_SIZE_BITS;
 | |
|  		if (!machdep->max_physmem_bits) {
 | |
| -			if (machdep->flags & VM_5LEVEL)
 | |
| +			if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
 | |
| +				machdep->max_physmem_bits = atol(string);
 | |
| +				free(string);
 | |
| +			} else if (machdep->flags & VM_5LEVEL)
 | |
|  				machdep->max_physmem_bits = 
 | |
|  					_MAX_PHYSMEM_BITS_5LEVEL;
 | |
|  			else if (THIS_KERNEL_VERSION >= LINUX(2,6,31))
 | |
| 
 | |
| commit 6664cb3f4ea2eac1b6d482e541b56d7792a4be04
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Tue Nov 26 12:18:02 2019 -0500
 | |
| 
 | |
|     If an S390X kernel crashes before vmcoreinfo initialization, there is
 | |
|     no way to extract the KASLR offset for such early dumps.  In a new
 | |
|     S390X kernel patch, the KASLR offset will be stored in the lowcore
 | |
|     memory during early boot and then overwritten after vmcoreinfo is
 | |
|     initialized.  This patch allows crash to identify the KASLR offset
 | |
|     that is stored in the lowcore memory.
 | |
|     (zaslonko@linux.ibm.com)
 | |
| 
 | |
| diff --git a/s390x.c b/s390x.c
 | |
| index 4a1a466..8840cc7 100644
 | |
| --- a/s390x.c
 | |
| +++ b/s390x.c
 | |
| @@ -46,6 +46,8 @@
 | |
|  
 | |
|  #define S390X_PSW_MASK_PSTATE	0x0001000000000000UL
 | |
|  
 | |
| +#define S390X_LC_VMCORE_INFO	0xe0c
 | |
| +
 | |
|  /*
 | |
|   * Flags for Region and Segment table entries.
 | |
|   */
 | |
| @@ -460,6 +462,8 @@ static void s390x_check_live(void)
 | |
|  void
 | |
|  s390x_init(int when)
 | |
|  {
 | |
| +	ulong s390x_lc_kaslr;
 | |
| +
 | |
|  	switch (when)
 | |
|  	{
 | |
|  	case SETUP_ENV:
 | |
| @@ -486,6 +490,24 @@ s390x_init(int when)
 | |
|  		machdep->verify_paddr = generic_verify_paddr;
 | |
|  		machdep->get_kvaddr_ranges = s390x_get_kvaddr_ranges;
 | |
|  		machdep->ptrs_per_pgd = PTRS_PER_PGD;
 | |
| +		if (DUMPFILE() && !(kt->flags & RELOC_SET)) {
 | |
| +			/* Read the value from well-known lowcore location*/
 | |
| +			if (readmem(S390X_LC_VMCORE_INFO, PHYSADDR, &s390x_lc_kaslr,
 | |
| +			    sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
 | |
| +			    QUIET|RETURN_ON_ERROR)) {
 | |
| +				/* Check for explicit kaslr offset flag */
 | |
| +				if (s390x_lc_kaslr & 0x1UL) {
 | |
| +					/* Drop the last bit to get an offset value */
 | |
| +					s390x_lc_kaslr &= ~(0x1UL);
 | |
| +					/* Make sure the offset is aligned by 0x1000 */
 | |
| +					if (s390x_lc_kaslr && !(s390x_lc_kaslr & 0xfff)) {
 | |
| +						kt->relocate = s390x_lc_kaslr * (-1);
 | |
| +						kt->flags |= RELOC_SET;
 | |
| +						kt->flags2 |= KASLR;
 | |
| +					}
 | |
| +				}
 | |
| +			}
 | |
| +		}
 | |
|  		break;
 | |
|  
 | |
|  	case PRE_GDB:
 | |
| 
 | |
| commit b265bad21cdb394b230431360605551b02fc5053
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Sun Dec 1 14:06:59 2019 -0500
 | |
| 
 | |
|     Fix for a crash-7.2.7 regression that determined the value of the
 | |
|     ARM64 kernel SECTION_SIZE_BITS by reading the in-kernel configuration
 | |
|     data if there is no VMCOREINFO data available.  In that case, without
 | |
|     the patch, a double-free exception may occur.
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/arm64.c b/arm64.c
 | |
| index 0834913..233029d 100644
 | |
| --- a/arm64.c
 | |
| +++ b/arm64.c
 | |
| @@ -1073,10 +1073,8 @@ arm64_get_section_size_bits(void)
 | |
|  		free(string);
 | |
|  	} else if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
 | |
|  		if ((ret = get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL)) == IKCONFIG_Y) {
 | |
| -			if ((ret = get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string)) == IKCONFIG_STR) {
 | |
| +			if ((ret = get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string)) == IKCONFIG_STR)
 | |
|  				machdep->section_size_bits = atol(string);
 | |
| -				free(string);
 | |
| -			}
 | |
|  		} 
 | |
|  	}
 | |
|  
 | |
| 
 | |
| commit e13b51a59645fd8c3884082b157a0b494cf77ec6
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Sun Dec 1 14:18:41 2019 -0500
 | |
| 
 | |
|     Fix for segmentation violation if the gdb_readmem_callback() function
 | |
|     gets called from other than a crash command, such as from an epython
 | |
|     command from the mypkdump.so extension module.
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/gdb_interface.c b/gdb_interface.c
 | |
| index 608da86..562d2ac 100644
 | |
| --- a/gdb_interface.c
 | |
| +++ b/gdb_interface.c
 | |
| @@ -1,8 +1,8 @@
 | |
|  /* gdb_interface.c - core analysis suite
 | |
|   *
 | |
|   * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
 | |
| - * Copyright (C) 2002-2015,2018 David Anderson
 | |
| - * Copyright (C) 2002-2015,2018 Red Hat, Inc. All rights reserved.
 | |
| + * Copyright (C) 2002-2015,2018-2019 David Anderson
 | |
| + * Copyright (C) 2002-2015,2018-2019 Red Hat, Inc. All rights reserved.
 | |
|   *
 | |
|   * This program is free software; you can redistribute it and/or modify
 | |
|   * it under the terms of the GNU General Public License as published by
 | |
| @@ -831,6 +831,11 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
 | |
|  	if (write)
 | |
|  		return FALSE;
 | |
|  
 | |
| +	if (!(pc->cur_req)) {
 | |
| +		return(readmem(addr, KVADDR, buf, len, 
 | |
| +			"gdb_readmem_callback", RETURN_ON_ERROR));
 | |
| +	}
 | |
| +
 | |
|  	if (pc->cur_req->flags & GNU_NO_READMEM)
 | |
|  		return TRUE;
 | |
|  
 | |
| 
 | |
| commit da4a22029aa55fa55200d52f98866fce48ba720e
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Tue Dec 3 11:41:19 2019 -0500
 | |
| 
 | |
|     Fix for the "dis -s" option when running against kernels that have
 | |
|     been configured with CONFIG_RANDOMIZE_BASE=y (KASLR).  Without the
 | |
|     patch, the command option indicates that the FILE and LINE numbers
 | |
|     are "(unknown)", and that "source code is not available".
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/kernel.c b/kernel.c
 | |
| index c4cb001..80486ba 100644
 | |
| --- a/kernel.c
 | |
| +++ b/kernel.c
 | |
| @@ -1459,12 +1459,20 @@ list_source_code(struct gnu_request *req, int count_entered)
 | |
|          char *argv[MAXARGS];
 | |
|  	struct syment *sp;
 | |
|  	ulong remaining, offset;
 | |
| +	struct load_module *lm;
 | |
|  	char *p1;
 | |
|  
 | |
|  	sp = value_search(req->addr, &offset);
 | |
|  	if (!sp || !is_symbol_text(sp))
 | |
|  		error(FATAL, "%lx: not a kernel text address\n", req->addr);
 | |
|  
 | |
| +	if (module_symbol(req->addr, NULL, &lm, NULL, 0)) {
 | |
| +		if (!(lm->mod_flags & MOD_LOAD_SYMS))
 | |
| +			error(FATAL, "%s: module source code is not available\n", lm->mod_name);
 | |
| +		get_line_number(req->addr, buf1, FALSE);
 | |
| +	} else if (kt->flags2 & KASLR)
 | |
| +		req->addr -= (kt->relocate * -1);
 | |
| +
 | |
|  	sprintf(buf1, "list *0x%lx", req->addr);
 | |
|  	open_tmpfile();
 | |
|  	if (!gdb_pass_through(buf1, pc->tmpfile, GNU_RETURN_ON_ERROR)) {
 | |
| 
 | |
| commit 4e4e5859731da650d3520150d7ea2ef07094c7af
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Thu Dec 12 12:08:11 2019 -0500
 | |
| 
 | |
|     Fix for newer Xen hypervisors, which fail during initialization with
 | |
|     the error message "crash: cannot resolve init_tss".  This is caused
 | |
|     by a change in the Xen hypervisor with commit 78884406256, from
 | |
|     4.12.0-rc5-763-g7888440625.  In that patch the tss_struct structure
 | |
|     was renamed to tss64 and the tss_page structure was introduced,
 | |
|     which contains a single tss64.  Now tss information is accessible
 | |
|     via the symbol "per_cpu__tss_page".
 | |
|     (dietmar.hahn@ts.fujitsu.com)
 | |
| 
 | |
| diff --git a/x86.c b/x86.c
 | |
| index 88562b6..de0d3d3 100644
 | |
| --- a/x86.c
 | |
| +++ b/x86.c
 | |
| @@ -5600,18 +5600,18 @@ x86_get_stackbase_hyper(ulong task)
 | |
|  
 | |
|  	if (symbol_exists("init_tss")) {
 | |
|  		init_tss = symbol_value("init_tss");
 | |
| -		init_tss += XEN_HYPER_SIZE(tss_struct) * pcpu;
 | |
| +		init_tss += XEN_HYPER_SIZE(tss) * pcpu;
 | |
|  	} else {
 | |
|  		init_tss = symbol_value("per_cpu__init_tss");
 | |
|  		init_tss = xen_hyper_per_cpu(init_tss, pcpu);
 | |
|  	}
 | |
|  	
 | |
| -	buf = GETBUF(XEN_HYPER_SIZE(tss_struct));
 | |
| +	buf = GETBUF(XEN_HYPER_SIZE(tss));
 | |
|  	if (!readmem(init_tss, KVADDR, buf,
 | |
| -			XEN_HYPER_SIZE(tss_struct), "init_tss", RETURN_ON_ERROR)) {
 | |
| +			XEN_HYPER_SIZE(tss), "init_tss", RETURN_ON_ERROR)) {
 | |
|  		error(FATAL, "cannot read init_tss.\n");
 | |
|  	}
 | |
| -	esp = ULONG(buf + XEN_HYPER_OFFSET(tss_struct_esp0));
 | |
| +	esp = ULONG(buf + XEN_HYPER_OFFSET(tss_esp0));
 | |
|  	FREEBUF(buf);
 | |
|  	base = esp & (~(STACKSIZE() - 1));
 | |
|  
 | |
| @@ -5745,8 +5745,8 @@ x86_init_hyper(int when)
 | |
|  #endif
 | |
|  		XEN_HYPER_STRUCT_SIZE_INIT(cpu_time, "cpu_time");
 | |
|  		XEN_HYPER_STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
 | |
| -		XEN_HYPER_STRUCT_SIZE_INIT(tss_struct, "tss_struct");
 | |
| -		XEN_HYPER_MEMBER_OFFSET_INIT(tss_struct_esp0, "tss_struct", "esp0");
 | |
| +		XEN_HYPER_STRUCT_SIZE_INIT(tss, "tss_struct");
 | |
| +		XEN_HYPER_MEMBER_OFFSET_INIT(tss_esp0, "tss_struct", "esp0");
 | |
|  		XEN_HYPER_MEMBER_OFFSET_INIT(cpu_time_local_tsc_stamp, "cpu_time", "local_tsc_stamp");
 | |
|  		XEN_HYPER_MEMBER_OFFSET_INIT(cpu_time_stime_local_stamp, "cpu_time", "stime_local_stamp");
 | |
|  		XEN_HYPER_MEMBER_OFFSET_INIT(cpu_time_stime_master_stamp, "cpu_time", "stime_master_stamp");
 | |
| diff --git a/x86_64.c b/x86_64.c
 | |
| index a4138ed..4f1a6d7 100644
 | |
| --- a/x86_64.c
 | |
| +++ b/x86_64.c
 | |
| @@ -7973,13 +7973,23 @@ x86_64_init_hyper(int when)
 | |
|  
 | |
|  	case POST_GDB:
 | |
|  		XEN_HYPER_STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
 | |
| -		XEN_HYPER_STRUCT_SIZE_INIT(tss_struct, "tss_struct");
 | |
| -		if (MEMBER_EXISTS("tss_struct", "__blh")) {
 | |
| -			XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "__blh") + sizeof(short unsigned int);
 | |
| +		if (symbol_exists("per_cpu__tss_page")) {
 | |
| +			XEN_HYPER_STRUCT_SIZE_INIT(tss, "tss64");
 | |
| +			XEN_HYPER_ASSIGN_OFFSET(tss_rsp0) =
 | |
| +							MEMBER_OFFSET("tss64", "rsp0");
 | |
| +			XEN_HYPER_MEMBER_OFFSET_INIT(tss_ist, "tss64", "ist");
 | |
|  		} else {
 | |
| -			XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "rsp0");
 | |
| +			XEN_HYPER_STRUCT_SIZE_INIT(tss, "tss_struct");
 | |
| +			XEN_HYPER_MEMBER_OFFSET_INIT(tss_ist, "tss_struct", "ist");
 | |
| +			if (MEMBER_EXISTS("tss_struct", "__blh")) {
 | |
| +				XEN_HYPER_ASSIGN_OFFSET(tss_rsp0) =
 | |
| +					MEMBER_OFFSET("tss_struct", "__blh") +
 | |
| +								sizeof(short unsigned int);
 | |
| +			} else	{
 | |
| +				XEN_HYPER_ASSIGN_OFFSET(tss_rsp0) =
 | |
| +							MEMBER_OFFSET("tss_struct", "rsp0");
 | |
| +			}
 | |
|  		}
 | |
| -		XEN_HYPER_MEMBER_OFFSET_INIT(tss_struct_ist, "tss_struct", "ist");
 | |
|  		if (symbol_exists("cpu_data")) {
 | |
|  			xht->cpu_data_address = symbol_value("cpu_data");
 | |
|  		}
 | |
| diff --git a/xen_hyper.c b/xen_hyper.c
 | |
| index f2f00e6..1030c0a 100644
 | |
| --- a/xen_hyper.c
 | |
| +++ b/xen_hyper.c
 | |
| @@ -338,33 +338,35 @@ xen_hyper_x86_pcpu_init(void)
 | |
|  	if((xhpct->pcpu_struct = malloc(XEN_HYPER_SIZE(cpu_info))) == NULL) {
 | |
|  		error(FATAL, "cannot malloc pcpu struct space.\n");
 | |
|  	}
 | |
| -
 | |
|  	/* get physical cpu context */
 | |
|  	xen_hyper_alloc_pcpu_context_space(XEN_HYPER_MAX_CPUS());
 | |
|  	if (symbol_exists("per_cpu__init_tss")) {
 | |
|  		init_tss_base = symbol_value("per_cpu__init_tss");
 | |
|  		flag = TRUE;
 | |
| +	} else if (symbol_exists("per_cpu__tss_page")) {
 | |
| +			init_tss_base = symbol_value("per_cpu__tss_page");
 | |
| +			flag = TRUE;
 | |
|  	} else {
 | |
|  		init_tss_base = symbol_value("init_tss");
 | |
|  		flag = FALSE;
 | |
|  	}
 | |
| -	buf = GETBUF(XEN_HYPER_SIZE(tss_struct));	
 | |
| +	buf = GETBUF(XEN_HYPER_SIZE(tss));
 | |
|  	for_cpu_indexes(i, cpuid)
 | |
|  	{
 | |
|  		if (flag)
 | |
|  			init_tss = xen_hyper_per_cpu(init_tss_base, cpuid);
 | |
|  		else
 | |
|  			init_tss = init_tss_base +
 | |
| -				XEN_HYPER_SIZE(tss_struct) * cpuid;
 | |
| +				XEN_HYPER_SIZE(tss) * cpuid;
 | |
|  		if (!readmem(init_tss, KVADDR, buf,
 | |
| -			XEN_HYPER_SIZE(tss_struct), "init_tss", RETURN_ON_ERROR)) {
 | |
| +			XEN_HYPER_SIZE(tss), "init_tss", RETURN_ON_ERROR)) {
 | |
|  			error(FATAL, "cannot read init_tss.\n");
 | |
|  		}
 | |
|  		if (machine_type("X86")) {
 | |
| -			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_struct_esp0));
 | |
| +			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_esp0));
 | |
|  		} else if (machine_type("X86_64")) {
 | |
| -			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_struct_rsp0));
 | |
| -		} else 
 | |
| +			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_rsp0));
 | |
| +		} else
 | |
|  			sp = 0;
 | |
|  		cpu_info = XEN_HYPER_GET_CPU_INFO(sp);
 | |
|  		if (CRASHDEBUG(1)) {
 | |
| @@ -1777,10 +1779,10 @@ xen_hyper_store_pcpu_context_tss(struct xen_hyper_pcpu_context *pcc,
 | |
|  
 | |
|  	pcc->init_tss = init_tss;
 | |
|  	if (machine_type("X86")) {
 | |
| -		pcc->sp.esp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_struct_esp0));
 | |
| +		pcc->sp.esp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_esp0));
 | |
|  	} else if (machine_type("X86_64")) {
 | |
| -		pcc->sp.rsp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_struct_rsp0));
 | |
| -		ist_p = (uint64_t *)(tss + XEN_HYPER_OFFSET(tss_struct_ist));
 | |
| +		pcc->sp.rsp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_rsp0));
 | |
| +		ist_p = (uint64_t *)(tss + XEN_HYPER_OFFSET(tss_ist));
 | |
|  		for (i = 0; i < XEN_HYPER_TSS_IST_MAX; i++, ist_p++) {
 | |
|  			pcc->ist[i] = ULONG(ist_p);
 | |
|  		}
 | |
| diff --git a/xen_hyper_defs.h b/xen_hyper_defs.h
 | |
| index b871bdd..acf910a 100644
 | |
| --- a/xen_hyper_defs.h
 | |
| +++ b/xen_hyper_defs.h
 | |
| @@ -598,7 +598,7 @@ struct xen_hyper_size_table {
 | |
|  	long scheduler;
 | |
|  	long shared_info;
 | |
|  	long timer;
 | |
| -	long tss_struct;
 | |
| +	long tss;
 | |
|  	long vcpu;
 | |
|  	long vcpu_runstate_info;
 | |
|  	long xen_crash_xen_regs_t;		/* elf note v2 */
 | |
| @@ -727,9 +727,9 @@ struct xen_hyper_offset_table {
 | |
|  	long timer_heap_offset;
 | |
|  	long timer_killed;
 | |
|  	/* tss */
 | |
| -	long tss_struct_rsp0;
 | |
| -	long tss_struct_esp0;
 | |
| -	long tss_struct_ist;
 | |
| +	long tss_rsp0;
 | |
| +	long tss_esp0;
 | |
| +	long tss_ist;
 | |
|  	/* vcpu */
 | |
|  	long vcpu_vcpu_id;
 | |
|  	long vcpu_processor;
 | |
| diff --git a/xen_hyper_dump_tables.c b/xen_hyper_dump_tables.c
 | |
| index eb646b6..0360d25 100644
 | |
| --- a/xen_hyper_dump_tables.c
 | |
| +++ b/xen_hyper_dump_tables.c
 | |
| @@ -636,8 +636,8 @@ xen_hyper_dump_xen_hyper_size_table(char *spec, ulong makestruct)
 | |
|  		(buf, "%ld\n", xen_hyper_size_table.shared_info));
 | |
|  	XEN_HYPER_PRI(fp, len, "timer: ", buf, flag,
 | |
|  		(buf, "%ld\n", xen_hyper_size_table.timer));
 | |
| -	XEN_HYPER_PRI(fp, len, "tss_struct: ", buf, flag,
 | |
| -		(buf, "%ld\n", xen_hyper_size_table.tss_struct));
 | |
| +	XEN_HYPER_PRI(fp, len, "tss: ", buf, flag,
 | |
| +		(buf, "%ld\n", xen_hyper_size_table.tss));
 | |
|  	XEN_HYPER_PRI(fp, len, "vcpu: ", buf, flag,
 | |
|  		(buf, "%ld\n", xen_hyper_size_table.vcpu));
 | |
|  	XEN_HYPER_PRI(fp, len, "vcpu_runstate_info: ", buf, flag,
 | |
| @@ -868,9 +868,9 @@ xen_hyper_dump_xen_hyper_offset_table(char *spec, ulong makestruct)
 | |
|  		(buf, "%ld\n", xen_hyper_offset_table.timer_killed));
 | |
|  
 | |
|  	XEN_HYPER_PRI(fp, len, "tss_struct_rsp0: ", buf, flag,
 | |
| -		(buf, "%ld\n", xen_hyper_offset_table.tss_struct_rsp0));
 | |
| +		(buf, "%ld\n", xen_hyper_offset_table.tss_rsp0));
 | |
|  	XEN_HYPER_PRI(fp, len, "tss_struct_esp0: ", buf, flag,
 | |
| -		(buf, "%ld\n", xen_hyper_offset_table.tss_struct_esp0));
 | |
| +		(buf, "%ld\n", xen_hyper_offset_table.tss_esp0));
 | |
|  
 | |
|  	XEN_HYPER_PRI(fp, len, "vcpu_vcpu_id: ", buf, flag,
 | |
|  		(buf, "%ld\n", xen_hyper_offset_table.vcpu_vcpu_id));
 | |
| 
 | |
| commit c408862daff0b07f0d98a1c309febcf6590ccf0c
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Sun Dec 15 12:24:13 2019 -0500
 | |
| 
 | |
|     When accessing the ARM64 kernel's "crash_notes" array, continue to
 | |
|     read the per-cpu NT_PRSTATUS note contents if an invalid note is
 | |
|     encountered.  Without the patch, if an invalid note is found, all
 | |
|     other notes were ignored, and subsequent "bt" attempts on the active
 | |
|     tasks would fail.
 | |
|     (chenqiwu@xiaomi.com, anderson@redhat.com)
 | |
| 
 | |
| diff --git a/arm64.c b/arm64.c
 | |
| index 233029d..1b024a4 100644
 | |
| --- a/arm64.c
 | |
| +++ b/arm64.c
 | |
| @@ -81,7 +81,7 @@ static int arm64_on_irq_stack(int, ulong);
 | |
|  static void arm64_set_irq_stack(struct bt_info *);
 | |
|  static void arm64_set_process_stack(struct bt_info *);
 | |
|  static int arm64_get_kvaddr_ranges(struct vaddr_range *);
 | |
| -static int arm64_get_crash_notes(void);
 | |
| +static void arm64_get_crash_notes(void);
 | |
|  static void arm64_calc_VA_BITS(void);
 | |
|  static int arm64_is_uvaddr(ulong, struct task_context *);
 | |
|  
 | |
| @@ -465,11 +465,8 @@ arm64_init(int when)
 | |
|  		 * of the crash. We need this information to extract correct
 | |
|  		 * backtraces from the panic task.
 | |
|  		 */
 | |
| -		if (!LIVE() && !arm64_get_crash_notes())
 | |
| -			error(WARNING, 
 | |
| -			    "cannot retrieve registers for active task%s\n\n",
 | |
| -				kt->cpus > 1 ? "s" : "");
 | |
| -
 | |
| +		if (!LIVE()) 
 | |
| +			arm64_get_crash_notes();
 | |
|  		break;
 | |
|  
 | |
|  	case LOG_ONLY:
 | |
| @@ -3578,7 +3575,7 @@ arm64_get_smp_cpus(void)
 | |
|  /*
 | |
|   * Retrieve task registers for the time of the crash.
 | |
|   */
 | |
| -static int
 | |
| +static void
 | |
|  arm64_get_crash_notes(void)
 | |
|  {
 | |
|  	struct machine_specific *ms = machdep->machspec;
 | |
| @@ -3587,10 +3584,10 @@ arm64_get_crash_notes(void)
 | |
|  	ulong offset;
 | |
|  	char *buf, *p;
 | |
|  	ulong *notes_ptrs;
 | |
| -	ulong i;
 | |
| +	ulong i, found;
 | |
|  
 | |
|  	if (!symbol_exists("crash_notes"))
 | |
| -		return FALSE;
 | |
| +		return;
 | |
|  
 | |
|  	crash_notes = symbol_value("crash_notes");
 | |
|  
 | |
| @@ -3602,9 +3599,9 @@ arm64_get_crash_notes(void)
 | |
|  	 */
 | |
|  	if (!readmem(crash_notes, KVADDR, ¬es_ptrs[kt->cpus-1], 
 | |
|  	    sizeof(notes_ptrs[kt->cpus-1]), "crash_notes", RETURN_ON_ERROR)) {
 | |
| -		error(WARNING, "cannot read crash_notes\n");
 | |
| +		error(WARNING, "cannot read \"crash_notes\"\n");
 | |
|  		FREEBUF(notes_ptrs);
 | |
| -		return FALSE;
 | |
| +		return;
 | |
|  	}
 | |
|  
 | |
|  	if (symbol_exists("__per_cpu_offset")) {
 | |
| @@ -3620,12 +3617,11 @@ arm64_get_crash_notes(void)
 | |
|  	if (!(ms->panic_task_regs = calloc((size_t)kt->cpus, sizeof(struct arm64_pt_regs))))
 | |
|  		error(FATAL, "cannot calloc panic_task_regs space\n");
 | |
|  	
 | |
| -	for  (i = 0; i < kt->cpus; i++) {
 | |
| -
 | |
| +	for  (i = found = 0; i < kt->cpus; i++) {
 | |
|  		if (!readmem(notes_ptrs[i], KVADDR, buf, SIZE(note_buf), 
 | |
|  		    "note_buf_t", RETURN_ON_ERROR)) {
 | |
| -			error(WARNING, "failed to read note_buf_t\n");
 | |
| -			goto fail;
 | |
| +			error(WARNING, "cpu %d: cannot read NT_PRSTATUS note\n", i);
 | |
| +			continue;
 | |
|  		}
 | |
|  
 | |
|  		/*
 | |
| @@ -3655,19 +3651,24 @@ arm64_get_crash_notes(void)
 | |
|  				    note->n_descsz == notesz)
 | |
|  					BCOPY((char *)note, buf, notesz);
 | |
|  			} else {
 | |
| -				error(WARNING,
 | |
| -					"cannot find NT_PRSTATUS note for cpu: %d\n", i);
 | |
| +				error(WARNING, "cpu %d: cannot find NT_PRSTATUS note\n", i);
 | |
|  				continue;
 | |
|  			}
 | |
|  		}
 | |
|  
 | |
| +		/*
 | |
| +		 * Check the sanity of NT_PRSTATUS note only for each online cpu.
 | |
| +		 * If this cpu has invalid note, continue to find the crash notes
 | |
| +		 * for other online cpus.
 | |
| +		 */
 | |
|  		if (note->n_type != NT_PRSTATUS) {
 | |
| -			error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
 | |
| -			goto fail;
 | |
| +			error(WARNING, "cpu %d: invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)\n", i);
 | |
| +			continue;
 | |
|  		}
 | |
| -		if (p[0] != 'C' || p[1] != 'O' || p[2] != 'R' || p[3] != 'E') {
 | |
| -			error(WARNING, "invalid note (name != \"CORE\"\n");
 | |
| -			goto fail;
 | |
| +
 | |
| +		if (!STRNEQ(p, "CORE")) {
 | |
| +			error(WARNING, "cpu %d: invalid NT_PRSTATUS note (name != \"CORE\")\n", i);
 | |
| +			continue;
 | |
|  		}
 | |
|  
 | |
|  		/*
 | |
| @@ -3680,18 +3681,17 @@ arm64_get_crash_notes(void)
 | |
|  
 | |
|  		BCOPY(p + OFFSET(elf_prstatus_pr_reg), &ms->panic_task_regs[i],
 | |
|  		      sizeof(struct arm64_pt_regs));
 | |
| +
 | |
| +		found++;
 | |
|  	}
 | |
|  
 | |
|  	FREEBUF(buf);
 | |
|  	FREEBUF(notes_ptrs);
 | |
| -	return TRUE;
 | |
|  
 | |
| -fail:
 | |
| -	FREEBUF(buf);
 | |
| -	FREEBUF(notes_ptrs);
 | |
| -	free(ms->panic_task_regs);
 | |
| -	ms->panic_task_regs = NULL;
 | |
| -	return FALSE;
 | |
| +	if (!found) {
 | |
| +		free(ms->panic_task_regs);
 | |
| +		ms->panic_task_regs = NULL;
 | |
| +	}
 | |
|  }
 | |
|  
 | |
|  static void
 | |
| 
 | |
| commit 63df9c067de0b2017f50f5d236954890bbb42fe3
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Mon Dec 16 11:28:46 2019 -0500
 | |
| 
 | |
|     When accessing the 32-bit ARM kernel's "crash_notes" array, continue
 | |
|     to read the per-cpu NT_PRSTATUS note contents if an invalid note is
 | |
|     encountered.  Without the patch, if an invalid note is found, all
 | |
|     other notes were ignored, and subsequent "bt" attempts on the active
 | |
|     tasks would fail.
 | |
|     (chenqiwu@xiaomi.com, anderson@redhat.com)
 | |
| 
 | |
| diff --git a/arm.c b/arm.c
 | |
| index b05b0b3..e52d29f 100644
 | |
| --- a/arm.c
 | |
| +++ b/arm.c
 | |
| @@ -26,7 +26,7 @@
 | |
|  #include "defs.h"
 | |
|  
 | |
|  static void arm_parse_cmdline_args(void);
 | |
| -static int arm_get_crash_notes(void);
 | |
| +static void arm_get_crash_notes(void);
 | |
|  static int arm_verify_symbol(const char *, ulong, char);
 | |
|  static int arm_is_module_addr(ulong);
 | |
|  static int arm_is_kvaddr(ulong);
 | |
| @@ -348,10 +348,8 @@ arm_init(int when)
 | |
|  		 * of the crash. We need this information to extract correct
 | |
|  		 * backtraces from the panic task.
 | |
|  		 */
 | |
| -		if (!ACTIVE() && !arm_get_crash_notes())
 | |
| -			error(WARNING, 
 | |
| -			    "cannot retrieve registers for active task%s\n\n",
 | |
| -				kt->cpus > 1 ? "s" : "");
 | |
| +		if (!ACTIVE())
 | |
| +			arm_get_crash_notes();
 | |
|  
 | |
|  		if (init_unwind_tables()) {
 | |
|  			if (CRASHDEBUG(1))
 | |
| @@ -543,7 +541,7 @@ arm_parse_cmdline_args(void)
 | |
|  /*
 | |
|   * Retrieve task registers for the time of the crash.
 | |
|   */
 | |
| -static int
 | |
| +static void
 | |
|  arm_get_crash_notes(void)
 | |
|  {
 | |
|  	struct machine_specific *ms = machdep->machspec;
 | |
| @@ -552,10 +550,10 @@ arm_get_crash_notes(void)
 | |
|  	ulong offset;
 | |
|  	char *buf, *p;
 | |
|  	ulong *notes_ptrs;
 | |
| -	ulong i;
 | |
| +	ulong i, found;
 | |
|  
 | |
|  	if (!symbol_exists("crash_notes"))
 | |
| -		return FALSE;
 | |
| +		return;
 | |
|  
 | |
|  	crash_notes = symbol_value("crash_notes");
 | |
|  
 | |
| @@ -570,11 +568,10 @@ arm_get_crash_notes(void)
 | |
|  		     RETURN_ON_ERROR)) {
 | |
|  		error(WARNING, "cannot read crash_notes\n");
 | |
|  		FREEBUF(notes_ptrs);
 | |
| -		return FALSE;
 | |
| +		return;
 | |
|  	}
 | |
|  
 | |
|  	if (symbol_exists("__per_cpu_offset")) {
 | |
| -
 | |
|  		/* Add __per_cpu_offset for each cpu to form the pointer to the notes */
 | |
|  		for (i = 0; i<kt->cpus; i++)
 | |
|  			notes_ptrs[i] = notes_ptrs[kt->cpus-1] + kt->__per_cpu_offset[i];	
 | |
| @@ -585,12 +582,11 @@ arm_get_crash_notes(void)
 | |
|  	if (!(panic_task_regs = calloc((size_t)kt->cpus, sizeof(*panic_task_regs))))
 | |
|  		error(FATAL, "cannot calloc panic_task_regs space\n");
 | |
|  	
 | |
| -	for  (i=0;i<kt->cpus;i++) {
 | |
| -
 | |
| +	for  (i = found = 0; i<kt->cpus; i++) {
 | |
|  		if (!readmem(notes_ptrs[i], KVADDR, buf, SIZE(note_buf), "note_buf_t",
 | |
|  			     RETURN_ON_ERROR)) {
 | |
| -			error(WARNING, "failed to read note_buf_t\n");
 | |
| -			goto fail;
 | |
| +			error(WARNING, "cpu %d: cannot read NT_PRSTATUS note\n", i);
 | |
| +			continue;
 | |
|  		}
 | |
|  
 | |
|  		/*
 | |
| @@ -620,19 +616,23 @@ arm_get_crash_notes(void)
 | |
|  				    note->n_descsz == notesz)
 | |
|  					BCOPY((char *)note, buf, notesz);
 | |
|  			} else {
 | |
| -				error(WARNING,
 | |
| -					"cannot find NT_PRSTATUS note for cpu: %d\n", i);
 | |
| +				error(WARNING, "cpu %d: cannot find NT_PRSTATUS note\n", i);
 | |
|  				continue;
 | |
|  			}
 | |
|  		}
 | |
| -
 | |
| +		/*
 | |
| +		 * Check the sanity of NT_PRSTATUS note only for each online cpu.
 | |
| +		 * If this cpu has invalid note, continue to find the crash notes
 | |
| +		 * for other online cpus.
 | |
| +		 */
 | |
|  		if (note->n_type != NT_PRSTATUS) {
 | |
| -			error(WARNING, "invalid note (n_type != NT_PRSTATUS)\n");
 | |
| -			goto fail;
 | |
| +			error(WARNING, "cpu %d: invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)\n", i);
 | |
| +			continue;
 | |
|  		}
 | |
| -		if (p[0] != 'C' || p[1] != 'O' || p[2] != 'R' || p[3] != 'E') {
 | |
| -			error(WARNING, "invalid note (name != \"CORE\"\n");
 | |
| -			goto fail;
 | |
| +
 | |
| +		if (!STRNEQ(p, "CORE")) {
 | |
| +			error(WARNING, "cpu %d: invalid NT_PRSTATUS note (name != \"CORE\")\n", i);
 | |
| +			continue;
 | |
|  		}
 | |
|  
 | |
|  		/*
 | |
| @@ -646,6 +646,7 @@ arm_get_crash_notes(void)
 | |
|  		BCOPY(p + OFFSET(elf_prstatus_pr_reg), &panic_task_regs[i],
 | |
|  		      sizeof(panic_task_regs[i]));
 | |
|  
 | |
| +		found++;
 | |
|  	}
 | |
|  
 | |
|  	/*
 | |
| @@ -656,13 +657,10 @@ arm_get_crash_notes(void)
 | |
|  
 | |
|  	FREEBUF(buf);
 | |
|  	FREEBUF(notes_ptrs);
 | |
| -	return TRUE;
 | |
| -
 | |
| -fail:
 | |
| -	FREEBUF(buf);
 | |
| -	FREEBUF(notes_ptrs);
 | |
| -	free(panic_task_regs);
 | |
| -	return FALSE;
 | |
| +	if (!found) {
 | |
| +		free(panic_task_regs);
 | |
| +		ms->crash_task_regs = NULL;
 | |
| +	}
 | |
|  }
 | |
|  
 | |
|  /*
 | |
| 
 | |
| commit af7f78dc501b8acf7fee3f924f69e93513d0a74b
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Fri Dec 20 14:33:11 2019 -0500
 | |
| 
 | |
|     Fix for the "log -a" option.  The kernel's sk_buff.len field is a
 | |
|     32-bit unsigned int, but crash was reading its 32-bit value into a
 | |
|     64-bit unsigned long stack variable.  All extra bits that pre-existed
 | |
|     in the upper 32-bits of the stack variable were passed along as part
 | |
|     of a buffer size request; if the upper 32-bit bits were non-zero,
 | |
|     then the command would fail with a dump of the internal buffer
 | |
|     allocation stats followed by the message "log: cannot allocate any
 | |
|     more memory!".
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/kernel.c b/kernel.c
 | |
| index 80486ba..68ee282 100644
 | |
| --- a/kernel.c
 | |
| +++ b/kernel.c
 | |
| @@ -11284,7 +11284,8 @@ dump_audit_skb_queue(ulong audit_skb_queue)
 | |
|  
 | |
|  	p = skb_buff_head_next;
 | |
|  	do {
 | |
| -		ulong data, len, data_len;
 | |
| +		ulong data, data_len;
 | |
| +		uint len;
 | |
|  		uint16_t nlmsg_type;
 | |
|  		char *buf = NULL;
 | |
|  
 | |
| @@ -11295,7 +11296,7 @@ dump_audit_skb_queue(ulong audit_skb_queue)
 | |
|  			KVADDR,
 | |
|  			&len,
 | |
|  			SIZE(sk_buff_len),
 | |
| -			"sk_buff.data",
 | |
| +			"sk_buff.len",
 | |
|  			FAULT_ON_ERROR);
 | |
|  
 | |
|  		data_len = len - roundup(SIZE(nlmsghdr), NLMSG_ALIGNTO);
 | |
| 
 | |
| commit 5e975dd8c817ea6aea35e1e15b83c378aee9c136
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Tue Dec 24 08:43:52 2019 -0500
 | |
| 
 | |
|     When determining the ARM64 kernel's "vabits_actual" value by reading
 | |
|     the new TCR_EL1.T1SZ vmcoreinfo entry, display its value during
 | |
|     session initialization only when invoking crash with "-d1" or larger
 | |
|     -d debug value.
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/arm64.c b/arm64.c
 | |
| index 1b024a4..6c2c58f 100644
 | |
| --- a/arm64.c
 | |
| +++ b/arm64.c
 | |
| @@ -3864,7 +3864,8 @@ arm64_calc_VA_BITS(void)
 | |
|  				 * vabits_actual = 64 - T1SZ;
 | |
|  				 */
 | |
|  				value = 64 - strtoll(string, NULL, 0);
 | |
| -				fprintf(fp,  "vmcoreinfo : vabits_actual: %ld\n", value);
 | |
| +				if (CRASHDEBUG(1))
 | |
| +					fprintf(fp,  "vmcoreinfo : vabits_actual: %ld\n", value);
 | |
|  				free(string);
 | |
|  				machdep->machspec->VA_BITS_ACTUAL = value;
 | |
|  				machdep->machspec->VA_BITS = value;
 | |
| 
 | |
| commit 0ab7ac3bea5deaa3da894247ffab9ef2433c1b9b
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Tue Jan 7 09:34:38 2020 -0500
 | |
| 
 | |
|     Update copyright to 2020 in crash version output.
 | |
| 
 | |
| diff --git a/help.c b/help.c
 | |
| index eed249b..a481850 100644
 | |
| --- a/help.c
 | |
| +++ b/help.c
 | |
| @@ -1,8 +1,8 @@
 | |
|  /* help.c - core analysis suite
 | |
|   *
 | |
|   * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
 | |
| - * Copyright (C) 2002-2019 David Anderson
 | |
| - * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
 | |
| + * Copyright (C) 2002-2020 David Anderson
 | |
| + * Copyright (C) 2002-2020 Red Hat, Inc. All rights reserved.
 | |
|   *
 | |
|   * This program is free software; you can redistribute it and/or modify
 | |
|   * it under the terms of the GNU General Public License as published by
 | |
| @@ -8269,7 +8269,7 @@ display_version(void)
 | |
|  static 
 | |
|  char *version_info[] = {
 | |
|  
 | |
| -"Copyright (C) 2002-2019  Red Hat, Inc.",
 | |
| +"Copyright (C) 2002-2020  Red Hat, Inc.",
 | |
|  "Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation", 
 | |
|  "Copyright (C) 1999-2006  Hewlett-Packard Co",
 | |
|  "Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited",
 | |
| 
 | |
| commit 08b01834641b0a387c86adf651c660df0fe37ae1
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Tue Jan 7 11:07:12 2020 -0500
 | |
| 
 | |
|     Fix for ARM64 when running against Linux 5.5-rc1 and later kernels
 | |
|     that contain commit b6e43c0e3129ffe87e65c85f20fcbdf0eb86fba0, titled
 | |
|     "arm64: remove __exception annotations".  Without the patch, the
 | |
|     ARM64 crash session fails during initialization with the error
 | |
|     message "crash: cannot resolve __exception_text_start".
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/arm64.c b/arm64.c
 | |
| index 6c2c58f..7662d71 100644
 | |
| --- a/arm64.c
 | |
| +++ b/arm64.c
 | |
| @@ -1,8 +1,8 @@
 | |
|  /*
 | |
|   * arm64.c - core analysis suite
 | |
|   *
 | |
| - * Copyright (C) 2012-2019 David Anderson
 | |
| - * Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
 | |
| + * Copyright (C) 2012-2020 David Anderson
 | |
| + * Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
 | |
|   *
 | |
|   * This program is free software; you can redistribute it and/or modify
 | |
|   * it under the terms of the GNU General Public License as published by
 | |
| @@ -1644,10 +1644,11 @@ arm64_stackframe_init(void)
 | |
|  		machdep->machspec->kern_eframe_offset = SIZE(pt_regs);
 | |
|  	}
 | |
|  
 | |
| -	machdep->machspec->__exception_text_start = 
 | |
| -		symbol_value("__exception_text_start");
 | |
| -	machdep->machspec->__exception_text_end = 
 | |
| -		symbol_value("__exception_text_end");
 | |
| +	if ((sp1 = kernel_symbol_search("__exception_text_start")) &&
 | |
| +	    (sp2 = kernel_symbol_search("__exception_text_end"))) {
 | |
| +		machdep->machspec->__exception_text_start = sp1->value;
 | |
| +		machdep->machspec->__exception_text_end = sp2->value;
 | |
| +	}
 | |
|  	if ((sp1 = kernel_symbol_search("__irqentry_text_start")) &&
 | |
|  	    (sp2 = kernel_symbol_search("__irqentry_text_end"))) {
 | |
|  		machdep->machspec->__irqentry_text_start = sp1->value; 
 | |
| @@ -1856,20 +1857,38 @@ arm64_eframe_search(struct bt_info *bt)
 | |
|  	return count;
 | |
|  }
 | |
|  
 | |
| +static char *arm64_exception_functions[] = {
 | |
| +        "do_undefinstr",
 | |
| +        "do_sysinstr",
 | |
| +        "do_debug_exception",
 | |
| +        "do_mem_abort",
 | |
| +        "do_el0_irq_bp_hardening",
 | |
| +        "do_sp_pc_abort",
 | |
| +        NULL
 | |
| +};
 | |
| +
 | |
|  static int
 | |
|  arm64_in_exception_text(ulong ptr)
 | |
|  {
 | |
|  	struct machine_specific *ms = machdep->machspec;
 | |
| -
 | |
| -	if ((ptr >= ms->__exception_text_start) &&
 | |
| -	    (ptr < ms->__exception_text_end))
 | |
| -		return TRUE;
 | |
| +	char *name, **func;
 | |
|  
 | |
|  	if (ms->__irqentry_text_start && ms->__irqentry_text_end &&
 | |
|  	    ((ptr >= ms->__irqentry_text_start) && 
 | |
|  	    (ptr < ms->__irqentry_text_end)))
 | |
|  		return TRUE;
 | |
|  
 | |
| +	if (ms->__exception_text_start && ms->__exception_text_end) {
 | |
| +		if ((ptr >= ms->__exception_text_start) &&
 | |
| +		    (ptr < ms->__exception_text_end))
 | |
| +			return TRUE;
 | |
| +	} else if ((name = closest_symbol(ptr))) {  /* Linux 5.5 and later */
 | |
| +		for (func = &arm64_exception_functions[0]; *func; func++) {
 | |
| +			if (STREQ(name, *func))
 | |
| +				return TRUE;
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
|  	return FALSE;
 | |
|  }
 | |
|  
 | |
| 
 | |
| commit 7c2d41e1b25e9fec50d525361bcfa29bdaa410b2
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Wed Jan 8 14:28:39 2020 -0500
 | |
| 
 | |
|     Fix for support of ELF format kdump vmcores from S390X KASLR kernels.
 | |
|     Without the patch, the crash session fails during initialization with
 | |
|     the error message "crash: vmlinux and vmcore do not match!".
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/symbols.c b/symbols.c
 | |
| index 7e1bca7..82ac549 100644
 | |
| --- a/symbols.c
 | |
| +++ b/symbols.c
 | |
| @@ -1,8 +1,8 @@
 | |
|  /* symbols.c - core analysis suite
 | |
|   *
 | |
|   * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
 | |
| - * Copyright (C) 2002-2019 David Anderson
 | |
| - * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
 | |
| + * Copyright (C) 2002-2020 David Anderson
 | |
| + * Copyright (C) 2002-2020 Red Hat, Inc. All rights reserved.
 | |
|   *
 | |
|   * This program is free software; you can redistribute it and/or modify
 | |
|   * it under the terms of the GNU General Public License as published by
 | |
| @@ -597,6 +597,11 @@ kaslr_init(void)
 | |
|  	    !machine_type("S390X")) || (kt->flags & RELOC_SET))
 | |
|  		return;
 | |
|  
 | |
| +	if ((string = pc->read_vmcoreinfo("SYMBOL(_stext)"))) {
 | |
| +		kt->vmcoreinfo._stext_SYMBOL = htol(string, RETURN_ON_ERROR, NULL);
 | |
| +		free(string);
 | |
| +	}
 | |
| +
 | |
|  	/*
 | |
|  	 *  --kaslr=auto
 | |
|  	 */
 | |
| @@ -609,8 +614,7 @@ kaslr_init(void)
 | |
|  		st->_stext_vmlinux = UNINITIALIZED;
 | |
|  	}
 | |
|  
 | |
| -	if (machine_type("S390X") &&  /* Linux 5.2 */
 | |
| -	    (symbol_value_from_proc_kallsyms("__kaslr_offset") != BADVAL)) {
 | |
| +	if (machine_type("S390X")) { 
 | |
|  		kt->flags2 |= (RELOC_AUTO|KASLR);
 | |
|  		st->_stext_vmlinux = UNINITIALIZED;
 | |
|  	}
 | |
| @@ -622,12 +626,6 @@ kaslr_init(void)
 | |
|  			kt->flags2 |= KASLR_CHECK;
 | |
|  		}
 | |
|  	} else if (KDUMP_DUMPFILE() || DISKDUMP_DUMPFILE()) {
 | |
| -		if ((string = pc->read_vmcoreinfo("SYMBOL(_stext)"))) {
 | |
| -			kt->vmcoreinfo._stext_SYMBOL =
 | |
| -				htol(string, RETURN_ON_ERROR, NULL);
 | |
| -			free(string);
 | |
| -		}
 | |
| -
 | |
|  		/* Linux 3.14 */
 | |
|  		if ((string = pc->read_vmcoreinfo("KERNELOFFSET"))) {
 | |
|  			free(string);
 | |
| 
 | |
| commit 6e033fe099f8faea8fe284b9f7c08da7bc3af7a7
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Thu Jan 16 11:46:10 2020 -0500
 | |
| 
 | |
|     Fix for support of S390X standalone dumpfiles and LKCD dumpfiles that
 | |
|     were taken from S390X KASLR kernels.
 | |
|     (zaslonko@linux.ibm.com)
 | |
| 
 | |
| diff --git a/defs.h b/defs.h
 | |
| index efa40b9..88a47d6 100644
 | |
| --- a/defs.h
 | |
| +++ b/defs.h
 | |
| @@ -6267,6 +6267,8 @@ void get_s390_panicmsg(char *);
 | |
|  /*
 | |
|   *  s390x.c
 | |
|   */
 | |
| +ulong get_stext_relocated_s390x(void);
 | |
| +
 | |
|  #ifdef S390X
 | |
|  void s390x_init(int);
 | |
|  void s390x_dump_machdep_table(ulong);
 | |
| diff --git a/s390x.c b/s390x.c
 | |
| index 8840cc7..e030f93 100644
 | |
| --- a/s390x.c
 | |
| +++ b/s390x.c
 | |
| @@ -455,6 +455,78 @@ static void s390x_check_live(void)
 | |
|  		pc->flags2 |= LIVE_DUMP;
 | |
|  }
 | |
|  
 | |
| +static char *
 | |
| +vmcoreinfo_read_string_s390x(const char *vmcoreinfo, const char *key)
 | |
| +{
 | |
| +	char *value_string = NULL;
 | |
| +	size_t value_length;
 | |
| +	char keybuf[128];
 | |
| +	char *p1, *p2;
 | |
| +
 | |
| +	sprintf(keybuf, "%s=", key);
 | |
| +
 | |
| +	if ((p1 = strstr(vmcoreinfo, keybuf))) {
 | |
| +		p2 = p1 + strlen(keybuf);
 | |
| +		p1 = strstr(p2, "\n");
 | |
| +		value_length = p1-p2;
 | |
| +		value_string = calloc(value_length + 1, sizeof(char));
 | |
| +		strncpy(value_string, p2, value_length);
 | |
| +		value_string[value_length] = NULLCHAR;
 | |
| +	}
 | |
| +
 | |
| +	return value_string;
 | |
| +}
 | |
| +
 | |
| +/*
 | |
| + * Read _stext symbol from vmcoreinfo when lowcore vmcoreinfo pointer is present
 | |
| + * in the dump (can be relevant for s390 and lkcd dump formats).
 | |
| + */
 | |
| +ulong get_stext_relocated_s390x(void)
 | |
| +{
 | |
| +	char *_stext_string, *vmcoreinfo;
 | |
| +	Elf64_Nhdr note;
 | |
| +	char str[128];
 | |
| +	ulong val = 0;
 | |
| +	ulong addr;
 | |
| +
 | |
| +	if (!readmem(S390X_LC_VMCORE_INFO, PHYSADDR, &addr,
 | |
| +		    sizeof(addr), "s390x vmcoreinfo ptr",
 | |
| +		    QUIET|RETURN_ON_ERROR))
 | |
| +		return 0;
 | |
| +	if (addr == 0 ||  addr & 0x1)
 | |
| +		return 0;
 | |
| +	if (!readmem(addr, PHYSADDR, ¬e,
 | |
| +		     sizeof(note), "Elf64_Nhdr vmcoreinfo",
 | |
| +		     QUIET|RETURN_ON_ERROR))
 | |
| +		return 0;
 | |
| +	memset(str, 0, sizeof(str));
 | |
| +	if (!readmem(addr + sizeof(note), PHYSADDR, str,
 | |
| +		     note.n_namesz, "VMCOREINFO",
 | |
| +		     QUIET|RETURN_ON_ERROR))
 | |
| +		return 0;
 | |
| +	if (memcmp(str, "VMCOREINFO", sizeof("VMCOREINFO")) != 0)
 | |
| +		return 0;
 | |
| +	if ((vmcoreinfo = malloc(note.n_descsz + 1)) == NULL) {
 | |
| +		error(INFO, "s390x: cannot malloc vmcoreinfo buffer\n");
 | |
| +		return 0;
 | |
| +	}
 | |
| +	addr = addr + sizeof(note) + note.n_namesz + 1;
 | |
| +	if (!readmem(addr, PHYSADDR, vmcoreinfo,
 | |
| +		     note.n_descsz, "s390x vmcoreinfo",
 | |
| +		     QUIET|RETURN_ON_ERROR)) {
 | |
| +		free(vmcoreinfo);
 | |
| +		return 0;
 | |
| +	}
 | |
| +	vmcoreinfo[note.n_descsz] = 0;
 | |
| +	if ((_stext_string = vmcoreinfo_read_string_s390x(vmcoreinfo,
 | |
| +							  "SYMBOL(_stext)"))) {
 | |
| +		val = htol(_stext_string, RETURN_ON_ERROR, NULL);
 | |
| +		free(_stext_string);
 | |
| +	}
 | |
| +	free(vmcoreinfo);
 | |
| +	return val;
 | |
| +}
 | |
| +
 | |
|  /*
 | |
|   *  Do all necessary machine-specific setup here.  This is called several
 | |
|   *  times during initialization.
 | |
| @@ -1948,4 +2020,10 @@ s390x_get_kvaddr_ranges(struct vaddr_range *vrp)
 | |
|  
 | |
|  	return cnt;
 | |
|  }
 | |
| -#endif 
 | |
| +#else
 | |
| +#include "defs.h"
 | |
| +ulong get_stext_relocated_s390x(void)
 | |
| +{
 | |
| +	return 0;
 | |
| +}
 | |
| +#endif  /* S390X */
 | |
| diff --git a/symbols.c b/symbols.c
 | |
| index 82ac549..6df3358 100644
 | |
| --- a/symbols.c
 | |
| +++ b/symbols.c
 | |
| @@ -614,7 +614,9 @@ kaslr_init(void)
 | |
|  		st->_stext_vmlinux = UNINITIALIZED;
 | |
|  	}
 | |
|  
 | |
| -	if (machine_type("S390X")) { 
 | |
| +	if (machine_type("S390X")) {
 | |
| +		if (!kt->vmcoreinfo._stext_SYMBOL)
 | |
| +			kt->vmcoreinfo._stext_SYMBOL = get_stext_relocated_s390x();
 | |
|  		kt->flags2 |= (RELOC_AUTO|KASLR);
 | |
|  		st->_stext_vmlinux = UNINITIALIZED;
 | |
|  	}
 | |
| 
 | |
| commit c6b19715495221dca52a57690419f9df9777573d
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Fri Jan 17 13:34:53 2020 -0500
 | |
| 
 | |
|     Rework the previous patch for support of S390X standalone dumpfiles
 | |
|     and LKCD dumpfiles that were taken from S390X KASLR kernels to avoid
 | |
|     calling an s390x-specific function from generic code.
 | |
|     (zaslonko@linux.ibm.com)
 | |
| 
 | |
| diff --git a/defs.h b/defs.h
 | |
| index 88a47d6..efa40b9 100644
 | |
| --- a/defs.h
 | |
| +++ b/defs.h
 | |
| @@ -6267,8 +6267,6 @@ void get_s390_panicmsg(char *);
 | |
|  /*
 | |
|   *  s390x.c
 | |
|   */
 | |
| -ulong get_stext_relocated_s390x(void);
 | |
| -
 | |
|  #ifdef S390X
 | |
|  void s390x_init(int);
 | |
|  void s390x_dump_machdep_table(ulong);
 | |
| diff --git a/s390x.c b/s390x.c
 | |
| index e030f93..c07d283 100644
 | |
| --- a/s390x.c
 | |
| +++ b/s390x.c
 | |
| @@ -478,53 +478,72 @@ vmcoreinfo_read_string_s390x(const char *vmcoreinfo, const char *key)
 | |
|  }
 | |
|  
 | |
|  /*
 | |
| - * Read _stext symbol from vmcoreinfo when lowcore vmcoreinfo pointer is present
 | |
| - * in the dump (can be relevant for s390 and lkcd dump formats).
 | |
| + * Check the value in well-known lowcore location and process it as either
 | |
| + * an explicit KASLR offset (early dump case) or as vmcoreinfo pointer to
 | |
| + * read the relocated _stext symbol value (important for s390 and lkcd dump
 | |
| + * formats).
 | |
|   */
 | |
| -ulong get_stext_relocated_s390x(void)
 | |
| +static void s390x_check_kaslr(void)
 | |
|  {
 | |
|  	char *_stext_string, *vmcoreinfo;
 | |
|  	Elf64_Nhdr note;
 | |
|  	char str[128];
 | |
| -	ulong val = 0;
 | |
|  	ulong addr;
 | |
|  
 | |
| +	/* Read the value from well-known lowcore location*/
 | |
|  	if (!readmem(S390X_LC_VMCORE_INFO, PHYSADDR, &addr,
 | |
|  		    sizeof(addr), "s390x vmcoreinfo ptr",
 | |
|  		    QUIET|RETURN_ON_ERROR))
 | |
| -		return 0;
 | |
| -	if (addr == 0 ||  addr & 0x1)
 | |
| -		return 0;
 | |
| +		return;
 | |
| +	if (addr == 0)
 | |
| +		return;
 | |
| +	/* Check for explicit kaslr offset flag */
 | |
| +	if (addr & 0x1UL) {
 | |
| +		/* Drop the last bit to get an offset value */
 | |
| +		addr &= ~(0x1UL);
 | |
| +		/* Make sure the offset is aligned by 0x1000 */
 | |
| +		if (addr && !(addr & 0xfff)) {
 | |
| +					kt->relocate = addr * (-1);
 | |
| +					kt->flags |= RELOC_SET;
 | |
| +					kt->flags2 |= KASLR;
 | |
| +		}
 | |
| +		return;
 | |
| +	}
 | |
| +	/* Use the addr value as vmcoreinfo pointer */
 | |
|  	if (!readmem(addr, PHYSADDR, ¬e,
 | |
|  		     sizeof(note), "Elf64_Nhdr vmcoreinfo",
 | |
|  		     QUIET|RETURN_ON_ERROR))
 | |
| -		return 0;
 | |
| +		return;
 | |
|  	memset(str, 0, sizeof(str));
 | |
|  	if (!readmem(addr + sizeof(note), PHYSADDR, str,
 | |
|  		     note.n_namesz, "VMCOREINFO",
 | |
|  		     QUIET|RETURN_ON_ERROR))
 | |
| -		return 0;
 | |
| +		return;
 | |
|  	if (memcmp(str, "VMCOREINFO", sizeof("VMCOREINFO")) != 0)
 | |
| -		return 0;
 | |
| +		return;
 | |
|  	if ((vmcoreinfo = malloc(note.n_descsz + 1)) == NULL) {
 | |
| -		error(INFO, "s390x: cannot malloc vmcoreinfo buffer\n");
 | |
| -		return 0;
 | |
| +		error(INFO, "s390x_check_kaslr: cannot malloc vmcoreinfo buffer\n");
 | |
| +		return;
 | |
|  	}
 | |
|  	addr = addr + sizeof(note) + note.n_namesz + 1;
 | |
|  	if (!readmem(addr, PHYSADDR, vmcoreinfo,
 | |
|  		     note.n_descsz, "s390x vmcoreinfo",
 | |
|  		     QUIET|RETURN_ON_ERROR)) {
 | |
|  		free(vmcoreinfo);
 | |
| -		return 0;
 | |
| +		return;
 | |
|  	}
 | |
| -	vmcoreinfo[note.n_descsz] = 0;
 | |
| +	vmcoreinfo[note.n_descsz] = NULLCHAR;
 | |
| +	/*
 | |
| +	 * Read relocated _stext symbol value and store it in the kernel_table
 | |
| +	 * for further processing within derive_kaslr_offset().
 | |
| +	 */
 | |
|  	if ((_stext_string = vmcoreinfo_read_string_s390x(vmcoreinfo,
 | |
|  							  "SYMBOL(_stext)"))) {
 | |
| -		val = htol(_stext_string, RETURN_ON_ERROR, NULL);
 | |
| +		kt->vmcoreinfo._stext_SYMBOL = htol(_stext_string,
 | |
| +						    RETURN_ON_ERROR, NULL);
 | |
|  		free(_stext_string);
 | |
|  	}
 | |
|  	free(vmcoreinfo);
 | |
| -	return val;
 | |
|  }
 | |
|  
 | |
|  /*
 | |
| @@ -534,8 +553,6 @@ ulong get_stext_relocated_s390x(void)
 | |
|  void
 | |
|  s390x_init(int when)
 | |
|  {
 | |
| -	ulong s390x_lc_kaslr;
 | |
| -
 | |
|  	switch (when)
 | |
|  	{
 | |
|  	case SETUP_ENV:
 | |
| @@ -562,24 +579,8 @@ s390x_init(int when)
 | |
|  		machdep->verify_paddr = generic_verify_paddr;
 | |
|  		machdep->get_kvaddr_ranges = s390x_get_kvaddr_ranges;
 | |
|  		machdep->ptrs_per_pgd = PTRS_PER_PGD;
 | |
| -		if (DUMPFILE() && !(kt->flags & RELOC_SET)) {
 | |
| -			/* Read the value from well-known lowcore location*/
 | |
| -			if (readmem(S390X_LC_VMCORE_INFO, PHYSADDR, &s390x_lc_kaslr,
 | |
| -			    sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
 | |
| -			    QUIET|RETURN_ON_ERROR)) {
 | |
| -				/* Check for explicit kaslr offset flag */
 | |
| -				if (s390x_lc_kaslr & 0x1UL) {
 | |
| -					/* Drop the last bit to get an offset value */
 | |
| -					s390x_lc_kaslr &= ~(0x1UL);
 | |
| -					/* Make sure the offset is aligned by 0x1000 */
 | |
| -					if (s390x_lc_kaslr && !(s390x_lc_kaslr & 0xfff)) {
 | |
| -						kt->relocate = s390x_lc_kaslr * (-1);
 | |
| -						kt->flags |= RELOC_SET;
 | |
| -						kt->flags2 |= KASLR;
 | |
| -					}
 | |
| -				}
 | |
| -			}
 | |
| -		}
 | |
| +		if (DUMPFILE() && !(kt->flags & RELOC_SET))
 | |
| +			s390x_check_kaslr();
 | |
|  		break;
 | |
|  
 | |
|  	case PRE_GDB:
 | |
| @@ -2020,10 +2021,4 @@ s390x_get_kvaddr_ranges(struct vaddr_range *vrp)
 | |
|  
 | |
|  	return cnt;
 | |
|  }
 | |
| -#else
 | |
| -#include "defs.h"
 | |
| -ulong get_stext_relocated_s390x(void)
 | |
| -{
 | |
| -	return 0;
 | |
| -}
 | |
|  #endif  /* S390X */
 | |
| diff --git a/symbols.c b/symbols.c
 | |
| index 6df3358..f04e8b5 100644
 | |
| --- a/symbols.c
 | |
| +++ b/symbols.c
 | |
| @@ -597,7 +597,8 @@ kaslr_init(void)
 | |
|  	    !machine_type("S390X")) || (kt->flags & RELOC_SET))
 | |
|  		return;
 | |
|  
 | |
| -	if ((string = pc->read_vmcoreinfo("SYMBOL(_stext)"))) {
 | |
| +	if (!kt->vmcoreinfo._stext_SYMBOL &&
 | |
| +	    (string = pc->read_vmcoreinfo("SYMBOL(_stext)"))) {
 | |
|  		kt->vmcoreinfo._stext_SYMBOL = htol(string, RETURN_ON_ERROR, NULL);
 | |
|  		free(string);
 | |
|  	}
 | |
| @@ -615,8 +616,6 @@ kaslr_init(void)
 | |
|  	}
 | |
|  
 | |
|  	if (machine_type("S390X")) {
 | |
| -		if (!kt->vmcoreinfo._stext_SYMBOL)
 | |
| -			kt->vmcoreinfo._stext_SYMBOL = get_stext_relocated_s390x();
 | |
|  		kt->flags2 |= (RELOC_AUTO|KASLR);
 | |
|  		st->_stext_vmlinux = UNINITIALIZED;
 | |
|  	}
 | |
| 
 | |
| commit 6c1c8ac6b3c877e6facd6f2807ba721ddbc4597b
 | |
| Author: Dave Anderson <anderson@redhat.com>
 | |
| Date:   Wed Jan 29 11:10:26 2020 -0500
 | |
| 
 | |
|     Fix for a gcc-10 compilation error.  Without the patch, the build of
 | |
|     the crash library fails with a stream of error messages indicating
 | |
|     "multiple definition of 'diskdump_flags'"
 | |
|     (anderson@redhat.com)
 | |
| 
 | |
| diff --git a/defs.h b/defs.h
 | |
| index efa40b9..ac24a5d 100644
 | |
| --- a/defs.h
 | |
| +++ b/defs.h
 | |
| @@ -1,8 +1,8 @@
 | |
|  /* defs.h - core analysis suite
 | |
|   *
 | |
|   * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
 | |
| - * Copyright (C) 2002-2019 David Anderson
 | |
| - * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
 | |
| + * Copyright (C) 2002-2020 David Anderson
 | |
| + * Copyright (C) 2002-2020 Red Hat, Inc. All rights reserved.
 | |
|   * Copyright (C) 2002 Silicon Graphics, Inc.
 | |
|   *
 | |
|   * This program is free software; you can redistribute it and/or modify
 | |
| @@ -6447,7 +6447,7 @@ FILE *set_diskdump_fp(FILE *);
 | |
|  void get_diskdump_regs(struct bt_info *, ulong *, ulong *);
 | |
|  int diskdump_phys_base(unsigned long *);
 | |
|  int diskdump_set_phys_base(unsigned long);
 | |
| -ulong *diskdump_flags;
 | |
| +extern ulong *diskdump_flags;
 | |
|  int is_partial_diskdump(void);
 | |
|  int get_dump_level(void);
 | |
|  int dumpfile_is_split(void);
 |