Update to latest upstream release(crash-8.0.0)

Release: crash-8.0.0-1

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
Lianbo Jiang 2021-11-24 21:10:10 +08:00
parent e1f6e2b6fb
commit 99e49885eb
58 changed files with 11 additions and 15418 deletions

1
.gitignore vendored
View File

@ -44,5 +44,6 @@ crash-5.0.6.tar.gz
/crash-7.2.8.tar.gz
/crash-7.2.9.tar.gz
/crash-7.3.0.tar.gz
/crash-8.0.0.tar.gz
/gdb-7.6.tar.gz
/gdb-10.2.tar.gz

View File

@ -1,50 +0,0 @@
From a7ecf2467f953b632713f38ab8104596755bca8c Mon Sep 17 00:00:00 2001
From: John Donnelly <john.p.donnelly@oracle.com>
Date: Wed, 12 May 2021 14:48:03 -0700
Subject: [PATCH 01/16] arm64: Add lowercase tcr_el1_t1sz
Commit 1c45cea "arm64: Change tcr_el1_t1sz variable name to
TCR_EL1_T1SZ", renamed the variable to upper case, but there are
kernels in existence that still have the lower case name, which
breaks crash backwards compatibility.
Resolves: https://github.com/crash-utility/crash/pull/82
Signed-off-by: John Donnelly <john.p.donnelly@oracle.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 3 ++-
netdump.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index 4787fa61e3e5..8934961b109d 100644
--- a/arm64.c
+++ b/arm64.c
@@ -3936,7 +3936,8 @@ 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(TCR_EL1_T1SZ)"))) {
+ if ((string = pc->read_vmcoreinfo("NUMBER(TCR_EL1_T1SZ)")) ||
+ (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
diff --git a/netdump.c b/netdump.c
index c1c9cbfaed94..aaea945aaca7 100644
--- a/netdump.c
+++ b/netdump.c
@@ -1921,7 +1921,8 @@ vmcoreinfo_read_string(const char *key)
sprintf(value, "%ld", nd->arch_data2 & 0xffffffff);
return value;
}
- if (STREQ(key, "NUMBER(TCR_EL1_T1SZ)") && nd->arch_data2) {
+ if ((STREQ(key, "NUMBER(TCR_EL1_T1SZ)") ||
+ 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;
--
2.30.2

View File

@ -1,156 +0,0 @@
From 80334ed25820cc08d147de5da361f427885cdd9e Mon Sep 17 00:00:00 2001
From: Aaron Tomlin <atomlin@redhat.com>
Date: Tue, 13 Jul 2021 14:24:49 +0100
Subject: [PATCH 01/27] kmem: Add support to -S option to specify a range of
CPU-specific slab data
With this patch, it is now possible for one to explicitly specify a range
of CPU-specific slab data to list. For example:
Note: This is only applicable to a Linux kernel with Kconfig
CONFIG_SLUB enabled. The optional argument GNU extension
for getopt(3) is utilized; and, the CPU range must be
specified as expected
crash> kmem -S=1,4 kmalloc-512
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
ffff8d3f07c06c00 512 1916 3680 115 16k kmalloc-512
CPU 1 KMEM_CACHE_CPU:
ffff8d461fa6f140
CPU 1 SLAB:
SLAB MEMORY NODE TOTAL ALLOCATED FREE
fffff540df7c4000 ffff8d45df100000 0 32 8 24
FREE / [ALLOCATED]
ffff8d45df100000 (cpu 1 cache)
[ffff8d45df100200]
ffff8d45df101000 (cpu 1 cache)
...skipped ...
CPU 4 KMEM_CACHE_CPU:
ffff8d461fb2f140
CPU 4 SLAB:
SLAB MEMORY NODE TOTAL ALLOCATED FREE
fffff540dfde3800 ffff8d45f78e0000 0 32 8 24
FREE / [ALLOCATED]
[ffff8d45f78e0000]
ffff8d45f78e0200 (cpu 4 cache)
ffff8d45f78e0400 (cpu 4 cache)
...skipped ...
Signed-off-by: Aaron Tomlin <atomlin@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
help.c | 5 ++++-
memory.c | 37 ++++++++++++++++++++++++++++++++++---
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/help.c b/help.c
index 99be7cb4e17c..6c262a3ffcbb 100644
--- a/help.c
+++ b/help.c
@@ -6601,7 +6601,7 @@ char *help_kmem[] = {
"kmem",
"kernel memory",
"[-f|-F|-c|-C|-i|-v|-V|-n|-z|-o|-h] [-p | -m member[,member]]\n"
-" [[-s|-S|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]",
+" [[-s|-S|-S=cpu[s]|-r] [slab] [-I slab[,slab]]] [-g [flags]] [[-P] address]]",
" This command displays information about the use of kernel memory.\n",
" -f displays the contents of the system free memory headers.",
" also verifies that the page count equals nr_free_pages.",
@@ -6649,6 +6649,9 @@ char *help_kmem[] = {
" slab data for each per-cpu slab is displayed, along with the",
" address of each kmem_cache_node, its count of full and partial",
" slabs, and a list of all tracked slabs.",
+" Note: one can specify the per-cpu slab data to be displayed;",
+" the cpu[s] can be given as \"1,3,5\", \"1-3\", \"1,3,5-7,10\",",
+" \"all\", or \"a\" (shortcut for \"all\").",
" -r displays the accumulated basic kmalloc() slab data of each",
" root slab cache and its children. The kernel must contain the",
" \"slab_root_caches\" list_head. (currently only available if",
diff --git a/memory.c b/memory.c
index cbe90eebe748..ca4c633e5074 100644
--- a/memory.c
+++ b/memory.c
@@ -48,6 +48,7 @@ struct meminfo { /* general purpose memory information structure */
int slab_offset;
char *reqname;
char *curname;
+ ulong *spec_cpumask;
ulong *addrlist;
int *kmem_bufctl;
ulong *cpudata[NR_CPUS];
@@ -4851,10 +4852,13 @@ cmd_kmem(void)
struct meminfo meminfo;
ulonglong value[MAXARGS];
char buf[BUFSIZE];
+ char arg_buf[BUFSIZE];
char *p1;
- int spec_addr, escape;
+ ulong *cpus;
+ int spec_addr, escape, choose_cpu;
- spec_addr = 0;
+ cpus = NULL;
+ spec_addr = choose_cpu = 0;
sflag = Sflag = pflag = fflag = Fflag = Pflag = zflag = oflag = 0;
vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = Vflag = 0;
gflag = hflag = rflag = 0;
@@ -4863,7 +4867,7 @@ cmd_kmem(void)
BZERO(&value[0], sizeof(ulonglong)*MAXARGS);
pc->curcmd_flags &= ~HEADER_PRINTED;
- while ((c = getopt(argcnt, args, "gI:sSrFfm:pvczCinl:L:PVoh")) != EOF) {
+ while ((c = getopt(argcnt, args, "gI:sS::rFfm:pvczCinl:L:PVoh")) != EOF) {
switch(c)
{
case 'V':
@@ -4903,6 +4907,29 @@ cmd_kmem(void)
break;
case 'S':
+ if (choose_cpu)
+ error(FATAL, "only one -S option allowed\n");
+ /* Use the GNU extension with getopt(3) ... */
+ if (optarg) {
+ if (!(vt->flags & KMALLOC_SLUB))
+ error(FATAL,
+ "can only use -S=cpu(s) with a kernel \n"
+ "that is built with CONFIG_SLUB support.\n");
+ if (optarg[0] != '=')
+ error(FATAL,
+ "CPU-specific slab data to be displayed "
+ "must be written as expected only e.g. -S=1,45.\n");
+ /* Skip = ... */
+ optarg++;
+
+ choose_cpu = 1;
+ BZERO(arg_buf, BUFSIZE);
+ strcpy(arg_buf, optarg);
+
+ cpus = get_cpumask_buf();
+ make_cpumask(arg_buf, cpus, FAULT_ON_ERROR, NULL);
+ meminfo.spec_cpumask = cpus;
+ }
Sflag = 1; sflag = rflag = 0;
break;
@@ -5185,6 +5212,8 @@ cmd_kmem(void)
meminfo.flags = VERBOSE;
vt->dump_kmem_cache(&meminfo);
}
+ if (choose_cpu)
+ FREEBUF(cpus);
}
if (vflag == 1)
@@ -19083,6 +19112,8 @@ do_kmem_cache_slub(struct meminfo *si)
per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes);
for (i = 0; i < kt->cpus; i++) {
+ if (si->spec_cpumask && !NUM_IN_BITMAP(si->spec_cpumask, i))
+ continue;
if (hide_offline_cpu(i)) {
fprintf(fp, "CPU %d [OFFLINE]\n", i);
continue;
--
2.30.2

View File

@ -1,151 +0,0 @@
From 2fab8fbc0c4f1c4cbe889de4cead5f7457a19f77 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:11 +0800
Subject: [PATCH 1/9] symbols: Implement install and remove operations for
mod_symname_hash
Currently the sequence for symbol_search to search a symbol is: 1) kernel
symname hash table, 2) iterate all kernel symbols, 3) iterate all kernel
modules and their symbols. In the worst case, if a non-exist symbol been
searched, all 3 stages will be went through. The time consuming status for
each stage is like:
stage 1 stage 2 stage 3
0.007000(ms) 0.593000(ms) 2.421000(ms)
stage 3 takes too much time when comparing to stage 1. This patch series
introduces a symname hash table for kernel modules, to improve the
performance of symbol searching.
Functions symbol_search() and symbol_exists() are fundamental and widely
used by other crash functions, thus the benefit of performance improvement
can get accumulated. For example, "ps -m" and "irq" commands, which call
the functions many times, will become faster with the patch series.
This patch indroduces mod_symname_hash, and its install/remove operations.
Since symbol_search() has to return the lowest address symbol and
symbol_search_next() returns the next lowest symbol, thus the installation
should be sorted ascendingly.
In mod_symname_hash_install_range() scenario, spn are already arranged
ascendingly, so for mod_symname_hash_install():
Install spn previous to sp:
If sp is the start of bucket, or
1) spn->value is smaller than sp->value.
Install spn next to sp:
1) sp->name_hash_next is NULL, or
2) sp->name_hash_next->value is larger than spn->value
spn->value is the kernel address of the symbol and will not change.
So we use it mainly to determine the sequence. When spn->value equals
sp->value, they must be symbols within a kernel module.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
defs.h | 1 +
symbols.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+)
diff --git a/defs.h b/defs.h
index cbd45e52f9da..bbdca799f72d 100644
--- a/defs.h
+++ b/defs.h
@@ -2755,6 +2755,7 @@ struct symbol_table_data {
double val_hash_searches;
double val_hash_iterations;
struct syment *symname_hash[SYMNAME_HASH];
+ struct syment *mod_symname_hash[SYMNAME_HASH];
struct symbol_namespace kernel_namespace;
struct syment *ext_module_symtable;
struct syment *ext_module_symend;
diff --git a/symbols.c b/symbols.c
index 69dccdb09d5f..ad12d1c22225 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1157,6 +1157,79 @@ symname_hash_install(struct syment *spn)
}
}
+/*
+ * Install a single kernel module symbol into the mod_symname_hash.
+ */
+static void
+mod_symname_hash_install(struct syment *spn)
+{
+ struct syment *sp;
+ int index;
+
+ if (!spn)
+ return;
+
+ index = SYMNAME_HASH_INDEX(spn->name);
+
+ sp = st->mod_symname_hash[index];
+
+ if (!sp || (spn->value < sp->value)) {
+ st->mod_symname_hash[index] = spn;
+ spn->name_hash_next = sp;
+ return;
+ }
+ for (; sp; sp = sp->name_hash_next) {
+ if (!sp->name_hash_next ||
+ spn->value < sp->name_hash_next->value) {
+ spn->name_hash_next = sp->name_hash_next;
+ sp->name_hash_next = spn;
+ return;
+ }
+ }
+}
+
+static void
+mod_symname_hash_remove(struct syment *spn)
+{
+ struct syment *sp;
+ int index;
+
+ if (!spn)
+ return;
+
+ index = SYMNAME_HASH_INDEX(spn->name);
+
+ if (st->mod_symname_hash[index] == spn) {
+ st->mod_symname_hash[index] = spn->name_hash_next;
+ return;
+ }
+
+ for (sp = st->mod_symname_hash[index]; sp; sp = sp->name_hash_next) {
+ if (sp->name_hash_next == spn) {
+ sp->name_hash_next = spn->name_hash_next;
+ return;
+ }
+ }
+}
+
+static void
+mod_symtable_hash_install_range(struct syment *from, struct syment *to)
+{
+ struct syment *sp;
+
+ for (sp = from; sp <= to; sp++)
+ mod_symname_hash_install(sp);
+}
+
+static void
+mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
+{
+ struct syment *sp;
+
+ for (sp = from; sp <= to; sp++)
+ mod_symname_hash_remove(sp);
+}
+
/*
* Static kernel symbol value search
*/
--
2.30.2

View File

@ -1,59 +0,0 @@
From 647a5c33e1c94054d7b63168cd6c12901591cb77 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 27 May 2021 18:02:11 +0800
Subject: [PATCH 02/16] Fix for "kmem -s|-S" option on Linux 5.7 and later
kernels
Linux 5.7 and later kernels that contain kernel commit 1ad53d9fa3f6
("slub: improve bit diffusion for freelist ptr obfuscation") changed
the calculation formula in the freelist_ptr(), which added a swab()
call to mix bits a little more. When kernel is configured with the
"CONFIG_SLAB_FREELIST_HARDENED=y", without the patch, the "kmem -s|-S"
options display wrong statistics and state whether slab objects are
in use or free and can print the following errors:
crash> kmem -s
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
87201e00 528 0 0 0 8k xfs_dqtrx
87201f00 496 0 0 0 8k xfs_dquot
kmem: xfs_buf: slab: 37202e6e900 invalid freepointer: b844bab900001d70
kmem: xfs_buf: slab: 3720250fd80 invalid freepointer: b8603f9400001370
...
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index 8c6bbe409922..a3cf8a86728d 100644
--- a/memory.c
+++ b/memory.c
@@ -20,6 +20,7 @@
#include <sys/mman.h>
#include <ctype.h>
#include <netinet/in.h>
+#include <byteswap.h>
struct meminfo { /* general purpose memory information structure */
ulong cache; /* used by the various memory searching/dumping */
@@ -19336,10 +19337,14 @@ count_free_objects(struct meminfo *si, ulong freelist)
static ulong
freelist_ptr(struct meminfo *si, ulong ptr, ulong ptr_addr)
{
- if (VALID_MEMBER(kmem_cache_random))
+ if (VALID_MEMBER(kmem_cache_random)) {
/* CONFIG_SLAB_FREELIST_HARDENED */
+
+ if (THIS_KERNEL_VERSION >= LINUX(5,7,0))
+ ptr_addr = (sizeof(long) == 8) ? bswap_64(ptr_addr)
+ : bswap_32(ptr_addr);
return (ptr ^ si->random ^ ptr_addr);
- else
+ } else
return ptr;
}
--
2.30.2

View File

@ -1,125 +0,0 @@
From 4631320e96f8a63c897fbbce4e87e3c47af40bc9 Mon Sep 17 00:00:00 2001
From: Roman Bolshakov <r.bolshakov@yadro.com>
Date: Thu, 17 Jun 2021 02:27:32 +0300
Subject: [PATCH 02/27] diskdump: Fail readmem() early if dump is incomplete
kdump format description [1] says:
[...] zero page has its own offset not equal 0. So when reading page
from incomplete core, only the page lost by ENOSPACE errors has 0 in its
corresponding page descriptor's member offset.
crash has special treatment for page descriptors with zero offset only if
DUMP_DH_COMPRESSED_INCOMPLETE is set in dump header. However,
makedumpfile places the flag after ENOSPC is hit and only if dump header
modification went without errors.
In case if crashkernel environment was terminated early (e.g. by BMC) or
some other reason, DUMP_DH_COMPRESSED_INCOMPLETE won't be set on the
dump header. Then cache_page() would be performed on pages with
pd.offset == 0 and due to pd.size == 0 it'll skip read into
compressed_page and then non related pre-existing contents of
compressed_page will copied into page cache for the non-present page.
Ultimately, it'll lead to a cryptic failure, like:
crash: invalid kernel virtual address: 72288cacacf427f8 [...]
The failure would be a bit cleaner if crash explicitly fails on the page
that is an outcome of incomplete dump:
crash: page incomplete: kernel virtual address: c000003fff9d17e8 [...]
Debugging level 8 would also produce exact offset from data_offset to
print descriptor value with ease:
read_diskdump/cache_page: descriptor with zero offset found at paddr/pfn/pos: 3fff9d0000/3fff9d/743dd
That helps in inspecting broken descriptor with hexdump or similar tools:
hexdump -s (data_offset + pos * 0x18) -n 0x18
[1] https://github.com/makedumpfile/makedumpfile/blob/master/IMPLEMENTATION
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
---
defs.h | 1 +
diskdump.c | 16 +++++++++++-----
memory.c | 7 +++++++
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index c91177a245fd..eb1c71b5333a 100644
--- a/defs.h
+++ b/defs.h
@@ -361,6 +361,7 @@ struct number_option {
#define READ_ERROR (-2)
#define WRITE_ERROR (-3)
#define PAGE_EXCLUDED (-4)
+#define PAGE_INCOMPLETE (-5)
#define RESTART() (longjmp(pc->main_loop_env, 1))
#define RESUME_FOREACH() (longjmp(pc->foreach_loop_env, 1))
diff --git a/diskdump.c b/diskdump.c
index 668069585080..59b79e1bce95 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1146,10 +1146,9 @@ cache_page(physaddr_t paddr)
if (FLAT_FORMAT()) {
if (!read_flattened_format(dd->dfd, pd.offset, dd->compressed_page, pd.size))
return READ_ERROR;
- } else if (is_incomplete_dump() && (0 == pd.offset)) {
+ } else if (0 == pd.offset) {
/*
- * If the incomplete flag has been set in the header,
- * first check whether zero_excluded has been set.
+ * First check whether zero_excluded has been set.
*/
if (*diskdump_flags & ZERO_EXCLUDED) {
if (CRASHDEBUG(8))
@@ -1158,8 +1157,15 @@ cache_page(physaddr_t paddr)
"paddr/pfn: %llx/%lx\n",
(ulonglong)paddr, pfn);
memset(dd->compressed_page, 0, dd->block_size);
- } else
- return READ_ERROR;
+ } else {
+ if (CRASHDEBUG(8))
+ fprintf(fp,
+ "read_diskdump/cache_page: "
+ "descriptor with zero offset found at "
+ "paddr/pfn/pos: %llx/%lx/%lx\n",
+ (ulonglong)paddr, pfn, desc_pos);
+ return PAGE_INCOMPLETE;
+ }
} else {
if (lseek(dd->dfd, pd.offset, SEEK_SET) == failed)
return SEEK_ERROR;
diff --git a/memory.c b/memory.c
index ca4c633e5074..86c02c132890 100644
--- a/memory.c
+++ b/memory.c
@@ -2213,6 +2213,7 @@ accessible(ulong kva)
#define READ_ERRMSG "read error: %s address: %llx type: \"%s\"\n"
#define WRITE_ERRMSG "write error: %s address: %llx type: \"%s\"\n"
#define PAGE_EXCLUDED_ERRMSG "page excluded: %s address: %llx type: \"%s\"\n"
+#define PAGE_INCOMPLETE_ERRMSG "page incomplete: %s address: %llx type: \"%s\"\n"
#define RETURN_ON_PARTIAL_READ() \
if ((error_handle & RETURN_PARTIAL) && (size < orig_size)) { \
@@ -2378,6 +2379,12 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
error(INFO, PAGE_EXCLUDED_ERRMSG, memtype_string(memtype, 0), addr, type);
goto readmem_error;
+ case PAGE_INCOMPLETE:
+ RETURN_ON_PARTIAL_READ();
+ if (PRINT_ERROR_MESSAGE)
+ error(INFO, PAGE_INCOMPLETE_ERRMSG, memtype_string(memtype, 0), addr, type);
+ goto readmem_error;
+
default:
break;
}
--
2.30.2

View File

@ -1,103 +0,0 @@
From 214f9bf3727c3350401b3f4b4389258c24486e06 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:12 +0800
Subject: [PATCH 2/9] symbols: Integrate symbol_search() with mod_symname_hash
search
This patch introduces mod_symname_hash search to symbol_search(),
to get a better searching performance.
Signed-off-by: Tao Liu <ltao@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
---
symbols.c | 58 ++++++++++++++++++-------------------------------------
1 file changed, 19 insertions(+), 39 deletions(-)
diff --git a/symbols.c b/symbols.c
index ad12d1c22225..c4ad31fe926f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -4551,6 +4551,17 @@ symbol_query(char *s, char *print_pad, struct syment **spp)
return(cnt);
}
+static int
+skip_symbols(struct syment *sp, char *s)
+{
+ int pseudos, skip = FALSE;
+
+ pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_") ||
+ strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
+ if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
+ skip = TRUE;
+ return skip;
+}
/*
* Return the syment of a symbol.
@@ -4558,10 +4569,7 @@ symbol_query(char *s, char *print_pad, struct syment **spp)
struct syment *
symbol_search(char *s)
{
- int i;
- struct syment *sp_hashed, *sp, *sp_end;
- struct load_module *lm;
- int pseudos, search_init;
+ struct syment *sp_hashed, *sp;
sp_hashed = symname_hash_search(s);
@@ -4570,43 +4578,15 @@ symbol_search(char *s)
return(sp);
}
- pseudos = (strstr(s, "_MODULE_START_") || strstr(s, "_MODULE_END_"));
- search_init = FALSE;
-
- for (i = 0; i < st->mods_installed; i++) {
- lm = &st->load_modules[i];
- if (lm->mod_flags & MOD_INIT)
- search_init = TRUE;
- sp = lm->mod_symtable;
- sp_end = lm->mod_symend;
-
- for ( ; sp <= sp_end; sp++) {
- if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
- continue;
- if (STREQ(s, sp->name))
- return(sp);
- }
- }
-
- if (!search_init)
- return((struct syment *)NULL);
-
- pseudos = (strstr(s, "_MODULE_INIT_START_") || strstr(s, "_MODULE_INIT_END_"));
-
- for (i = 0; i < st->mods_installed; i++) {
- lm = &st->load_modules[i];
- if (!lm->mod_init_symtable)
+ sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
+ while (sp) {
+ if (skip_symbols(sp, s)) {
+ sp = sp->name_hash_next;
continue;
- sp = lm->mod_init_symtable;
- sp_end = lm->mod_init_symend;
-
- for ( ; sp < sp_end; sp++) {
- if (!pseudos && MODULE_PSEUDO_SYMBOL(sp))
- continue;
-
- if (STREQ(s, sp->name))
- return(sp);
}
+ if (STREQ(sp->name, s))
+ return sp;
+ sp = sp->name_hash_next;
}
return((struct syment *)NULL);
--
2.30.2

View File

@ -1,102 +0,0 @@
From 0b5435e10161345cf713ed447a155a611a1b408b Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Wed, 26 May 2021 17:33:13 +0900
Subject: [PATCH 03/16] memory: Add support for SECTION_TAINT_ZONE_DEVICE flag
Fix for "kmem -n|-p" options on Linux 5.12-rc1 and later kernels
that contain commit 1f90a3477df3f ("mm: teach pfn_to_online_page()
about ZONE_DEVICE section collisions"). Without the patch, the
"kmem -n" option incorrectly shows mem_map addresses containing the
flag in bit 5 as part of the virtual address, and also the "kmem -p"
option shows page structures at wrong position. With the patch,
the "kmem -n" option displays the new "D" state flag.
Without the patch:
crash> kmem -n
...
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
1040 ffff9edf3ffd4100 ffffe2bcc0000010 ffffe2bd42000010 PMOE 34078720
^ ^
crash> kmem -p
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffe2bd42000010 2080000000 400040 1ffffffff 9961471 dead000000000122 referenced,active,error
ffffe2bd42000050 2080001000 800080 1ffffffff 9961471 dead000000000122 referenced,active,error
ffffe2bd42000090 2080002000 0 1ffffffff 9961471 dead000000000122 referenced,active,error
^^
With the patch:
crash> kmem -n
...
NR SECTION CODED_MEM_MAP MEM_MAP STATE PFN
1040 ffff9edf3ffd4100 ffffe2bcc0000000 ffffe2bd42000000 PMOED 34078720
crash> kmem -p
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffe2bd42000000 2080000000 ffff9ebfc0044100 0 1 97ffffc0000200 slab
ffffe2bd42000040 2080001000 ffff9ebfc0044400 0 1 97ffffc0000200 slab
ffffe2bd42000080 2080002000 0 0 1 97ffffc0000000
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
help.c | 11 +++++++----
memory.c | 15 +++++++++------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/help.c b/help.c
index e0c84087add3..9649cc81fa36 100644
--- a/help.c
+++ b/help.c
@@ -6584,10 +6584,13 @@ char *help_kmem[] = {
" kernels, the vm_zone_stat, vm_node_stat and vm_numa_stat tables,",
" the cumulative page_states counter values if they exist, and/or ",
" the cumulative, vm_event_states counter values if they exist.",
-" -n display memory node, memory section, and memory block data",
-" and state; the state of each memory section state is encoded",
-" as \"P\", \"M\", \"O\" and/or \"E\", meaning SECTION_MARKED_PRESENT,",
-" SECTION_HAS_MEM_MAP, SECTION_IS_ONLINE and SECTION_IS_EARLY.",
+" -n display memory node, memory section, memory block data and state;",
+" the state of each memory section is shown as the following flags:",
+" \"P\": SECTION_MARKED_PRESENT",
+" \"M\": SECTION_HAS_MEM_MAP",
+" \"O\": SECTION_IS_ONLINE",
+" \"E\": SECTION_IS_EARLY",
+" \"D\": SECTION_TAINT_ZONE_DEVICE",
" -z displays per-zone memory statistics.",
" -o displays each cpu's offset value that is added to per-cpu symbol",
" values to translate them into kernel virtual addresses.",
diff --git a/memory.c b/memory.c
index a3cf8a86728d..2c4f9790f498 100644
--- a/memory.c
+++ b/memory.c
@@ -17270,12 +17270,13 @@ nr_to_section(ulong nr)
* which results in PFN_SECTION_SHIFT equal 6.
* To sum it up, at least 6 bits are available.
*/
-#define SECTION_MARKED_PRESENT (1UL<<0)
-#define SECTION_HAS_MEM_MAP (1UL<<1)
-#define SECTION_IS_ONLINE (1UL<<2)
-#define SECTION_IS_EARLY (1UL<<3)
-#define SECTION_MAP_LAST_BIT (1UL<<4)
-#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
+#define SECTION_MARKED_PRESENT (1UL<<0)
+#define SECTION_HAS_MEM_MAP (1UL<<1)
+#define SECTION_IS_ONLINE (1UL<<2)
+#define SECTION_IS_EARLY (1UL<<3)
+#define SECTION_TAINT_ZONE_DEVICE (1UL<<4)
+#define SECTION_MAP_LAST_BIT (1UL<<5)
+#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
int
@@ -17373,6 +17374,8 @@ fill_mem_section_state(ulong state, char *buf)
bufidx += sprintf(buf + bufidx, "%s", "O");
if (state & SECTION_IS_EARLY)
bufidx += sprintf(buf + bufidx, "%s", "E");
+ if (state & SECTION_TAINT_ZONE_DEVICE)
+ bufidx += sprintf(buf + bufidx, "%s", "D");
}
void
--
2.30.2

View File

@ -1,36 +0,0 @@
From 41cda195c6421fbde72ed67b32b8c1ab3eb0c56f Mon Sep 17 00:00:00 2001
From: Roman Bolshakov <r.bolshakov@yadro.com>
Date: Thu, 17 Jun 2021 02:27:33 +0300
Subject: [PATCH 03/27] netdump: Permit --zero_excluded for incomplete ELF
dumps
DUMP_ELF_INCOMPLETE is set very late after ENOSPC error is hit by
makedumpfile. Any following error that prevents modification of ELF
header would result in effectively incomplete core that doesn't have the
flag. zero_excluded flag doesn't work for such kind of incomplete core.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
---
netdump.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/netdump.c b/netdump.c
index aaea945aaca7..e8721d89f1a3 100644
--- a/netdump.c
+++ b/netdump.c
@@ -819,10 +819,9 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
read_ret = read(nd->ndfd, bufptr, cnt);
if (read_ret != cnt) {
/*
- * If the incomplete flag has been set in the header,
- * first check whether zero_excluded has been set.
+ * First check whether zero_excluded has been set.
*/
- if (is_incomplete_dump() && (read_ret >= 0) &&
+ if ((read_ret >= 0) &&
(*diskdump_flags & ZERO_EXCLUDED)) {
if (CRASHDEBUG(8))
fprintf(fp, "read_netdump: zero-fill: "
--
2.30.2

View File

@ -1,82 +0,0 @@
From 340c6ad1a0a7ce76eb5d9397833bfc6a049e2b3b Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:13 +0800
Subject: [PATCH 3/9] symbols: Extend symname_hash_search() with hash table
select
Previously symname_hash_search() can only search symbols from kernel's
symname_hash. This patch add hash table pointer as parameter for
symname_hash_search(). Thus symname_hash_search() can be used both for
symname_hash and mod_symname_hash searching.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
symbols.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/symbols.c b/symbols.c
index c4ad31fe926f..83393f09270d 100644
--- a/symbols.c
+++ b/symbols.c
@@ -65,7 +65,7 @@ static void symval_hash_init(void);
static struct syment *symval_hash_search(ulong);
static void symname_hash_init(void);
static void symname_hash_install(struct syment *);
-static struct syment *symname_hash_search(char *);
+static struct syment *symname_hash_search(struct syment *[], char *);
static void gnu_qsort(bfd *, void *, long, unsigned int, asymbol *, asymbol *);
static int check_gnu_debuglink(bfd *);
static int separate_debug_file_exists(const char *, unsigned long, int *);
@@ -1234,11 +1234,11 @@ mod_symtable_hash_remove_range(struct syment *from, struct syment *to)
* Static kernel symbol value search
*/
static struct syment *
-symname_hash_search(char *name)
+symname_hash_search(struct syment *table[], char *name)
{
struct syment *sp;
- sp = st->symname_hash[SYMNAME_HASH_INDEX(name)];
+ sp = table[SYMNAME_HASH_INDEX(name)];
while (sp) {
if (STREQ(sp->name, name))
@@ -4571,7 +4571,7 @@ symbol_search(char *s)
{
struct syment *sp_hashed, *sp;
- sp_hashed = symname_hash_search(s);
+ sp_hashed = symname_hash_search(st->symname_hash, s);
for (sp = sp_hashed ? sp_hashed : st->symtable; sp < st->symend; sp++) {
if (STREQ(s, sp->name))
@@ -5485,7 +5485,7 @@ symbol_exists(char *symbol)
struct syment *sp, *sp_end;
struct load_module *lm;
- if ((sp = symname_hash_search(symbol)))
+ if ((sp = symname_hash_search(st->symname_hash, symbol)))
return TRUE;
for (i = 0; i < st->mods_installed; i++) {
@@ -5564,7 +5564,7 @@ kernel_symbol_exists(char *symbol)
{
struct syment *sp;
- if ((sp = symname_hash_search(symbol)))
+ if ((sp = symname_hash_search(st->symname_hash, symbol)))
return TRUE;
else
return FALSE;
@@ -5576,7 +5576,7 @@ kernel_symbol_exists(char *symbol)
struct syment *
kernel_symbol_search(char *symbol)
{
- return symname_hash_search(symbol);
+ return symname_hash_search(st->symname_hash, symbol);
}
/*
--
2.30.2

View File

@ -1,52 +0,0 @@
From 1425b0504b1e79d88a2d188d7e4c0e7fceba4501 Mon Sep 17 00:00:00 2001
From: Roman Bolshakov <r.bolshakov@yadro.com>
Date: Thu, 17 Jun 2021 02:27:34 +0300
Subject: [PATCH 04/27] diskdump: Print total number of dumpable pages
It's not clear how broken an incomplete dump from the existing debugging
prints. Aggregate number of valid pages helps to figure out approximate
size of the dump. Size of a complete dump is roughly:
EXPECTED_CORE_SIZE = a few pages (kdump headers + bitmaps + descriptors) +
(total_valid_pages * block_size) * compression rate
An incomplete core would be significantly smaller than:
total_valid_pages * block_size
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
---
diskdump.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/diskdump.c b/diskdump.c
index 59b79e1bce95..0f9402248d51 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -74,6 +74,7 @@ struct diskdump_data {
ulong evictions; /* total evictions done */
ulong cached_reads;
ulong *valid_pages;
+ int max_sect_len; /* highest bucket of valid_pages */
ulong accesses;
ulong snapshot_task;
};
@@ -877,6 +878,7 @@ restart:
}
dd->valid_pages = calloc(sizeof(ulong), max_sect_len + 1);
+ dd->max_sect_len = max_sect_len;
for (i = 1; i < max_sect_len + 1; i++) {
dd->valid_pages[i] = dd->valid_pages[i - 1];
for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
@@ -2089,6 +2091,7 @@ __diskdump_memory_dump(FILE *fp)
else
fprintf(fp, "\n");
fprintf(fp, " valid_pages: %lx\n", (ulong)dd->valid_pages);
+ fprintf(fp, " total_valid_pages: %ld\n", dd->valid_pages[dd->max_sect_len]);
return 0;
}
--
2.30.2

View File

@ -1,50 +0,0 @@
From ec44b902d3467e7b86ee39e2d7d472b9cb202148 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 31 May 2021 14:08:28 +0900
Subject: [PATCH 04/16] memory: Fix for "kmem -n" option to display NID
correctly
The nid member of struct memory_block is a 4-byte integer, but read
and printed as a 8-byte integer on 64-bit machines. Without the
patch, the option displays wrong NIDs.
crash> kmem -n
...
MEM_BLOCK NAME PHYSICAL RANGE NODE STATE START_SECTION_NO
ffff9edeff2b9400 memory0 0 - 7fffffff 14195095130662240256 ONLINE 0
ffff9edeff2bb400 memory2 100000000 - 17fffffff 14195094718345379840 ONLINE 32
The issue seems to appear on Linux 5.12 and later kernels that contain
commit e9a2e48e8704c ("drivers/base/memory: don't store phys_device
in memory blocks"), which changed the arrangement of the members of
struct memory_block.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
memory.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/memory.c b/memory.c
index 2c4f9790f498..cbe90eebe748 100644
--- a/memory.c
+++ b/memory.c
@@ -17568,13 +17568,13 @@ print_memory_block(ulong memory_block)
if (MEMBER_EXISTS("memory_block", "nid")) {
readmem(memory_block + OFFSET(memory_block_nid), KVADDR, &nid,
- sizeof(void *), "memory_block nid", FAULT_ON_ERROR);
+ sizeof(int), "memory_block nid", FAULT_ON_ERROR);
fprintf(fp, " %s %s %s %s %s %s\n",
mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
MKSTR(memory_block)),
mkstring(buf2, 12, CENTER, name),
parangebuf,
- mkstring(buf5, strlen("NODE"), CENTER|LONG_DEC,
+ mkstring(buf5, strlen("NODE"), CENTER|INT_DEC,
MKSTR(nid)),
mkstring(buf6, strlen("OFFLINE"), LJUST,
statebuf),
--
2.30.2

View File

@ -1,74 +0,0 @@
From f3bee9375ed32b85e7f81a5e46a0040620553ae0 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:14 +0800
Subject: [PATCH 4/9] symbols: Intergrate symbol_exists() with mod_symname_hash
search
This patch introduces mod_symname_hash search to symbol_exists()
to improve its performance. And code refactoring for
kernel_symbol_exists().
Signed-off-by: Tao Liu <ltao@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
---
symbols.c | 35 ++++-------------------------------
1 file changed, 4 insertions(+), 31 deletions(-)
diff --git a/symbols.c b/symbols.c
index 83393f09270d..8d3dd95f737b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -5481,33 +5481,11 @@ value_symbol(ulong value)
int
symbol_exists(char *symbol)
{
- int i;
- struct syment *sp, *sp_end;
- struct load_module *lm;
-
- if ((sp = symname_hash_search(st->symname_hash, symbol)))
+ if (symname_hash_search(st->symname_hash, symbol))
return TRUE;
- for (i = 0; i < st->mods_installed; i++) {
- lm = &st->load_modules[i];
- sp = lm->mod_symtable;
- sp_end = lm->mod_symend;
-
- for ( ; sp < sp_end; sp++) {
- if (STREQ(symbol, sp->name))
- return(TRUE);
- }
-
- if (lm->mod_init_symtable) {
- sp = lm->mod_init_symtable;
- sp_end = lm->mod_init_symend;
-
- for ( ; sp < sp_end; sp++) {
- if (STREQ(symbol, sp->name))
- return(TRUE);
- }
- }
- }
+ if (symname_hash_search(st->mod_symname_hash, symbol))
+ return TRUE;
return(FALSE);
}
@@ -5562,12 +5540,7 @@ per_cpu_symbol_search(char *symbol)
int
kernel_symbol_exists(char *symbol)
{
- struct syment *sp;
-
- if ((sp = symname_hash_search(st->symname_hash, symbol)))
- return TRUE;
- else
- return FALSE;
+ return !!symname_hash_search(st->symname_hash, symbol);
}
/*
--
2.30.2

View File

@ -1,103 +0,0 @@
From 704623dfde43da98ffb354b3d7f450cd012a8215 Mon Sep 17 00:00:00 2001
From: Youling Tang <tangyouling@loongson.cn>
Date: Thu, 3 Jun 2021 16:07:41 +0800
Subject: [PATCH 05/16] defs.h: Fix the value of TIF_SIGPENDING macro
Correct the change of the value of TIF_SIGPENDING macro between
different kernel versions.
TIF_SIGPENDING changes with the kernel version as follows:
ARM 2 -> 0 at v2.6.23
MIPS 2 -> 1 at v2.6.23
MIPS64 2 -> 1 at v2.6.23
PPC 2 -> 1 at v2.6.23
IA64 1 -> 0 at v2.6.23
PPC64 2 -> 1 at v2.6.23
S390 2 -> 1 at v3.16
S390X 2 -> 1 at v3.16
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/defs.h b/defs.h
index 396d61aaf532..3502c6d6e90c 100644
--- a/defs.h
+++ b/defs.h
@@ -2997,7 +2997,7 @@ typedef struct QEMUCPUState QEMUCPUState;
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 0 : 2)
#define _SECTION_SIZE_BITS 28
#define _MAX_PHYSMEM_BITS 32
@@ -3377,7 +3377,7 @@ struct arm64_stackframe {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define _SECTION_SIZE_BITS 26
#define _MAX_PHYSMEM_BITS 32
@@ -3416,7 +3416,7 @@ struct arm64_stackframe {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define _SECTION_SIZE_BITS 28
#define _MAX_PHYSMEM_BITS 48
@@ -3884,7 +3884,7 @@ struct machine_specific {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define _SECTION_SIZE_BITS 24
#define _MAX_PHYSMEM_BITS 44
@@ -4079,7 +4079,7 @@ struct efi_memory_desc_t {
#define __swp_type(entry) ((entry >> 2) & 0x7f)
#define __swp_offset(entry) ((entry << 1) >> 10)
-#define TIF_SIGPENDING (1)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 0 : 1)
#define KERNEL_TR_PAGE_SIZE (1 << _PAGE_SIZE_64M)
#define KERNEL_TR_PAGE_MASK (~(KERNEL_TR_PAGE_SIZE - 1))
@@ -4219,7 +4219,7 @@ struct efi_memory_desc_t {
#define PTE_RPN_MASK (machdep->machspec->pte_rpn_mask)
#define PTE_RPN_SHIFT (machdep->machspec->pte_rpn_shift)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(2,6,23) ? 1 : 2)
#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
#define SWP_OFFSET(entry) ((entry) >> 8)
@@ -4259,7 +4259,7 @@ struct efi_memory_desc_t {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(3,16,0) ? 1 : 2)
#define _SECTION_SIZE_BITS 25
#define _MAX_PHYSMEM_BITS 31
@@ -4284,7 +4284,7 @@ struct efi_memory_desc_t {
#define __swp_type(entry) SWP_TYPE(entry)
#define __swp_offset(entry) SWP_OFFSET(entry)
-#define TIF_SIGPENDING (2)
+#define TIF_SIGPENDING (THIS_KERNEL_VERSION >= LINUX(3,16,0) ? 1 : 2)
#define _SECTION_SIZE_BITS 28
#define _MAX_PHYSMEM_BITS_OLD 42
--
2.30.2

View File

@ -1,67 +0,0 @@
From 881f33d97cee9895796829d0cc969b51dd34d831 Mon Sep 17 00:00:00 2001
From: Roman Bolshakov <r.bolshakov@yadro.com>
Date: Thu, 17 Jun 2021 02:27:35 +0300
Subject: [PATCH 05/27] diskdump: Introduce read_pd()
Standalone function for reading of page descriptors is needed later for
of expected core size and detection of incomplete dumps.
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
---
diskdump.c | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index 0f9402248d51..de3eeb2c720c 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -510,6 +510,27 @@ arm_kdump_header_adjust(int header_version)
}
#endif /* __i386__ && (ARM || MIPS) */
+/*
+ * Read page descriptor.
+ */
+static int
+read_pd(int fd, off_t offset, page_desc_t *pd)
+{
+ const off_t failed = (off_t)-1;
+
+ if (FLAT_FORMAT()) {
+ if (!read_flattened_format(fd, offset, pd, sizeof(*pd)))
+ return READ_ERROR;
+ } else {
+ if (lseek(fd, offset, SEEK_SET) == failed)
+ return SEEK_ERROR;
+ if (read(fd, pd, sizeof(*pd)) != sizeof(*pd))
+ return READ_ERROR;
+ }
+
+ return 0;
+}
+
static int
read_dump_header(char *file)
{
@@ -1130,15 +1151,9 @@ cache_page(physaddr_t paddr)
+ (off_t)(desc_pos - 1)*sizeof(page_desc_t);
/* read page descriptor */
- if (FLAT_FORMAT()) {
- if (!read_flattened_format(dd->dfd, seek_offset, &pd, sizeof(pd)))
- return READ_ERROR;
- } else {
- if (lseek(dd->dfd, seek_offset, SEEK_SET) == failed)
- return SEEK_ERROR;
- if (read(dd->dfd, &pd, sizeof(pd)) != sizeof(pd))
- return READ_ERROR;
- }
+ ret = read_pd(dd->dfd, seek_offset, &pd);
+ if (ret)
+ return ret;
/* sanity check */
if (pd.size > block_size)
--
2.30.2

View File

@ -1,92 +0,0 @@
From 1e23335dab6bf9f6219a23bf0be4ad9f433f4f43 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:15 +0800
Subject: [PATCH 5/9] symbols: Sync module symbols into mod_symtable whenever
module symbols change
Signed-off-by: Tao Liu <ltao@redhat.com>
Reviewed-by: Philipp Rudo <prudo@redhat.com>
---
kernel.c | 1 +
symbols.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/kernel.c b/kernel.c
index 3ead4bbb172e..f10b8b216571 100644
--- a/kernel.c
+++ b/kernel.c
@@ -4661,6 +4661,7 @@ reinit_modules(void)
st->ext_module_symtable = NULL;
st->load_modules = NULL;
kt->mods_installed = 0;
+ memset(st->mod_symname_hash, 0, sizeof(st->mod_symname_hash));
module_init();
}
diff --git a/symbols.c b/symbols.c
index 8d3dd95f737b..5603a2efd61f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1668,6 +1668,7 @@ store_module_symbols_v1(ulong total, int mods_installed)
lm->mod_symend = sp;
}
}
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
}
st->flags |= MODULE_SYMS;
@@ -2148,6 +2149,8 @@ store_module_symbols_v2(ulong total, int mods_installed)
lm->mod_init_symend = sp;
}
}
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
+ mod_symtable_hash_install_range(lm->mod_init_symtable, lm->mod_init_symend);
}
st->flags |= MODULE_SYMS;
@@ -12478,8 +12481,10 @@ store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms,
error(INFO, "%s: last symbol: %s is not _MODULE_END_%s?\n",
lm->mod_name, lm->mod_load_symend->name, lm->mod_name);
+ mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
lm->mod_symtable = lm->mod_load_symtable;
lm->mod_symend = lm->mod_load_symend;
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
lm->mod_flags &= ~MOD_EXT_SYMS;
lm->mod_flags |= MOD_LOAD_SYMS;
@@ -12509,6 +12514,7 @@ delete_load_module(ulong base_addr)
req->name = lm->mod_namelist;
gdb_interface(req);
}
+ mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
if (lm->mod_load_symtable) {
free(lm->mod_load_symtable);
namespace_ctl(NAMESPACE_FREE,
@@ -12518,6 +12524,7 @@ delete_load_module(ulong base_addr)
unlink_module(lm);
lm->mod_symtable = lm->mod_ext_symtable;
lm->mod_symend = lm->mod_ext_symend;
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
lm->mod_flags |= MOD_EXT_SYMS;
lm->mod_load_symtable = NULL;
@@ -12546,6 +12553,7 @@ delete_load_module(ulong base_addr)
req->name = lm->mod_namelist;
gdb_interface(req);
}
+ mod_symtable_hash_remove_range(lm->mod_symtable, lm->mod_symend);
if (lm->mod_load_symtable) {
free(lm->mod_load_symtable);
namespace_ctl(NAMESPACE_FREE,
@@ -12555,6 +12563,7 @@ delete_load_module(ulong base_addr)
unlink_module(lm);
lm->mod_symtable = lm->mod_ext_symtable;
lm->mod_symend = lm->mod_ext_symend;
+ mod_symtable_hash_install_range(lm->mod_symtable, lm->mod_symend);
lm->mod_flags &= ~(MOD_LOAD_SYMS|MOD_REMOTE|MOD_NOPATCH);
lm->mod_flags |= MOD_EXT_SYMS;
lm->mod_load_symtable = NULL;
--
2.30.2

View File

@ -1,81 +0,0 @@
From 859d1c0e8a6618634cbc1fe7ee2b082a6a3c99a1 Mon Sep 17 00:00:00 2001
From: Youling Tang <tangyouling@loongson.cn>
Date: Fri, 23 Apr 2021 15:40:41 +0800
Subject: [PATCH 06/16] MIPS32/64: Add 'irq' command support
Add support for the 'irq' series of commands in the MIPS32/64
architecture, except for the 'irq -d' command, others can be
used. Without the patch, the 'irq' command fails as follows:
irq: cannot determine number of IRQs
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
mips.c | 10 ++++++++--
mips64.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/mips.c b/mips.c
index f73dfaddf34e..d6602e3c2b0e 100644
--- a/mips.c
+++ b/mips.c
@@ -1126,8 +1126,14 @@ mips_init(int when)
machdep->get_irq_affinity = generic_get_irq_affinity;
machdep->section_size_bits = _SECTION_SIZE_BITS;
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
- ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
- "irq_desc", NULL, 0);
+
+ if (symbol_exists("irq_desc"))
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
+ "irq_desc", NULL, 0);
+ else if (kernel_symbol_exists("nr_irqs"))
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
+ &machdep->nr_irqs);
+
mips_stackframe_init();
if (!machdep->hz)
diff --git a/mips64.c b/mips64.c
index 62ed799f479a..b1d6acfbd609 100644
--- a/mips64.c
+++ b/mips64.c
@@ -1160,6 +1160,9 @@ mips64_dump_machdep_table(ulong arg)
fprintf(fp, " is_task_addr: mips64_is_task_addr()\n");
fprintf(fp, " verify_symbol: mips64_verify_symbol()\n");
fprintf(fp, " dis_filter: generic_dis_filter()\n");
+ fprintf(fp, " dump_irq: generic_dump_irq()\n");
+ fprintf(fp, " show_interrupts: generic_show_interrupts()\n");
+ fprintf(fp, " get_irq_affinity: generic_get_irq_affinity()\n");
fprintf(fp, " cmd_mach: mips64_cmd_mach()\n");
fprintf(fp, " get_smp_cpus: mips64_get_smp_cpus()\n");
fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n");
@@ -1246,6 +1249,9 @@ mips64_init(int when)
machdep->is_task_addr = mips64_is_task_addr;
machdep->get_smp_cpus = mips64_get_smp_cpus;
machdep->dis_filter = generic_dis_filter;
+ machdep->dump_irq = generic_dump_irq;
+ machdep->show_interrupts = generic_show_interrupts;
+ machdep->get_irq_affinity = generic_get_irq_affinity;
machdep->value_to_symbol = generic_machdep_value_to_symbol;
machdep->init_kernel_pgd = NULL;
break;
@@ -1257,6 +1263,14 @@ mips64_init(int when)
mips64_stackframe_init();
if (!machdep->hz)
machdep->hz = 250;
+
+ if (symbol_exists("irq_desc"))
+ ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc,
+ "irq_desc", NULL, 0);
+ else if (kernel_symbol_exists("nr_irqs"))
+ get_symbol_data("nr_irqs", sizeof(unsigned int),
+ &machdep->nr_irqs);
+
MEMBER_OFFSET_INIT(elf_prstatus_pr_reg, "elf_prstatus",
"pr_reg");
STRUCT_SIZE_INIT(note_buf, "note_buf_t");
--
2.30.2

View File

@ -1,121 +0,0 @@
From df0049d12b2ced1b6ff7350ee3c0ca28c3f7cd52 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:16 +0800
Subject: [PATCH 6/9] symbols: Refactor SYMNAME_HASH_INDEX macro to be a
function
SYMNAME_HASH_INDEX is used as the index of symname hash table. It will
be out of range if SYMNAME_HASH_INDEX is negative. This patch avoids
the risk by changing the marco into a function, and casting and calculating
the numbers as unsigned.
Suggested-by: Lianbo Jiang <lijiang@redhat.com>
Suggested-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
---
defs.h | 2 --
symbols.c | 31 +++++++++++++++++++++++--------
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/defs.h b/defs.h
index bbdca799f72d..8b356d5e8959 100644
--- a/defs.h
+++ b/defs.h
@@ -2728,8 +2728,6 @@ struct downsized {
(((vaddr) >> machdep->pageshift) % SYMVAL_HASH)
#define SYMNAME_HASH (512)
-#define SYMNAME_HASH_INDEX(name) \
- ((name[0] ^ (name[strlen(name)-1] * name[strlen(name)/2])) % SYMNAME_HASH)
#define PATCH_KERNEL_SYMBOLS_START ((char *)(1))
#define PATCH_KERNEL_SYMBOLS_STOP ((char *)(2))
diff --git a/symbols.c b/symbols.c
index 5603a2efd61f..67b701454563 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1127,6 +1127,21 @@ symname_hash_init(void)
st->__per_cpu_end = sp->value;
}
+static unsigned int
+symname_hash_index(char *name)
+{
+ unsigned int len, value;
+ unsigned char *array = (unsigned char *)name;
+
+ len = strlen(name);
+ if (!len)
+ error(FATAL, "The length of the symbol name is zero!\n");
+
+ value = array[len - 1] * array[len / 2];
+
+ return (array[0] ^ value) % SYMNAME_HASH;
+}
+
/*
* Install a single static kernel symbol into the symname_hash.
*/
@@ -1134,9 +1149,9 @@ static void
symname_hash_install(struct syment *spn)
{
struct syment *sp;
- int index;
+ unsigned int index;
- index = SYMNAME_HASH_INDEX(spn->name);
+ index = symname_hash_index(spn->name);
spn->cnt = 1;
if ((sp = st->symname_hash[index]) == NULL)
@@ -1164,12 +1179,12 @@ static void
mod_symname_hash_install(struct syment *spn)
{
struct syment *sp;
- int index;
+ unsigned int index;
if (!spn)
return;
- index = SYMNAME_HASH_INDEX(spn->name);
+ index = symname_hash_index(spn->name);
sp = st->mod_symname_hash[index];
@@ -1192,12 +1207,12 @@ static void
mod_symname_hash_remove(struct syment *spn)
{
struct syment *sp;
- int index;
+ unsigned int index;
if (!spn)
return;
- index = SYMNAME_HASH_INDEX(spn->name);
+ index = symname_hash_index(spn->name);
if (st->mod_symname_hash[index] == spn) {
st->mod_symname_hash[index] = spn->name_hash_next;
@@ -1238,7 +1253,7 @@ symname_hash_search(struct syment *table[], char *name)
{
struct syment *sp;
- sp = table[SYMNAME_HASH_INDEX(name)];
+ sp = table[symname_hash_index(name)];
while (sp) {
if (STREQ(sp->name, name))
@@ -4581,7 +4596,7 @@ symbol_search(char *s)
return(sp);
}
- sp = st->mod_symname_hash[SYMNAME_HASH_INDEX(s)];
+ sp = st->mod_symname_hash[symname_hash_index(s)];
while (sp) {
if (skip_symbols(sp, s)) {
sp = sp->name_hash_next;
--
2.30.2

View File

@ -1,66 +0,0 @@
From 44e5801d9016987b6b4ebd571bfde8ae3e75da7b Mon Sep 17 00:00:00 2001
From: Philipp Rudo <prudo@redhat.com>
Date: Thu, 5 Aug 2021 15:19:37 +0200
Subject: [PATCH 06/27] x86_64: Fix check for __per_cpu_offset initialization
Since at least kernel v2.6.30 the __per_cpu_offset gets initialized to
__per_cpu_load. So first check if the __per_cpu_offset was set to a
proper value before reading any per cpu variable to prevent potential
bugs.
[ kh: added check for the existence of __per_cpu_load ]
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
x86_64.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/x86_64.c b/x86_64.c
index 6eb7d6708db0..87cbeaeb4f06 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1285,6 +1285,7 @@ x86_64_per_cpu_init(void)
struct machine_specific *ms;
struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp;
ulong hardirq_stack_ptr;
+ ulong __per_cpu_load = 0;
ms = machdep->machspec;
@@ -1326,7 +1327,12 @@ x86_64_per_cpu_init(void)
else if (!ms->stkinfo.isize)
ms->stkinfo.isize = 16384;
+ if (kernel_symbol_exists("__per_cpu_load"))
+ __per_cpu_load = symbol_value("__per_cpu_load");
+
for (i = cpus = 0; i < NR_CPUS; i++) {
+ if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
+ break;
if (!readmem(cpu_sp->value + kt->__per_cpu_offset[i],
KVADDR, &cpunumber, sizeof(int),
"cpu number (per_cpu)", QUIET|RETURN_ON_ERROR))
@@ -5595,14 +5601,18 @@ x86_64_get_smp_cpus(void)
char *cpu_pda_buf;
ulong level4_pgt, cpu_pda_addr;
struct syment *sp;
+ ulong __per_cpu_load = 0;
if (!VALID_STRUCT(x8664_pda)) {
if (!(sp = per_cpu_symbol_search("per_cpu__cpu_number")) ||
!(kt->flags & PER_CPU_OFF))
return 1;
+ if (kernel_symbol_exists("__per_cpu_load"))
+ __per_cpu_load = symbol_value("__per_cpu_load");
+
for (i = cpus = 0; i < NR_CPUS; i++) {
- if (kt->__per_cpu_offset[i] == 0)
+ if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load)
break;
if (!readmem(sp->value + kt->__per_cpu_offset[i],
KVADDR, &cpunumber, sizeof(int),
--
2.30.2

View File

@ -1,67 +0,0 @@
From c15a1e025e62134094ba0ac600263d75673d5a22 Mon Sep 17 00:00:00 2001
From: Youling Tang <tangyouling@loongson.cn>
Date: Fri, 23 Apr 2021 15:42:11 +0800
Subject: [PATCH 07/16] MIPS64: three fixes for MIPS64 kernels
Three fixes for MIPS64 kernels:
(1) To support ramdumps, add the machine_type() check for MIPS64 in
ramdump_to_elf().
(2) To fix a stuck issue when invoking crash with "-d1" or larger
debug value, add the machine_type() check to get the correct
dump NOTE offsets.
(3) Fix the reference file path to the definition of the pt_regs
structure, to which mips64_regster refers.
[ kh: merged three patches into one ]
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 +-
diskdump.c | 2 +-
ramdump.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/defs.h b/defs.h
index 3502c6d6e90c..148b03e14455 100644
--- a/defs.h
+++ b/defs.h
@@ -6488,7 +6488,7 @@ void mips64_dump_machdep_table(ulong);
#define display_idt_table() \
error(FATAL, "-d option is not applicable to MIPS64 architecture\n")
-/* from arch/mips/include/uapi/asm/ptrace.h */
+/* from arch/mips/include/asm/ptrace.h */
struct mips64_register {
ulong regs[45];
};
diff --git a/diskdump.c b/diskdump.c
index 3effb52771c6..668069585080 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1700,7 +1700,7 @@ dump_note_offsets(FILE *fp)
qemu = FALSE;
if (machine_type("X86_64") || machine_type("S390X") ||
machine_type("ARM64") || machine_type("PPC64") ||
- machine_type("SPARC64")) {
+ machine_type("SPARC64") || machine_type("MIPS64")) {
note64 = (void *)dd->notes_buf + tot;
len = sizeof(Elf64_Nhdr);
if (STRNEQ((char *)note64 + len, "QEMU"))
diff --git a/ramdump.c b/ramdump.c
index 4c4a920a8281..a206fcbbab3c 100644
--- a/ramdump.c
+++ b/ramdump.c
@@ -184,7 +184,7 @@ char *ramdump_to_elf(void)
e_machine = EM_ARM;
else if (machine_type("ARM64"))
e_machine = EM_AARCH64;
- else if (machine_type("MIPS"))
+ else if (machine_type("MIPS") || machine_type("MIPS64"))
e_machine = EM_MIPS;
else if (machine_type("X86_64"))
e_machine = EM_X86_64;
--
2.30.2

View File

@ -1,77 +0,0 @@
From 4b34197508578bb43639e6d169fb91fb0489fa2b Mon Sep 17 00:00:00 2001
From: James Hsu <james.hsu@mediatek.com>
Date: Wed, 18 Aug 2021 15:45:47 +0800
Subject: [PATCH 07/27] arm64: Get CPU registers from ELF notes even without
crash_notes symbol
Currently arm64 crash retrieves the CPU registers from crash_notes symbol
or ELF notes only when the symbol exists, but there are dumpfiles which
have the registers in ELF notes without the symbol.
With the patch, crash can retrieve the registers from ELF notes without
the crash_notes symbol.
Signed-off-by: James Hsu <james.hsu@mediatek.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
arm64.c | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index d73d5c5a4fed..7069312671cf 100644
--- a/arm64.c
+++ b/arm64.c
@@ -3698,14 +3698,48 @@ arm64_get_crash_notes(void)
{
struct machine_specific *ms = machdep->machspec;
ulong crash_notes;
- Elf64_Nhdr *note;
+ Elf64_Nhdr *note = NULL;
ulong offset;
char *buf, *p;
ulong *notes_ptrs;
ulong i, found;
- if (!symbol_exists("crash_notes"))
+ if (!symbol_exists("crash_notes")) {
+ if (DISKDUMP_DUMPFILE() || KDUMP_DUMPFILE()) {
+ 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 = found = 0; i < kt->cpus; i++) {
+ if (DISKDUMP_DUMPFILE())
+ note = diskdump_get_prstatus_percpu(i);
+ else if (KDUMP_DUMPFILE())
+ note = netdump_get_prstatus_percpu(i);
+
+ if (!note) {
+ error(WARNING, "cpu %d: cannot find NT_PRSTATUS note\n", i);
+ continue;
+ }
+
+ /*
+ * Find correct location of note data. This contains elf_prstatus
+ * structure which has registers etc. for the crashed task.
+ */
+ offset = sizeof(Elf64_Nhdr);
+ offset = roundup(offset + note->n_namesz, 4);
+ p = (char *)note + offset; /* start of elf_prstatus */
+
+ BCOPY(p + OFFSET(elf_prstatus_pr_reg), &ms->panic_task_regs[i],
+ sizeof(struct arm64_pt_regs));
+
+ found++;
+ }
+ if (!found) {
+ free(ms->panic_task_regs);
+ ms->panic_task_regs = NULL;
+ }
+ }
return;
+ }
crash_notes = symbol_value("crash_notes");
--
2.30.2

View File

@ -1,99 +0,0 @@
From 5c04a6f3f923af7c50f0d853477044802b3fa6ec Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sat, 16 Oct 2021 13:21:17 +0800
Subject: [PATCH 7/9] symbols: Add mod_symname_hash table dump to help -s
Previously, help -s only print out the dump status of symname_hash
table. Since we have mod_symname_hash table introduced, let's print
out mod_symname_hash in help -s as well.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
symbols.c | 57 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 22 deletions(-)
diff --git a/symbols.c b/symbols.c
index 67b701454563..73baa953217a 100644
--- a/symbols.c
+++ b/symbols.c
@@ -3219,13 +3219,40 @@ kallsyms_module_function_size(struct syment *sp, struct load_module *lm, ulong *
return FALSE;
}
+static void
+dump_symname_hash_table(struct syment *table[])
+{
+ int i, cnt, tot;
+ struct syment *sp;
+
+ fprintf(fp, " ");
+ for (i = tot = 0; i < SYMNAME_HASH; i++) {
+ fprintf(fp, "[%3d]: ", i);
+ if ((sp = table[i]) == NULL)
+ fprintf(fp, "%3d ", 0);
+ else {
+ cnt = 1;
+ while (sp->name_hash_next) {
+ cnt++;
+ sp = sp->name_hash_next;
+ }
+ fprintf(fp, "%3d ", cnt);
+ tot += cnt;
+ }
+ if (i && (((i+1) % 6) == 0))
+ fprintf(fp, "\n ");
+ }
+ if (SYMNAME_HASH % 6)
+ fprintf(fp, "\n");
+}
+
/*
* "help -s" output
*/
void
dump_symbol_table(void)
{
- int i, s, cnt, tot;
+ int i, s, cnt;
struct load_module *lm;
struct syment *sp;
struct downsized *ds;
@@ -3355,28 +3382,14 @@ dump_symbol_table(void)
fprintf(fp, " symname_hash[%d]: %lx\n", SYMNAME_HASH,
(ulong)&st->symname_hash[0]);
+ if (CRASHDEBUG(1))
+ dump_symname_hash_table(st->symname_hash);
+
+ fprintf(fp, "mod_symname_hash[%d]: %lx\n", SYMNAME_HASH,
+ (ulong)&st->mod_symname_hash[0]);
+ if (CRASHDEBUG(1))
+ dump_symname_hash_table(st->mod_symname_hash);
- if (CRASHDEBUG(1)) {
- fprintf(fp, " ");
- for (i = tot = 0; i < SYMNAME_HASH; i++) {
- fprintf(fp, "[%3d]: ", i);
- if ((sp = st->symname_hash[i]) == NULL)
- fprintf(fp, "%3d ", 0);
- else {
- cnt = 1;
- while (sp->name_hash_next) {
- cnt++;
- sp = sp->name_hash_next;
- }
- fprintf(fp, "%3d ", cnt);
- tot += cnt;
- }
- if (i && (((i+1) % 6) == 0))
- fprintf(fp, "\n ");
- }
- if (SYMNAME_HASH % 6)
- fprintf(fp, "\n");
- }
fprintf(fp, " symbol_namespace: ");
fprintf(fp, "address: %lx ", (ulong)st->kernel_namespace.address);
fprintf(fp, "index: %ld ", st->kernel_namespace.index);
--
2.30.2

View File

@ -1,34 +0,0 @@
From 3db5fff2e9d7b8762d1bd46d8d2c47ba4c7e374f Mon Sep 17 00:00:00 2001
From: Ritesh Harjani <riteshh@linux.ibm.com>
Date: Thu, 26 Aug 2021 02:31:08 +0530
Subject: [PATCH 08/27] .gitignore: Add cscope, ctags & compile_commands.json
Add cscope, ctags & compile_commands.json in .gitignore file.
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
---
.gitignore | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/.gitignore b/.gitignore
index 5b2ba1d34012..b39832fa71df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,14 @@ gdb-7.6/
extensions/defs.h
extensions/*.so
extensions/eppic
+
+# cscope files
+cscope.*
+ncscope.*
+
+# ctags files
+tags
+TAGS
+
+# Clang's compilation database file
+/compile_commands.json
--
2.30.2

View File

@ -1,66 +0,0 @@
From c180a63f2cb370da6097ad97eb07333c07aa988b Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 25 Oct 2021 16:53:26 +0900
Subject: [PATCH 8/9] arm64: Use VA_BITS for page_offset calculation
Commit 167d37e347fe ("arm64: assign page_offset with VA_BITS kernel
configuration value") changed the page_offset calculation from
using VA_BITS_ACTUAL to CONFIG_ARM64_VA_BITS. This caused an error
for ramdumps without vmcoreinfo like this:
crash: vmlinux and /var/tmp/ramdump_elf_XUtCMT do not match!
Set the vmcoreinfo value to VA_BITS if available, and use VA_BITS
for page_offset calculation instead.
Also remove ARM64_FLIP_PAGE_OFFSET_ACTUAL because it's not used
actually.
Reported-by: Ankur Bansal <er.ankurbansal@gmail.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
arm64.c | 5 ++++-
defs.h | 4 +---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/arm64.c b/arm64.c
index 7069312671cf..3dcbcc642fda 100644
--- a/arm64.c
+++ b/arm64.c
@@ -404,7 +404,7 @@ arm64_init(int when)
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET);
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
@@ -4031,6 +4031,9 @@ arm64_calc_VA_BITS(void)
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
}
+ if (machdep->machspec->CONFIG_ARM64_VA_BITS)
+ machdep->machspec->VA_BITS = machdep->machspec->CONFIG_ARM64_VA_BITS;
+
/*
* The mm flip commit is introduced before 52-bits VA, which is before the
* commit to export NUMBER(TCR_EL1_T1SZ)
diff --git a/defs.h b/defs.h
index 8b356d5e8959..971005596506 100644
--- a/defs.h
+++ b/defs.h
@@ -3238,9 +3238,7 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
/* kernels >= v5.4 the kernel VA space is flipped */
-#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->CONFIG_ARM64_VA_BITS)
-#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- - ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
+#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->VA_BITS)
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
#define ARM64_USERSPACE_TOP_ACTUAL ((1UL) << machdep->machspec->VA_BITS_ACTUAL)
--
2.30.2

View File

@ -1,36 +0,0 @@
From e61841a8b86ac551c314f74f4b82daae84f99700 Mon Sep 17 00:00:00 2001
From: Luc Chouinard <lucchouina@gmail.com>
Date: Wed, 9 Jun 2021 07:59:40 -0400
Subject: [PATCH 08/16] extensions/eppic.mk: Enable use of alternate eppic
branch
Made significant changes and fixes to eppic.
Using options in the clone command break due to args parsing.
Use separate variable for clone options.
Closes: https://github.com/crash-utility/crash/pull/86
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
extensions/eppic.mk | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/extensions/eppic.mk b/extensions/eppic.mk
index bda69da6706f..b9c046b710ad 100644
--- a/extensions/eppic.mk
+++ b/extensions/eppic.mk
@@ -35,10 +35,10 @@ all:
if [ -f "$(GIT)" ]; \
then \
if [ -n "$(EPPIC_GIT_URL)" ]; then \
- git clone "$(EPPIC_GIT_URL)" eppic; \
+ git clone $(EPPIC_GIT_OPTIONS) $(EPPIC_GIT_URL) eppic; \
else \
if ping -c 1 -W 5 github.com >/dev/null ; then \
- git clone https://github.com/lucchouina/eppic.git eppic; \
+ git clone $(EPPIC_GIT_OPTIONS) https://github.com/lucchouina/eppic.git eppic; \
fi; \
fi; \
else \
--
2.30.2

View File

@ -1,57 +0,0 @@
From 68870c83d299603c07785e3530e33c13045c87ef Mon Sep 17 00:00:00 2001
From: Alexander Egorenkov <egorenar@linux.ibm.com>
Date: Wed, 13 Oct 2021 10:56:39 +0200
Subject: [PATCH 9/9] Handle task_struct cpu member changes for kernels >=
5.16-rc1
Kernel commit bcf9033e5449bdcaa9bed46467a7141a8049dadb
("sched: move CPU field back into thread_info if THREAD_INFO_IN_TASK=y")
moved the member cpu of task_struct back into thread_info.
Without the patch, crash fails with the following error message
during session initialization:
crash: invalid structure member offset: task_struct_cpu
FILE: task.c LINE: 2904 FUNCTION: add_context()
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
task.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/task.c b/task.c
index 672b41697e75..bb6a5da8ad33 100644
--- a/task.c
+++ b/task.c
@@ -278,8 +278,10 @@ task_init(void)
} else if (VALID_MEMBER(task_struct_stack))
MEMBER_OFFSET_INIT(task_struct_thread_info, "task_struct", "stack");
+ MEMBER_OFFSET_INIT(task_struct_cpu, "task_struct", "cpu");
+
if (VALID_MEMBER(task_struct_thread_info)) {
- if (tt->flags & THREAD_INFO_IN_TASK) {
+ if (tt->flags & THREAD_INFO_IN_TASK && VALID_MEMBER(task_struct_cpu)) {
MEMBER_OFFSET_INIT(thread_info_flags, "thread_info", "flags");
/* (unnecessary) reminders */
ASSIGN_OFFSET(thread_info_task) = INVALID_OFFSET;
@@ -315,7 +317,6 @@ task_init(void)
MEMBER_OFFSET_INIT(task_struct_has_cpu, "task_struct", "has_cpu");
MEMBER_OFFSET_INIT(task_struct_cpus_runnable,
"task_struct", "cpus_runnable");
- MEMBER_OFFSET_INIT(task_struct_cpu, "task_struct", "cpu");
MEMBER_OFFSET_INIT(task_struct_active_mm, "task_struct", "active_mm");
MEMBER_OFFSET_INIT(task_struct_next_run, "task_struct", "next_run");
MEMBER_OFFSET_INIT(task_struct_flags, "task_struct", "flags");
@@ -2900,7 +2901,7 @@ add_context(ulong task, char *tp)
else
tc->thread_info = ULONG(tp + OFFSET(task_struct_thread_info));
fill_thread_info(tc->thread_info);
- if (tt->flags & THREAD_INFO_IN_TASK)
+ if (tt->flags & THREAD_INFO_IN_TASK && VALID_MEMBER(task_struct_cpu))
processor_addr = (int *) (tp + OFFSET(task_struct_cpu));
else
processor_addr = (int *) (tt->thread_info +
--
2.30.2

View File

@ -1,156 +0,0 @@
From f091b5e76d2d6e81b12cd40df7b5863c9e2efed1 Mon Sep 17 00:00:00 2001
From: Firo Yang <firo.yang@suse.com>
Date: Tue, 25 May 2021 18:17:37 +0800
Subject: [PATCH 09/16] list: add -O option for specifying head node offset
The -O option is very useful to specify the embedded head node's
offset which is different to the offset of other nodes embedded,
e.g. dentry.d_subdirs (the head node) and dentry.d_child.
[ kh: did some cosmetic adjustments ]
Signed-off-by: Firo Yang <firo.yang@suse.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
help.c | 32 +++++++++++++++++++++++++++++++-
tools.c | 32 +++++++++++++++++++++++++++++---
3 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 148b03e14455..42c8074e6ac6 100644
--- a/defs.h
+++ b/defs.h
@@ -2613,6 +2613,7 @@ struct list_data { /* generic structure used by do_list() to walk */
#define LIST_PARSE_MEMBER (VERBOSE << 13)
#define LIST_READ_MEMBER (VERBOSE << 14)
#define LIST_BRENT_ALGO (VERBOSE << 15)
+#define LIST_HEAD_OFFSET_ENTERED (VERBOSE << 16)
struct tree_data {
ulong flags;
diff --git a/help.c b/help.c
index 9649cc81fa36..99be7cb4e17c 100644
--- a/help.c
+++ b/help.c
@@ -5716,7 +5716,7 @@ char *help__list[] = {
"list",
"linked list",
"[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]"
-"\n [-r|-B] [-h|-H] start",
+"\n [-r|-B] [-h [-O head_offset]|-H] start",
" ",
" This command dumps the contents of a linked list. The entries in a linked",
" list are typically data structures that are tied together in one of two",
@@ -5800,6 +5800,15 @@ char *help__list[] = {
" -S struct Similar to -s, but instead of parsing gdb output, member values",
" are read directly from memory, so the command works much faster",
" for 1-, 2-, 4-, and 8-byte members.",
+" -O offset Only used in conjunction with -h; it specifies the offset of",
+" head node list_head embedded within a data structure which is",
+" different than the offset of list_head of other nodes embedded",
+" within a data structure.",
+" The offset may be entered in either of the following manners:",
+"",
+" 1. in \"structure.member\" format.",
+" 2. a number of bytes.",
+"",
" -l offset Only used in conjunction with -s, if the start address argument",
" is a pointer to an embedded list head (or any other similar list",
" linkage structure whose first member points to the next linkage",
@@ -6116,6 +6125,27 @@ char *help__list[] = {
" comm = \"sudo\"",
" ffff88005ac10180",
" comm = \"crash\"",
+"",
+" To display a liked list whose head node and other nodes are embedded within",
+" either same or different data structures resulting in different offsets for",
+" head node and other nodes, e.g. dentry.d_subdirs and dentry.d_child, the",
+" -O option can be used:",
+"",
+" %s> list -o dentry.d_child -s dentry.d_name.name -O dentry.d_subdirs -h ffff9c585b81a180",
+" ffff9c585b9cb140",
+" d_name.name = 0xffff9c585b9cb178 ccc.txt",
+" ffff9c585b9cb980",
+" d_name.name = 0xffff9c585b9cb9b8 bbb.txt",
+" ffff9c585b9cb740",
+" d_name.name = 0xffff9c585b9cb778 aaa.txt",
+"",
+" The dentry.d_subdirs example above is equal to the following sequence:",
+"",
+" %s> struct -o dentry.d_subdirs ffff9c585b81a180",
+" struct dentry {",
+" [ffff9c585b81a220] struct list_head d_subdirs;",
+" }",
+" %s> list -o dentry.d_child -s dentry.d_name.name -H ffff9c585b81a220",
NULL
};
diff --git a/tools.c b/tools.c
index a26b101f6481..6fa3c70bac2b 100644
--- a/tools.c
+++ b/tools.c
@@ -3343,6 +3343,7 @@ void
cmd_list(void)
{
int c;
+ long head_member_offset = 0; /* offset for head like denty.d_subdirs */
struct list_data list_data, *ld;
struct datatype_member struct_member, *sm;
struct syment *sp;
@@ -3353,7 +3354,7 @@ cmd_list(void)
BZERO(ld, sizeof(struct list_data));
struct_list_offset = 0;
- while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) {
+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:O:xdl:")) != EOF) {
switch(c)
{
case 'B':
@@ -3394,6 +3395,20 @@ cmd_list(void)
optarg);
break;
+ case 'O':
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED)
+ error(FATAL, "offset value %d (0x%lx) already entered\n",
+ head_member_offset, head_member_offset);
+ else if (IS_A_NUMBER(optarg))
+ head_member_offset = stol(optarg, FAULT_ON_ERROR, NULL);
+ else if (arg_to_datatype(optarg, sm, RETURN_ON_ERROR) > 1)
+ head_member_offset = sm->member_offset;
+ else
+ error(FATAL, "invalid -O argument: %s\n", optarg);
+
+ ld->flags |= LIST_HEAD_OFFSET_ENTERED;
+ break;
+
case 'o':
if (ld->flags & LIST_OFFSET_ENTERED)
error(FATAL,
@@ -3599,8 +3614,19 @@ next_arg:
fprintf(fp, "(empty)\n");
return;
}
- } else
- ld->start += ld->list_head_offset;
+ } else {
+ if (ld->flags & LIST_HEAD_OFFSET_ENTERED) {
+ if (!ld->end)
+ ld->end = ld->start + head_member_offset;
+ readmem(ld->start + head_member_offset, KVADDR, &ld->start,
+ sizeof(void *), "LIST_HEAD contents", FAULT_ON_ERROR);
+ if (ld->start == ld->end) {
+ fprintf(fp, "(empty)\n");
+ return;
+ }
+ } else
+ ld->start += ld->list_head_offset;
+ }
}
ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED);
--
2.30.2

View File

@ -1,28 +0,0 @@
From 15765867c0f1d937db5ec06f51adb6bfd13354ea Mon Sep 17 00:00:00 2001
From: Ritesh Harjani <riteshh@linux.ibm.com>
Date: Thu, 26 Aug 2021 02:31:10 +0530
Subject: [PATCH 09/27] ppc64: Add MMU type info in machdep command
This adds MMU type info in "machdep" command.
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
---
ppc64.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/ppc64.c b/ppc64.c
index f368bf8e1a08..975caa53b812 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -3027,6 +3027,8 @@ ppc64_display_machine_stats(void)
else
fprintf(fp, "(unknown)\n");
fprintf(fp, " HZ: %d\n", machdep->hz);
+ fprintf(fp, " MMU: %s\n", machdep->flags & RADIX_MMU
+ ? "RADIX" : "HASH");
fprintf(fp, " PAGE SIZE: %d\n", PAGESIZE());
// fprintf(fp, " L1 CACHE SIZE: %d\n", l1_cache_size());
fprintf(fp, "KERNEL VIRTUAL BASE: %lx\n", machdep->kvbase);
--
2.30.2

View File

@ -1,132 +0,0 @@
From eaf14f852ae79f7745934e213661f1c6abac711e Mon Sep 17 00:00:00 2001
From: Greg Edwards <gedwards@ddn.com>
Date: Wed, 23 Jun 2021 13:50:47 -0600
Subject: [PATCH 10/16] Fix 'waitq' command for Linux 4.13 and later kernels
The wait queue structs and members were renamed in 4.13 in commits:
ac6424b981bc ("sched/wait: Rename wait_queue_t => wait_queue_entry_t")
9d9d676f595b ("sched/wait: Standardize internal naming of wait-queue heads")
2055da97389a ("sched/wait: Disambiguate wq_entry->task_list and wq_head->task_list naming")
Add support to the 'waitq' command for these more recent kernels.
[ kh: suppressed compilation warnings ]
Signed-off-by: Greg Edwards <gedwards@ddn.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 4 ++++
kernel.c | 27 +++++++++++++++++++++++----
symbols.c | 10 +++++++++-
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index 42c8074e6ac6..6bb00e29d811 100644
--- a/defs.h
+++ b/defs.h
@@ -2138,6 +2138,9 @@ struct offset_table { /* stash of commonly-used offsets */
long atomic_long_t_counter;
long block_device_bd_device;
long block_device_bd_stats;
+ long wait_queue_entry_private;
+ long wait_queue_head_head;
+ long wait_queue_entry_entry;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2300,6 +2303,7 @@ struct size_table { /* stash of commonly-used sizes */
long printk_info;
long printk_ringbuffer;
long prb_desc;
+ long wait_queue_entry;
};
struct array_table {
diff --git a/kernel.c b/kernel.c
index 528f6ee524f6..e123f760e036 100644
--- a/kernel.c
+++ b/kernel.c
@@ -615,7 +615,15 @@ kernel_init()
kt->flags |= TVEC_BASES_V1;
STRUCT_SIZE_INIT(__wait_queue, "__wait_queue");
- if (VALID_STRUCT(__wait_queue)) {
+ STRUCT_SIZE_INIT(wait_queue_entry, "wait_queue_entry");
+ if (VALID_STRUCT(wait_queue_entry)) {
+ MEMBER_OFFSET_INIT(wait_queue_entry_private,
+ "wait_queue_entry", "private");
+ MEMBER_OFFSET_INIT(wait_queue_head_head,
+ "wait_queue_head", "head");
+ MEMBER_OFFSET_INIT(wait_queue_entry_entry,
+ "wait_queue_entry", "entry");
+ } else if (VALID_STRUCT(__wait_queue)) {
if (MEMBER_EXISTS("__wait_queue", "task"))
MEMBER_OFFSET_INIT(__wait_queue_task,
"__wait_queue", "task");
@@ -9367,9 +9375,9 @@ dump_waitq(ulong wq, char *wq_name)
struct list_data list_data, *ld;
ulong *wq_list; /* addr of wait queue element */
ulong next_offset; /* next pointer of wq element */
- ulong task_offset; /* offset of task in wq element */
+ ulong task_offset = 0; /* offset of task in wq element */
int cnt; /* # elems on Queue */
- int start_index; /* where to start in wq array */
+ int start_index = -1; /* where to start in wq array */
int i;
ld = &list_data;
@@ -9397,9 +9405,20 @@ dump_waitq(ulong wq, char *wq_name)
ld->list_head_offset = OFFSET(__wait_queue_task_list);
ld->member_offset = next_offset;
+ start_index = 1;
+ } else if (VALID_STRUCT(wait_queue_entry)) {
+ ulong head_offset;
+
+ next_offset = OFFSET(list_head_next);
+ task_offset = OFFSET(wait_queue_entry_private);
+ head_offset = OFFSET(wait_queue_head_head);
+ ld->end = ld->start = wq + head_offset + next_offset;
+ ld->list_head_offset = OFFSET(wait_queue_entry_entry);
+ ld->member_offset = next_offset;
+
start_index = 1;
} else {
- return;
+ error(FATAL, "cannot determine wait queue structures\n");
}
hq_open();
diff --git a/symbols.c b/symbols.c
index 370d4c3e8ac0..67c135f12984 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9817,7 +9817,13 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(__wait_queue_head_task_list));
fprintf(fp, " __wait_queue_task_list: %ld\n",
OFFSET(__wait_queue_task_list));
-
+ fprintf(fp, " wait_queue_entry_private: %ld\n",
+ OFFSET(wait_queue_entry_private));
+ fprintf(fp, " wait_queue_head_head: %ld\n",
+ OFFSET(wait_queue_head_head));
+ fprintf(fp, " wait_queue_entry_entry: %ld\n",
+ OFFSET(wait_queue_entry_entry));
+
fprintf(fp, " pglist_data_node_zones: %ld\n",
OFFSET(pglist_data_node_zones));
fprintf(fp, " pglist_data_node_mem_map: %ld\n",
@@ -10717,6 +10723,8 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " wait_queue: %ld\n", SIZE(wait_queue));
fprintf(fp, " __wait_queue: %ld\n",
SIZE(__wait_queue));
+ fprintf(fp, " wait_queue_entry: %ld\n",
+ SIZE(wait_queue_entry));
fprintf(fp, " device: %ld\n", SIZE(device));
fprintf(fp, " net_device: %ld\n", SIZE(net_device));
--
2.30.2

View File

@ -1,48 +0,0 @@
From cf0c8d10e1870d89b39f40382634db51aa8fcf2c Mon Sep 17 00:00:00 2001
From: Hari Bathini <hbathini@linux.ibm.com>
Date: Fri, 3 Sep 2021 17:33:42 +0530
Subject: [PATCH 10/27] mod: fix module object file lookup
On systems where vmlinux file is not under /usr/lib/debug/lib/modules
directory, 'mod -s|-S' command may fail to find the module's object
file with the below error:
mod: cannot find or load object file for sd_mod module
Fix it by trying all possible module object file extentions while
searching for the object file under /usr/lib/debug/lib/modules
directory.
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
---
kernel.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/kernel.c b/kernel.c
index 36fdea29b1cb..b2c8a0ccb7ab 100644
--- a/kernel.c
+++ b/kernel.c
@@ -4796,7 +4796,18 @@ module_objfile_search(char *modref, char *filename, char *tree)
sprintf(dir, "%s/%s", DEFAULT_REDHAT_DEBUG_LOCATION,
kt->utsname.release);
- retbuf = search_directory_tree(dir, file, 0);
+ if (!(retbuf = search_directory_tree(dir, file, 0))) {
+ switch (kt->flags & (KMOD_V1|KMOD_V2))
+ {
+ case KMOD_V2:
+ sprintf(file, "%s.ko", modref);
+ retbuf = search_directory_tree(dir, file, 0);
+ if (!retbuf) {
+ sprintf(file, "%s.ko.debug", modref);
+ retbuf = search_directory_tree(dir, file, 0);
+ }
+ }
+ }
if (!retbuf && (env = getenv("CRASH_MODULE_PATH"))) {
sprintf(dir, "%s", env);
--
2.30.2

View File

@ -1,90 +0,0 @@
From 4badc6229c69f5cd9da7eb7bdf400a53ec6db01a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Tesa=C5=99=C3=ADk?= <ptesarik@suse.cz>
Date: Fri, 25 Jun 2021 17:21:18 +0200
Subject: [PATCH 11/16] Fix pvops Xen detection for kernels >= v4.20
Kernel commit 5c83511bdb9832c86be20fb86b783356e2f58062 removed
pv_init_ops, and later commit 054ac8ad5ebe4a69e1f0e842483821ddbe560121
removed the Xen-specific paravirt patch function. As a result, pvops Xen
dumps are no longer recognized as Xen dumps, and virtual-to-physical
translation fails.
Use the value of xen_start_info to determine whether the kernel is
running in Xen PV mode. This pointer is set during the initialization of
a PV domain. Kudos to Juergen Gross, who suggested this check.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
index e123f760e036..36fdea29b1cb 100644
--- a/kernel.c
+++ b/kernel.c
@@ -95,6 +95,7 @@ static ulong __dump_audit(char *);
static void dump_audit(void);
static char *vmcoreinfo_read_string(const char *);
static void check_vmcoreinfo(void);
+static int is_pvops_xen(void);
/*
@@ -109,7 +110,6 @@ kernel_init()
char *rqstruct;
char *rq_timestamp_name = NULL;
char *irq_desc_type_name;
- ulong pv_init_ops;
struct gnu_request req;
if (pc->flags & KERNEL_DEBUG_QUERY)
@@ -169,11 +169,7 @@ kernel_init()
error(FATAL, "cannot malloc m2p page.");
}
- if (PVOPS() && symbol_exists("pv_init_ops") &&
- readmem(symbol_value("pv_init_ops"), KVADDR, &pv_init_ops,
- sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
- ((p1 = value_symbol(pv_init_ops)) &&
- (STREQ(p1, "xen_patch") || STREQ(p1, "paravirt_patch_default")))) {
+ if (is_pvops_xen()) {
kt->flags |= ARCH_XEN | ARCH_PVOPS_XEN;
kt->xen_flags |= WRITABLE_PAGE_TABLES;
if (machine_type("X86"))
@@ -10709,6 +10705,32 @@ paravirt_init(void)
}
}
+static int
+is_pvops_xen(void)
+{
+ ulong addr;
+ char *sym;
+
+ if (!PVOPS())
+ return FALSE;
+
+ if (symbol_exists("pv_init_ops") &&
+ readmem(symbol_value("pv_init_ops"), KVADDR, &addr,
+ sizeof(void *), "pv_init_ops", RETURN_ON_ERROR) &&
+ (sym = value_symbol(addr)) &&
+ (STREQ(sym, "xen_patch") ||
+ STREQ(sym, "paravirt_patch_default")))
+ return TRUE;
+
+ if (symbol_exists("xen_start_info") &&
+ readmem(symbol_value("xen_start_info"), KVADDR, &addr,
+ sizeof(void *), "xen_start_info", RETURN_ON_ERROR) &&
+ addr != 0)
+ return TRUE;
+
+ return FALSE;
+}
+
/*
* Get the kernel's xtime timespec from its relevant location.
*/
--
2.30.2

View File

@ -1,265 +0,0 @@
From 7f38d1baf794823355ee100b3a1914155d4190f2 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Mon, 27 Sep 2021 09:45:42 +0900
Subject: [PATCH 11/27] diskdump: Add support for reading dumpfiles compressed
by Zstandard
Add support for reading dumpfiles compressed by Zstandard (zstd)
using makedumpfile.
To build crash with zstd support, type "make zstd".
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
Makefile | 4 ++++
README | 4 ++--
configure.c | 24 +++++++++++++++++++++---
defs.h | 4 ++++
diskdump.c | 37 +++++++++++++++++++++++++++++++++++++
diskdump.h | 1 +
help.c | 4 ++--
7 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index ece13069a029..eae023c54bdd 100644
--- a/Makefile
+++ b/Makefile
@@ -333,6 +333,10 @@ snappy: make_configure
@./configure -x snappy ${CONF_TARGET_FLAG} -w -b
@make --no-print-directory gdb_merge
+zstd: make_configure
+ @./configure -x zstd ${CONF_TARGET_FLAG} -w -b
+ @make --no-print-directory gdb_merge
+
valgrind: make_configure
@./configure -x valgrind ${CONF_TARGET_FLAG} -w -b
@make --no-print-directory gdb_merge
diff --git a/README b/README
index 50179742e620..4962f272074b 100644
--- a/README
+++ b/README
@@ -102,8 +102,8 @@
Traditionally when vmcores are compressed via the makedumpfile(8) facility
the libz compression library is used, and by default the crash utility
only supports libz. Recently makedumpfile has been enhanced to optionally
- use either the LZO or snappy compression libraries. To build crash with
- either or both of those libraries, type "make lzo" or "make snappy".
+ use the LZO, snappy or zstd compression libraries. To build crash with any
+ or all of those libraries, type "make lzo", "make snappy" or "make zstd".
crash supports valgrind Memcheck tool on the crash's custom memory allocator.
To build crash with this feature enabled, type "make valgrind" and then run
diff --git a/configure.c b/configure.c
index e8f619a3c061..b691a139b960 100644
--- a/configure.c
+++ b/configure.c
@@ -1738,6 +1738,10 @@ get_extra_flags(char *filename, char *initial)
* - enter -DSNAPPY in the CFLAGS.extra file
* - enter -lsnappy in the LDFLAGS.extra file
*
+ * For zstd:
+ * - enter -DZSTD in the CFLAGS.extra file
+ * - enter -lzstd in the LDFLAGS.extra file
+ *
* For valgrind:
* - enter -DVALGRIND in the CFLAGS.extra file
*/
@@ -1746,6 +1750,7 @@ add_extra_lib(char *option)
{
int lzo, add_DLZO, add_llzo2;
int snappy, add_DSNAPPY, add_lsnappy;
+ int zstd, add_DZSTD, add_lzstd;
int valgrind, add_DVALGRIND;
char *cflags, *ldflags;
FILE *fp_cflags, *fp_ldflags;
@@ -1754,6 +1759,7 @@ add_extra_lib(char *option)
lzo = add_DLZO = add_llzo2 = 0;
snappy = add_DSNAPPY = add_lsnappy = 0;
+ zstd = add_DZSTD = add_lzstd = 0;
valgrind = add_DVALGRIND = 0;
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
@@ -1775,13 +1781,21 @@ add_extra_lib(char *option)
add_lsnappy++;
}
+ if (strcmp(option, "zstd") == 0) {
+ zstd++;
+ if (!cflags || !strstr(cflags, "-DZSTD"))
+ add_DZSTD++;
+ if (!ldflags || !strstr(ldflags, "-lzstd"))
+ add_lzstd++;
+ }
+
if (strcmp(option, "valgrind") == 0) {
valgrind++;
if (!cflags || !strstr(cflags, "-DVALGRIND"))
add_DVALGRIND++;
}
- if ((lzo || snappy) &&
+ if ((lzo || snappy || zstd) &&
file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
perror("diskdump.o");
return;
@@ -1806,24 +1820,28 @@ add_extra_lib(char *option)
return;
}
- if (add_DLZO || add_DSNAPPY || add_DVALGRIND) {
+ if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) {
while (fgets(inbuf, 512, fp_cflags))
;
if (add_DLZO)
fputs("-DLZO\n", fp_cflags);
if (add_DSNAPPY)
fputs("-DSNAPPY\n", fp_cflags);
+ if (add_DZSTD)
+ fputs("-DZSTD\n", fp_cflags);
if (add_DVALGRIND)
fputs("-DVALGRIND\n", fp_cflags);
}
- if (add_llzo2 || add_lsnappy) {
+ if (add_llzo2 || add_lsnappy || add_lzstd) {
while (fgets(inbuf, 512, fp_ldflags))
;
if (add_llzo2)
fputs("-llzo2\n", fp_ldflags);
if (add_lsnappy)
fputs("-lsnappy\n", fp_ldflags);
+ if (add_lzstd)
+ fputs("-lzstd\n", fp_ldflags);
}
fclose(fp_cflags);
diff --git a/defs.h b/defs.h
index eb1c71b5333a..b2e94722c92b 100644
--- a/defs.h
+++ b/defs.h
@@ -54,6 +54,9 @@
#ifdef SNAPPY
#include <snappy-c.h>
#endif
+#ifdef ZSTD
+#include <zstd.h>
+#endif
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
@@ -327,6 +330,7 @@ struct number_option {
#define NO_ELF_NOTES (0x20)
#define LZO_SUPPORTED (0x40)
#define SNAPPY_SUPPORTED (0x80)
+#define ZSTD_SUPPORTED (0x100)
#define DISKDUMP_VALID() (dd->flags & DISKDUMP_LOCAL)
#define KDUMP_CMPRS_VALID() (dd->flags & KDUMP_CMPRS_LOCAL)
#define KDUMP_SPLIT() (dd->flags & DUMPFILE_SPLIT)
diff --git a/diskdump.c b/diskdump.c
index de3eeb2c720c..112f769f8949 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1001,6 +1001,9 @@ is_diskdump(char *file)
#ifdef SNAPPY
dd->flags |= SNAPPY_SUPPORTED;
#endif
+#ifdef ZSTD
+ dd->flags |= ZSTD_SUPPORTED;
+#endif
pc->read_vmcoreinfo = vmcoreinfo_read_string;
@@ -1124,6 +1127,9 @@ cache_page(physaddr_t paddr)
const int block_size = dd->block_size;
const off_t failed = (off_t)-1;
ulong retlen;
+#ifdef ZSTD
+ static ZSTD_DCtx *dctx = NULL;
+#endif
for (i = found = 0; i < DISKDUMP_CACHED_PAGES; i++) {
if (DISKDUMP_VALID_PAGE(dd->page_cache_hdr[i].pg_flags))
@@ -1251,6 +1257,33 @@ cache_page(physaddr_t paddr)
ret);
return READ_ERROR;
}
+#endif
+ } else if (pd.flags & DUMP_DH_COMPRESSED_ZSTD) {
+
+ if (!(dd->flags & ZSTD_SUPPORTED)) {
+ error(INFO, "%s: uncompess failed: no zstd compression support\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
+ return READ_ERROR;
+ }
+#ifdef ZSTD
+ if (!dctx) {
+ dctx = ZSTD_createDCtx();
+ if (!dctx) {
+ error(INFO, "%s: uncompess failed: cannot create ZSTD_DCtx\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
+ return READ_ERROR;
+ }
+ }
+
+ retlen = ZSTD_decompressDCtx(dctx,
+ dd->page_cache_hdr[i].pg_bufptr, block_size,
+ dd->compressed_page, pd.size);
+ if (ZSTD_isError(retlen) || (retlen != block_size)) {
+ error(INFO, "%s: uncompress failed: %d (%s)\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump",
+ retlen, ZSTD_getErrorName(retlen));
+ return READ_ERROR;
+ }
#endif
} else
memcpy(dd->page_cache_hdr[i].pg_bufptr,
@@ -1806,6 +1839,8 @@ __diskdump_memory_dump(FILE *fp)
fprintf(fp, "%sLZO_SUPPORTED", others++ ? "|" : "");
if (dd->flags & SNAPPY_SUPPORTED)
fprintf(fp, "%sSNAPPY_SUPPORTED", others++ ? "|" : "");
+ if (dd->flags & ZSTD_SUPPORTED)
+ fprintf(fp, "%sZSTD_SUPPORTED", others++ ? "|" : "");
fprintf(fp, ") %s\n", FLAT_FORMAT() ? "[FLAT]" : "");
fprintf(fp, " dfd: %d\n", dd->dfd);
fprintf(fp, " ofp: %lx\n", (ulong)dd->ofp);
@@ -1872,6 +1907,8 @@ __diskdump_memory_dump(FILE *fp)
fprintf(fp, "DUMP_DH_COMPRESSED_LZO");
if (dh->status & DUMP_DH_COMPRESSED_SNAPPY)
fprintf(fp, "DUMP_DH_COMPRESSED_SNAPPY");
+ if (dh->status & DUMP_DH_COMPRESSED_ZSTD)
+ fprintf(fp, "DUMP_DH_COMPRESSED_ZSTD");
if (dh->status & DUMP_DH_COMPRESSED_INCOMPLETE)
fprintf(fp, "DUMP_DH_COMPRESSED_INCOMPLETE");
if (dh->status & DUMP_DH_EXCLUDED_VMEMMAP)
diff --git a/diskdump.h b/diskdump.h
index 28713407b841..c152c7b86616 100644
--- a/diskdump.h
+++ b/diskdump.h
@@ -86,6 +86,7 @@ struct kdump_sub_header {
#define DUMP_DH_COMPRESSED_SNAPPY 0x4 /* page is compressed with snappy */
#define DUMP_DH_COMPRESSED_INCOMPLETE 0x8 /* dumpfile is incomplete */
#define DUMP_DH_EXCLUDED_VMEMMAP 0x10 /* unused vmemmap pages are excluded */
+#define DUMP_DH_COMPRESSED_ZSTD 0x20 /* page is compressed with zstd */
/* descriptor of each page for vmcore */
typedef struct page_desc {
diff --git a/help.c b/help.c
index 6c262a3ffcbb..f34838d59908 100644
--- a/help.c
+++ b/help.c
@@ -9420,8 +9420,8 @@ README_ENTER_DIRECTORY,
" Traditionally when vmcores are compressed via the makedumpfile(8) facility",
" the libz compression library is used, and by default the crash utility",
" only supports libz. Recently makedumpfile has been enhanced to optionally",
-" use either the LZO or snappy compression libraries. To build crash with",
-" either or both of those libraries, type \"make lzo\" or \"make snappy\".",
+" use the LZO, snappy or zstd compression libraries. To build crash with any",
+" or all of those libraries, type \"make lzo\", \"make snappy\" or \"make zstd\".",
"",
" crash supports valgrind Memcheck tool on the crash's custom memory allocator.",
" To build crash with this feature enabled, type \"make valgrind\" and then run",
--
2.30.2

View File

@ -1,77 +0,0 @@
From d6b4f36d6b22b70fb14e692f36d20910ef5563c1 Mon Sep 17 00:00:00 2001
From: Alexander Egorenkov <egorenar@linux.ibm.com>
Date: Tue, 29 Jun 2021 08:39:00 +0200
Subject: [PATCH 12/16] Handle task_struct state member changes for kernels >=
5.14-rc1
Kernel commit 2f064a59a11ff9bc22e52e9678bc601404c7cb34 ("sched: Change
task_struct::state") renamed the member state of task_struct to __state
and its type changed from long to unsigned int. Without the patch,
crash fails to start up with the following error:
crash: invalid structure member offset: task_struct_state
FILE: task.c LINE: 5929 FUNCTION: task_state()
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 1 +
symbols.c | 1 +
task.c | 10 +++++++++-
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index 6bb00e29d811..5d32954905c2 100644
--- a/defs.h
+++ b/defs.h
@@ -2304,6 +2304,7 @@ struct size_table { /* stash of commonly-used sizes */
long printk_ringbuffer;
long prb_desc;
long wait_queue_entry;
+ long task_struct_state;
};
struct array_table {
diff --git a/symbols.c b/symbols.c
index 67c135f12984..bf6d94db84af 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10678,6 +10678,7 @@ dump_offset_table(char *spec, ulong makestruct)
SIZE(page_cache_bucket));
fprintf(fp, " pt_regs: %ld\n", SIZE(pt_regs));
fprintf(fp, " task_struct: %ld\n", SIZE(task_struct));
+ fprintf(fp, " task_struct_state: %ld\n", SIZE(task_struct_state));
fprintf(fp, " task_struct_flags: %ld\n", SIZE(task_struct_flags));
fprintf(fp, " task_struct_policy: %ld\n", SIZE(task_struct_policy));
fprintf(fp, " thread_info: %ld\n", SIZE(thread_info));
diff --git a/task.c b/task.c
index 36cf259e5d7b..672b41697e75 100644
--- a/task.c
+++ b/task.c
@@ -297,6 +297,11 @@ task_init(void)
}
MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "state");
+ if (INVALID_MEMBER(task_struct_state)) {
+ MEMBER_OFFSET_INIT(task_struct_state, "task_struct", "__state");
+ MEMBER_SIZE_INIT(task_struct_state, "task_struct", "__state");
+ }
MEMBER_OFFSET_INIT(task_struct_exit_state, "task_struct", "exit_state");
MEMBER_OFFSET_INIT(task_struct_pid, "task_struct", "pid");
MEMBER_OFFSET_INIT(task_struct_comm, "task_struct", "comm");
@@ -5926,7 +5931,10 @@ task_state(ulong task)
if (!tt->last_task_read)
return 0;
- state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ if (SIZE(task_struct_state) == sizeof(ulong))
+ state = ULONG(tt->task_struct + OFFSET(task_struct_state));
+ else
+ state = UINT(tt->task_struct + OFFSET(task_struct_state));
exit_state = VALID_MEMBER(task_struct_exit_state) ?
ULONG(tt->task_struct + OFFSET(task_struct_exit_state)) : 0;
--
2.30.2

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
From 5719afc7a40868418405a87a2711088556e68a3b Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:21 +0800
Subject: [PATCH 13/16] arm64: rename ARM64_PAGE_OFFSET_ACTUAL to
ARM64_FLIP_PAGE_OFFSET_ACTUAL
Reflect the flipped layout of kernel VA, which is introduced by
kernel commit 14c127c957c1 ("arm64: mm: Flip kernel VA space").
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 10 ++++++----
defs.h | 3 ++-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arm64.c b/arm64.c
index 8934961b109d..9fe1a4a3bddb 100644
--- a/arm64.c
+++ b/arm64.c
@@ -217,10 +217,12 @@ arm64_init(int when)
arm64_calc_VA_BITS();
arm64_calc_KERNELPACMASK();
ms = machdep->machspec;
+
+ /* vabits_actual introduced after mm flip, so it should be flipped layout */
if (ms->VA_BITS_ACTUAL) {
- ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL;
- machdep->identity_map_base = ARM64_PAGE_OFFSET_ACTUAL;
- machdep->kvbase = ARM64_PAGE_OFFSET_ACTUAL;
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
} else {
ms->page_offset = ARM64_PAGE_OFFSET;
@@ -401,7 +403,7 @@ arm64_init(int when)
fprintf(fp, "CONFIG_ARM64_VA_BITS: %ld\n", ms->CONFIG_ARM64_VA_BITS);
fprintf(fp, " VA_BITS_ACTUAL: %ld\n", ms->VA_BITS_ACTUAL);
fprintf(fp, "(calculated) VA_BITS: %ld\n", ms->VA_BITS);
- fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_PAGE_OFFSET_ACTUAL);
+ fprintf(fp, " PAGE_OFFSET: %lx\n", ARM64_FLIP_PAGE_OFFSET_ACTUAL);
fprintf(fp, " VA_START: %lx\n", ms->VA_START);
fprintf(fp, " modules: %lx - %lx\n", ms->modules_vaddr, ms->modules_end);
fprintf(fp, " vmalloc: %lx - %lx\n", ms->vmalloc_start_addr, ms->vmalloc_end);
diff --git a/defs.h b/defs.h
index 5d32954905c2..eb7ce6aea331 100644
--- a/defs.h
+++ b/defs.h
@@ -3233,7 +3233,8 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
-#define ARM64_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
+/* kernels >= v5.4 the kernel VA space is flipped */
+#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
#define ARM64_USERSPACE_TOP ((1UL) << machdep->machspec->VA_BITS)
--
2.30.2

View File

@ -1,120 +0,0 @@
From 163abcbbabdf8207c11ee93b1c909d85ecbcbf1f Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:26 -0700
Subject: [PATCH 13/27] crash_get_nr_cpus: get nr_cpus from the dumps
Most of the dumps have information about real number of CPUS.
Use that to instantiate GDB's target inferior threads.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
diskdump.c | 13 +++++++++++--
gdb_interface.c | 9 +++++++++
netdump.c | 11 ++++++++---
sadump.c | 2 +-
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index 112f769f8949..3e1cfd548c96 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2593,13 +2593,22 @@ diskdump_kaslr_check()
return FALSE;
}
-#ifdef X86_64
int
diskdump_get_nr_cpus(void)
{
- return dd->num_qemu_notes;
+ if (dd->num_prstatus_notes)
+ return dd->num_prstatus_notes;
+ else if (dd->num_qemu_notes)
+ return dd->num_qemu_notes;
+ else if (dd->num_vmcoredd_notes)
+ return dd->num_vmcoredd_notes;
+ else if (dd->header->nr_cpus)
+ return dd->header->nr_cpus;
+
+ return 1;
}
+#ifdef X86_64
QEMUCPUState *
diskdump_get_qemucpustate(int cpu)
{
diff --git a/gdb_interface.c b/gdb_interface.c
index 93fc8baef2c6..bcca080eb8b4 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -1070,6 +1070,15 @@ int crash_get_nr_cpus(void);
int crash_get_nr_cpus(void)
{
+ if (SADUMP_DUMPFILE())
+ return sadump_get_nr_cpus();
+ else if (DISKDUMP_DUMPFILE())
+ return diskdump_get_nr_cpus();
+ else if (KDUMP_DUMPFILE())
+ return kdump_get_nr_cpus();
+ else if (VMSS_DUMPFILE())
+ return vmware_vmss_get_nr_cpus();
+
/* Just CPU #0 */
return 1;
}
diff --git a/netdump.c b/netdump.c
index e8721d89f1a3..ff273b4fdfab 100644
--- a/netdump.c
+++ b/netdump.c
@@ -5206,11 +5206,17 @@ kdump_kaslr_check(void)
return FALSE;
}
-#ifdef X86_64
int
kdump_get_nr_cpus(void)
{
- return nd->num_qemu_notes;
+ if (nd->num_prstatus_notes)
+ return nd->num_prstatus_notes;
+ else if (nd->num_qemu_notes)
+ return nd->num_qemu_notes;
+ else if (nd->num_vmcoredd_notes)
+ return nd->num_vmcoredd_notes;
+
+ return 1;
}
QEMUCPUState *
@@ -5232,7 +5238,6 @@ kdump_get_qemucpustate(int cpu)
return (QEMUCPUState *)nd->nt_qemu_percpu[cpu];
}
-#endif
static void *
get_kdump_device_dump_offset(void)
diff --git a/sadump.c b/sadump.c
index d75c66b74be9..cb43fdb8ecab 100644
--- a/sadump.c
+++ b/sadump.c
@@ -1670,7 +1670,6 @@ get_sadump_data(void)
return sd;
}
-#ifdef X86_64
int
sadump_get_nr_cpus(void)
{
@@ -1678,6 +1677,7 @@ sadump_get_nr_cpus(void)
return sd->dump_header->nr_cpus;
}
+#ifdef X86_64
int
sadump_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr)
{
--
2.30.2

View File

@ -1,57 +0,0 @@
From 167d37e347fe35c6f7db826e8539e192c4375564 Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:22 +0800
Subject: [PATCH 14/16] arm64: assign page_offset with VA_BITS kernel
configuration value
On RHEL9, crash hits a bug when executing "crash /proc/kcore":
seek error: kernel virtual address: ffff6a0f3fff0000 type: "pmd page"
The kernel virtual address does not vary with vabits_actual, instead,
is determined by configuration value. But crash does not observe this
fact.
Since vabits_actual related kernel commit is introduced after arm64
mm layout flip commit, so changes are safe under the condition if
(ms->VA_BITS_ACTUAL), and keep the else branch untouched.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 7 ++++---
defs.h | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arm64.c b/arm64.c
index 9fe1a4a3bddb..149db36cd119 100644
--- a/arm64.c
+++ b/arm64.c
@@ -220,9 +220,10 @@ arm64_init(int when)
/* vabits_actual introduced after mm flip, so it should be flipped layout */
if (ms->VA_BITS_ACTUAL) {
- ms->page_offset = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
- machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
- machdep->kvbase = ARM64_FLIP_PAGE_OFFSET_ACTUAL;
+ ms->page_offset = ARM64_FLIP_PAGE_OFFSET;
+ /* useless on arm64 */
+ machdep->identity_map_base = ARM64_FLIP_PAGE_OFFSET;
+ machdep->kvbase = ARM64_FLIP_PAGE_OFFSET;
ms->userspace_top = ARM64_USERSPACE_TOP_ACTUAL;
} else {
ms->page_offset = ARM64_PAGE_OFFSET;
diff --git a/defs.h b/defs.h
index eb7ce6aea331..b7b20af4bcf9 100644
--- a/defs.h
+++ b/defs.h
@@ -3234,6 +3234,7 @@ typedef signed int s32;
#define ARM64_PAGE_OFFSET ((0xffffffffffffffffUL) \
<< (machdep->machspec->VA_BITS - 1))
/* kernels >= v5.4 the kernel VA space is flipped */
+#define ARM64_FLIP_PAGE_OFFSET (-(1UL) << machdep->machspec->CONFIG_ARM64_VA_BITS)
#define ARM64_FLIP_PAGE_OFFSET_ACTUAL ((0xffffffffffffffffUL) \
- ((1UL) << machdep->machspec->VA_BITS_ACTUAL) + 1)
--
2.30.2

View File

@ -1,45 +0,0 @@
From 36e9d8673e9205f4ea4daad61c199597920c93df Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:27 -0700
Subject: [PATCH 14/27] "whatis -m": fix duplications in the output
"whatis -m" output started to generate duplicated results after GDB update:
crash> whatis -m mm_struct
SIZE TYPE
16 tlb_state
...
256 linux_binprm
2752 rq
2752 rq <<-- duplicated
2752 rq
2752 rq
2752 rq
4048 task_struct
It was caused by incorrect string comparisons.
Use strcmp for full string comparison instead of just string pointers
comparison.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reported-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
symbols.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/symbols.c b/symbols.c
index 7ffac2ee8b49..338af2ce5038 100644
--- a/symbols.c
+++ b/symbols.c
@@ -7000,7 +7000,7 @@ append_struct_symbol (struct gnu_request *req, void *data)
struct type_request *treq = (struct type_request *)data;
for (i = 0; i < treq->idx; i++)
- if (treq->types[i].name == req->name)
+ if (!strcmp(treq->types[i].name, req->name))
break;
if (i < treq->idx) // We've already collected this type
--
2.30.2

View File

@ -1,80 +0,0 @@
From 0b85218983ffcf939a638f1133871079c5615a46 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:30 -0700
Subject: [PATCH 15/27] Fix reduced output of `bt` command
gdb-10 produces reduced output of `bt` command.
Changed disassembler output is the reason of missing frames
in backtrace. Call instruction mnemonic for x86_64 was changed
from "callq" to "call" in gdb-10.
Fixing the issue by adding a search for "call" word in disassembler
parser.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reported-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
x86_64.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 21756f6cf7ab..4f34afac06f9 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4415,7 +4415,7 @@ x86_64_function_called_by(ulong rip)
if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
rewind(pc->tmpfile2);
while (fgets(buf, BUFSIZE, pc->tmpfile2)) {
- if ((p1 = strstr(buf, "callq")) &&
+ if ((p1 = strstr(buf, "call")) &&
whitespace(*(p1-1))) {
if (extract_hex(p1, &value, NULLCHAR, TRUE))
break;
@@ -6381,11 +6381,13 @@ search_for_switch_to(ulong start, ulong end)
char search_string1[BUFSIZE];
char search_string2[BUFSIZE];
char search_string3[BUFSIZE];
+ char search_string4[BUFSIZE];
int found;
max_instructions = end - start;
found = FALSE;
- search_string1[0] = search_string2[0] = search_string3[0] = NULLCHAR;
+ search_string1[0] = search_string2[0] = NULLCHAR;
+ search_string3[0] = search_string4[0] = NULLCHAR;
sprintf(buf1, "x/%ldi 0x%lx", max_instructions, start);
if (symbol_exists("__switch_to")) {
@@ -6396,7 +6398,9 @@ search_for_switch_to(ulong start, ulong end)
}
if (symbol_exists("__switch_to_asm")) {
sprintf(search_string3,
- "callq 0x%lx", symbol_value("__switch_to_asm"));
+ "callq 0x%lx", symbol_value("__switch_to_asm"));
+ sprintf(search_string4,
+ "call 0x%lx", symbol_value("__switch_to_asm"));
}
open_tmpfile();
@@ -6416,6 +6420,8 @@ search_for_switch_to(ulong start, ulong end)
found = TRUE;
if (strlen(search_string3) && strstr(buf1, search_string3))
found = TRUE;
+ if (strlen(search_string4) && strstr(buf1, search_string4))
+ found = TRUE;
}
close_tmpfile();
@@ -8230,7 +8236,7 @@ x86_64_do_not_cache_framesize(struct syment *sp, ulong textaddr)
return TRUE;
}
- if (STREQ(arglist[instr], "callq"))
+ if (STREQ(arglist[instr], "callq") || STREQ(arglist[instr], "call"))
break;
}
close_tmpfile2();
--
2.30.2

View File

@ -1,84 +0,0 @@
From bf1379a8b6ff8d6a8fa12978f7194f15f85c4380 Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:23 +0800
Subject: [PATCH 15/16] arm64: use dedicated bits to record the VA space layout
changes
arm64 memory layout experiences big changes due to the following kernel
commits in date descending order:
5. 7bc1a0f9e176 arm64: mm: use single quantity to represent the PA to VA translation
4. b6d00d47e81a arm64: mm: Introduce 52-bit Kernel VAs
3. 5383cc6efed1 arm64: mm: Introduce vabits_actual
2. 14c127c957c1 arm64: mm: Flip kernel VA space
1. f80fb3a3d508 arm64: add support for kernel ASLR
For 1, crash has already used NEW_VMEMMAP to trace it.
For 2, crash lacks a flag to tag it and handle it differently.
For 3, two important kernel variables vabits_actual and physvirt_offset
are introduced.
For 4, since it comes immediately after 3, crash-utility does not need
to distinguish it.
For 5, kernel variable phyvirt_offset is removed
These changes have effects on PTOV()/VTOP() formula. So introducing
two bits HAS_PHYSVIRT_OFFSET and FLIPPED_VM as hint to apply different
formula.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 10 ++++++++++
defs.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/arm64.c b/arm64.c
index 149db36cd119..b04369f6d4d8 100644
--- a/arm64.c
+++ b/arm64.c
@@ -563,6 +563,10 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, "%sMACHDEP_BT_TEXT", others++ ? "|" : "");
if (machdep->flags & NEW_VMEMMAP)
fprintf(fp, "%sNEW_VMEMMAP", others++ ? "|" : "");
+ if (machdep->flags & FLIPPED_VM)
+ fprintf(fp, "%sFLIPPED_VM", others++ ? "|" : "");
+ if (machdep->flags & HAS_PHYSVIRT_OFFSET)
+ fprintf(fp, "%sHAS_PHYSVIRT_OFFSET", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -997,6 +1001,7 @@ arm64_calc_physvirt_offset(void)
if (READMEM(pc->mfd, &physvirt_offset, sizeof(physvirt_offset),
sp->value, sp->value -
machdep->machspec->kimage_voffset) > 0) {
+ machdep->flags |= HAS_PHYSVIRT_OFFSET;
ms->physvirt_offset = physvirt_offset;
}
}
@@ -3963,6 +3968,11 @@ arm64_calc_VA_BITS(void)
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
}
+ /*
+ * The mm flip commit is introduced before 52-bits VA, which is before the
+ * commit to export NUMBER(TCR_EL1_T1SZ)
+ */
+ machdep->flags |= FLIPPED_VM;
return;
}
diff --git a/defs.h b/defs.h
index b7b20af4bcf9..eca145cb881c 100644
--- a/defs.h
+++ b/defs.h
@@ -3214,6 +3214,8 @@ typedef signed int s32;
#define NEW_VMEMMAP (0x80)
#define VM_L4_4K (0x100)
#define UNW_4_14 (0x200)
+#define FLIPPED_VM (0x400)
+#define HAS_PHYSVIRT_OFFSET (0x800)
/*
* Get kimage_voffset from /dev/crash
--
2.30.2

View File

@ -1,166 +0,0 @@
From f53b73e8380bca054cebd2b61ff118c46609429b Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Fri, 2 Jul 2021 10:14:24 +0800
Subject: [PATCH 16/16] arm64: implement switchable PTOV()/VTOP() for kernels
>= 5.10
Crash encounters a bug like the following:
...
SECTION_SIZE_BITS: 30
CONFIG_ARM64_VA_BITS: 52
VA_BITS_ACTUAL: 48
(calculated) VA_BITS: 48
PAGE_OFFSET: ffff000000000000
VA_START: ffff800000000000
modules: ffff800008000000 - ffff80000fffffff
vmalloc: ffff800010000000 - ffffffdfdffeffff
kernel image: ffff800010000000 - ffff800012750000
vmemmap: ffffffdfffe00000 - ffffffffffffffff
<readmem: ffff800011c53bc8, KVADDR, "nr_irqs", 4, (FOE), b47bdc>
<read_kdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4>
read_netdump: addr: ffff800011c53bc8 paddr: eb453bc8 cnt: 4 offset: 1c73bc8
irq_stack_ptr:
type: 1, TYPE_CODE_PTR
target_typecode: 8, TYPE_CODE_INT
target_length: 8
length: 8
GNU_GET_DATATYPE[thread_union]: returned via gdb_error_hook
<readmem: ffff000b779c0050, KVADDR, "IRQ stack pointer", 8, (ROE), 3a37bea0>
<read_kdump: addr: ffff000b779c0050 paddr: fff1000bf79c0050 cnt: 8>
read_netdump: READ_ERROR: offset not found for paddr: fff1000bf79c0050
crash: read error: kernel virtual address: ffff000b779c0050 type: "IRQ stack pointer"
...
Apparently, for a normal system, the 'paddr: fff1000bf79c0050' is
unreasonable.
This bug connects with kernel commit 7bc1a0f9e176 ("arm64: mm: use
single quantity to represent the PA to VA translation"), which removed
physvirt_offset kernel variable and changed the PTOV()/VTOP() formulas.
Implement switchable PTOV()/VTOP() to cope with different kernel
version.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
arm64.c | 37 +++++++++++++++++++++++++++++++++----
defs.h | 9 ++++-----
2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/arm64.c b/arm64.c
index b04369f6d4d8..d73d5c5a4fed 100644
--- a/arm64.c
+++ b/arm64.c
@@ -994,8 +994,6 @@ arm64_calc_physvirt_offset(void)
ulong physvirt_offset;
struct syment *sp;
- ms->physvirt_offset = ms->phys_offset - ms->page_offset;
-
if ((sp = kernel_symbol_search("physvirt_offset")) &&
machdep->machspec->kimage_voffset) {
if (READMEM(pc->mfd, &physvirt_offset, sizeof(physvirt_offset),
@@ -1003,8 +1001,13 @@ arm64_calc_physvirt_offset(void)
machdep->machspec->kimage_voffset) > 0) {
machdep->flags |= HAS_PHYSVIRT_OFFSET;
ms->physvirt_offset = physvirt_offset;
+ return;
}
}
+
+ /* Useless if no symbol 'physvirt_offset', just keep semantics */
+ ms->physvirt_offset = ms->phys_offset - ms->page_offset;
+
}
static void
@@ -1051,6 +1054,7 @@ arm64_calc_phys_offset(void)
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
vaddr, paddr) > 0) {
ms->phys_offset = phys_offset;
+
return;
}
}
@@ -1178,6 +1182,21 @@ arm64_init_kernel_pgd(void)
vt->kernel_pgd[i] = value;
}
+ulong arm64_PTOV(ulong paddr)
+{
+ struct machine_specific *ms = machdep->machspec;
+
+ /*
+ * Either older kernel before kernel has 'physvirt_offset' or newer
+ * kernel which removes 'physvirt_offset' has the same formula:
+ * #define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
+ */
+ if (!(machdep->flags & HAS_PHYSVIRT_OFFSET))
+ return (paddr - ms->phys_offset) | PAGE_OFFSET;
+ else
+ return paddr - ms->physvirt_offset;
+}
+
ulong
arm64_VTOP(ulong addr)
{
@@ -1188,8 +1207,18 @@ arm64_VTOP(ulong addr)
return addr - machdep->machspec->kimage_voffset;
}
- if (addr >= machdep->machspec->page_offset)
- return addr + machdep->machspec->physvirt_offset;
+ if (addr >= machdep->machspec->page_offset) {
+ if (machdep->flags & HAS_PHYSVIRT_OFFSET) {
+ return addr + machdep->machspec->physvirt_offset;
+ } else {
+ /*
+ * Either older kernel before kernel has 'physvirt_offset' or newer
+ * kernel which removes 'physvirt_offset' has the same formula:
+ * #define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+ */
+ return (addr & ~PAGE_OFFSET) + machdep->machspec->phys_offset;
+ }
+ }
else if (machdep->machspec->kimage_voffset)
return addr - machdep->machspec->kimage_voffset;
else /* no randomness */
diff --git a/defs.h b/defs.h
index eca145cb881c..c91177a245fd 100644
--- a/defs.h
+++ b/defs.h
@@ -3092,11 +3092,6 @@ typedef u64 pte_t;
#define _64BIT_
#define MACHINE_TYPE "ARM64"
-#define PTOV(X) \
- ((unsigned long)(X) - (machdep->machspec->physvirt_offset))
-
-#define VTOP(X) arm64_VTOP((ulong)(X))
-
#define USERSPACE_TOP (machdep->machspec->userspace_top)
#define PAGE_OFFSET (machdep->machspec->page_offset)
#define VMALLOC_START (machdep->machspec->vmalloc_start_addr)
@@ -3106,6 +3101,9 @@ typedef u64 pte_t;
#define MODULES_VADDR (machdep->machspec->modules_vaddr)
#define MODULES_END (machdep->machspec->modules_end)
+#define PTOV(X) arm64_PTOV((ulong)(X))
+#define VTOP(X) arm64_VTOP((ulong)(X))
+
#define IS_VMALLOC_ADDR(X) arm64_IS_VMALLOC_ADDR((ulong)(X))
#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
@@ -5910,6 +5908,7 @@ void unwind_backtrace(struct bt_info *);
void arm64_init(int);
void arm64_dump_machdep_table(ulong);
ulong arm64_VTOP(ulong);
+ulong arm64_PTOV(ulong);
int arm64_IS_VMALLOC_ADDR(ulong);
ulong arm64_swp_type(ulong);
ulong arm64_swp_offset(ulong);
--
2.30.2

View File

@ -1,335 +0,0 @@
From 2f967fb5ebd737ce5eadba462df35935122e8865 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:33 -0700
Subject: [PATCH 16/27] crash_taget: fetch_registers support
Provides API for crash_target to fetch registers of given
CPU. It will allow gdb to perform such commands as "bt",
"frame", "info locals".
Highlevel API is crash_get_cpu_reg (). It calls machine
(architecture) specific function: machdep->get_cpu_reg().
Input arguments such as register number and register size
come from gdb arch information. So, get_cpu_regs()
implementations in crash must understand it.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
crash_target.c | 33 +++++++++++++++++++++++++++++++-
defs.h | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
gdb_interface.c | 19 +++++++++++++-----
vmware_vmss.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-
x86_64.c | 16 ++++++++++++++++
5 files changed, 163 insertions(+), 7 deletions(-)
diff --git a/crash_target.c b/crash_target.c
index a123329019f5..455480679741 100644
--- a/crash_target.c
+++ b/crash_target.c
@@ -27,6 +27,8 @@ void crash_target_init (void);
extern "C" int gdb_readmem_callback(unsigned long, void *, int, int);
extern "C" int crash_get_nr_cpus(void);
+extern "C" int crash_get_cpu_reg (int cpu, int regno, const char *regname,
+ int regsize, void *val);
/* The crash target. */
@@ -44,6 +46,7 @@ public:
const target_info &info () const override
{ return crash_target_info; }
+ void fetch_registers (struct regcache *, int) override;
enum target_xfer_status xfer_partial (enum target_object object,
const char *annex,
gdb_byte *readbuf,
@@ -54,13 +57,35 @@ public:
bool has_all_memory () override { return true; }
bool has_memory () override { return true; }
bool has_stack () override { return true; }
- bool has_registers () override { return false; }
+ bool has_registers () override { return true; }
bool thread_alive (ptid_t ptid) override { return true; }
std::string pid_to_str (ptid_t ptid) override
{ return string_printf ("CPU %ld", ptid.tid ()); }
};
+/* We just get all the registers, so we don't use regno. */
+void
+crash_target::fetch_registers (struct regcache *regcache, int regno)
+{
+ gdb_byte regval[16];
+ int cpu = inferior_ptid.tid();
+ struct gdbarch *arch = regcache->arch ();
+
+ for (int r = 0; r < gdbarch_num_regs (arch); r++)
+ {
+ const char *regname = gdbarch_register_name(arch, r);
+ int regsize = register_size (arch, r);
+ if (regsize > sizeof (regval))
+ error (_("fatal error: buffer size is not enough to fit register value"));
+
+ if (crash_get_cpu_reg (cpu, r, regname, regsize, (void *)&regval))
+ regcache->raw_supply (r, regval);
+ else
+ regcache->raw_supply (r, NULL);
+ }
+}
+
enum target_xfer_status
crash_target::xfer_partial (enum target_object object, const char *annex,
@@ -101,4 +126,10 @@ crash_target_init (void)
if (!i)
switch_to_thread (thread);
}
+
+ /* Fetch all registers from core file. */
+ target_fetch_registers (get_current_regcache (), -1);
+
+ /* Now, set up the frame cache. */
+ reinit_frame_cache ();
}
diff --git a/defs.h b/defs.h
index db0bd9ca9fe8..b34c60e9a795 100644
--- a/defs.h
+++ b/defs.h
@@ -1013,6 +1013,7 @@ struct machdep_table {
ulong (*processor_speed)(void);
int (*uvtop)(struct task_context *, ulong, physaddr_t *, int);
int (*kvtop)(struct task_context *, ulong, physaddr_t *, int);
+ int (*get_cpu_reg)(int, int, const char *, int, void *);
ulong (*get_task_pgd)(ulong);
void (*dump_irq)(int);
void (*get_stack_frame)(struct bt_info *, ulong *, ulong *);
@@ -6858,6 +6859,7 @@ int vmware_vmss_get_nr_cpus(void);
int vmware_vmss_get_cr3_cr4_idtr(int, ulong *, ulong *, ulong *);
int vmware_vmss_phys_base(ulong *phys_base);
int vmware_vmss_set_phys_base(ulong);
+int vmware_vmss_get_cpu_reg(int, int, const char *, int, void *);
/*
* vmware_guestdump.c
@@ -7282,4 +7284,53 @@ extern int have_full_symbols(void);
#define XEN_HYPERVISOR_ARCH
#endif
+/*
+ * Register numbers must be in sync with gdb/features/i386/64bit-core.c
+ * to make crash_target->fetch_registers() ---> machdep->get_cpu_reg()
+ * working properly.
+ */
+enum x86_64_regnum {
+ RAX_REGNUM,
+ RBX_REGNUM,
+ RCX_REGNUM,
+ RDX_REGNUM,
+ RSI_REGNUM,
+ RDI_REGNUM,
+ RBP_REGNUM,
+ RSP_REGNUM,
+ R8_REGNUM,
+ R9_REGNUM,
+ R10_REGNUM,
+ R11_REGNUM,
+ R12_REGNUM,
+ R13_REGNUM,
+ R14_REGNUM,
+ R15_REGNUM,
+ RIP_REGNUM,
+ EFLAGS_REGNUM,
+ CS_REGNUM,
+ SS_REGNUM,
+ DS_REGNUM,
+ ES_REGNUM,
+ FS_REGNUM,
+ GS_REGNUM,
+ ST0_REGNUM,
+ ST1_REGNUM,
+ ST2_REGNUM,
+ ST3_REGNUM,
+ ST4_REGNUM,
+ ST5_REGNUM,
+ ST6_REGNUM,
+ ST7_REGNUM,
+ FCTRL_REGNUM,
+ FSTAT_REGNUM,
+ FTAG_REGNUM,
+ FISEG_REGNUM,
+ FIOFF_REGNUM,
+ FOSEG_REGNUM,
+ FOOFF_REGNUM,
+ FOP_REGNUM,
+ LAST_REGNUM
+};
+
#endif /* !GDB_COMMON */
diff --git a/gdb_interface.c b/gdb_interface.c
index bcca080eb8b4..ce88d5a7c338 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -698,11 +698,10 @@ static char *prohibited_list[] = {
"run", "r", "break", "b", "tbreak", "hbreak", "thbreak", "rbreak",
"watch", "rwatch", "awatch", "attach", "continue", "c", "fg", "detach",
"finish", "handle", "interrupt", "jump", "kill", "next", "nexti",
- "signal", "step", "s", "stepi", "target", "thread", "until", "delete",
- "clear", "disable", "enable", "condition", "ignore", "frame",
- "select-frame", "f", "up", "down", "catch", "tcatch", "return",
- "file", "exec-file", "core-file", "symbol-file", "load", "si", "ni",
- "shell", "sy",
+ "signal", "step", "s", "stepi", "target", "until", "delete",
+ "clear", "disable", "enable", "condition", "ignore", "frame", "catch",
+ "tcatch", "return", "file", "exec-file", "core-file", "symbol-file",
+ "load", "si", "ni", "shell", "sy",
NULL /* must be last */
};
@@ -1067,6 +1066,8 @@ unsigned long crash_get_kaslr_offset(void)
/* Callbacks for crash_target */
int crash_get_nr_cpus(void);
+int crash_get_cpu_reg (int cpu, int regno, const char *regname,
+ int regsize, void *val);
int crash_get_nr_cpus(void)
{
@@ -1083,3 +1084,11 @@ int crash_get_nr_cpus(void)
return 1;
}
+int crash_get_cpu_reg (int cpu, int regno, const char *regname,
+ int regsize, void *value)
+{
+ if (!machdep->get_cpu_reg)
+ return FALSE;
+ return machdep->get_cpu_reg(cpu, regno, regname, regsize, value);
+}
+
diff --git a/vmware_vmss.c b/vmware_vmss.c
index 52d58e87d1c5..948a83817847 100644
--- a/vmware_vmss.c
+++ b/vmware_vmss.c
@@ -1,7 +1,7 @@
/*
* vmware_vmss.c
*
- * Copyright (c) 2015 VMware, Inc.
+ * Copyright (c) 2015, 2020 VMware, Inc.
* Copyright (c) 2018 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -16,6 +16,7 @@
*
* Authors: Dyno Hongjun Fu <hfu@vmware.com>
* Sergio Lopez <slp@redhat.com>
+ * Alexey Makhalov <amakhalov@vmware.com>
*/
#include "defs.h"
@@ -891,6 +892,54 @@ vmware_vmss_get_cr3_cr4_idtr(int cpu, ulong *cr3, ulong *cr4, ulong *idtr)
return TRUE;
}
+int
+vmware_vmss_get_cpu_reg(int cpu, int regno, const char *name, int size,
+ void *value)
+{
+ if (cpu >= vmss.num_vcpus)
+ return FALSE;
+
+ /* All supported registers are 8 bytes long. */
+ if (size != 8)
+ return FALSE;
+
+#define CASE(R,r) \
+ case R##_REGNUM: \
+ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_##R)) \
+ return FALSE; \
+ memcpy(value, &vmss.regs64[cpu]->r, size); \
+ break
+
+
+ switch (regno) {
+ CASE (RAX, rax);
+ CASE (RBX, rbx);
+ CASE (RCX, rcx);
+ CASE (RDX, rdx);
+ CASE (RSI, rsi);
+ CASE (RDI, rdi);
+ CASE (RBP, rbp);
+ CASE (RSP, rsp);
+ CASE (R8, r8);
+ CASE (R9, r9);
+ CASE (R10, r10);
+ CASE (R11, r11);
+ CASE (R12, r12);
+ CASE (R13, r13);
+ CASE (R14, r14);
+ CASE (R15, r15);
+ CASE (RIP, rip);
+ case EFLAGS_REGNUM:
+ if (!(vmss.vcpu_regs[cpu] & REGS_PRESENT_RFLAGS))
+ return FALSE;
+ memcpy(value, &vmss.regs64[cpu]->rflags, size);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
int
vmware_vmss_phys_base(ulong *phys_base)
{
diff --git a/x86_64.c b/x86_64.c
index 4f34afac06f9..d0565ba26a0c 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -126,6 +126,7 @@ static int x86_64_get_framesize(struct bt_info *, ulong, ulong);
static void x86_64_framesize_debug(struct bt_info *);
static void x86_64_get_active_set(void);
static int x86_64_get_kvaddr_ranges(struct vaddr_range *);
+static int x86_64_get_cpu_reg(int, int, const char *, int, void *);
static int x86_64_verify_paddr(uint64_t);
static void GART_init(void);
static void x86_64_exception_stacks_init(void);
@@ -194,6 +195,7 @@ x86_64_init(int when)
machdep->machspec->irq_eframe_link = UNINITIALIZED;
machdep->machspec->irq_stack_gap = UNINITIALIZED;
machdep->get_kvaddr_ranges = x86_64_get_kvaddr_ranges;
+ machdep->get_cpu_reg = x86_64_get_cpu_reg;
if (machdep->cmdline_args[0])
parse_cmdline_args();
if ((string = pc->read_vmcoreinfo("relocate"))) {
@@ -884,6 +886,7 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, " is_page_ptr: x86_64_is_page_ptr()\n");
fprintf(fp, " verify_paddr: x86_64_verify_paddr()\n");
fprintf(fp, " get_kvaddr_ranges: x86_64_get_kvaddr_ranges()\n");
+ fprintf(fp, " get_cpu_reg: x86_64_get_cpu_reg()\n");
fprintf(fp, " init_kernel_pgd: x86_64_init_kernel_pgd()\n");
fprintf(fp, "clear_machdep_cache: x86_64_clear_machdep_cache()\n");
fprintf(fp, " xendump_p2m_create: %s\n", PVOPS_XEN() ?
@@ -8934,6 +8937,19 @@ x86_64_get_kvaddr_ranges(struct vaddr_range *vrp)
return cnt;
}
+static int
+x86_64_get_cpu_reg(int cpu, int regno, const char *name,
+ int size, void *value)
+{
+ if (regno >= LAST_REGNUM)
+ return FALSE;
+
+ if (VMSS_DUMPFILE())
+ return vmware_vmss_get_cpu_reg(cpu, regno, name, size, value);
+
+ return FALSE;
+}
+
/*
* Determine the physical memory range reserved for GART.
*/
--
2.30.2

View File

@ -1,33 +0,0 @@
From e832e0eb5bd8d97dfa9f4bd0e22fbfad849c11df Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:34 -0700
Subject: [PATCH 17/27] Allow 'gdb disassemble' command for relocated kernel
As new gdb is able to handle it properly.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
gdb_interface.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/gdb_interface.c b/gdb_interface.c
index ce88d5a7c338..d3e1484f8dd9 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -741,13 +741,6 @@ is_restricted_command(char *cmd, ulong flags)
}
}
- if (kt->relocate &&
- STRNEQ("disassemble", cmd) && STRNEQ(cmd, "disas"))
- error(FATAL,
- "the gdb \"disassemble\" command is prohibited because the kernel text\n"
- "%swas relocated%s; use the crash \"dis\" command instead.\n",
- space(strlen(pc->curcmd)+2), kt->flags2 & KASLR ? " by KASLR" : "");
-
return FALSE;
}
--
2.30.2

View File

@ -1,45 +0,0 @@
From 96716862765f73676bfdb2d19fc5872364d21b73 Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:35 -0700
Subject: [PATCH 18/27] vmware backend: honor silence flag
Do not print any boot messages in silence (-s) mode.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
vmware_vmss.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/vmware_vmss.c b/vmware_vmss.c
index 948a83817847..f6c5f32ea4c0 100644
--- a/vmware_vmss.c
+++ b/vmware_vmss.c
@@ -444,11 +444,13 @@ vmware_vmss_init(char *filename, FILE *ofp)
if (vmss.memsize == 0) {
char *vmem_filename, *p;
- fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n");
+ if (!(pc->flags & SILENT))
+ fprintf(ofp, LOGPRX"Memory dump is not part of this vmss file.\n");
fclose(fp);
fp = NULL;
- fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n");
+ if (!(pc->flags & SILENT))
+ fprintf(ofp, LOGPRX"Try to locate the companion vmem file ...\n");
/* check the companion vmem file */
vmem_filename = strdup(filename);
p = vmem_filename + strlen(vmem_filename) - 4;
@@ -471,7 +473,8 @@ vmware_vmss_init(char *filename, FILE *ofp)
vmss.separate_vmem = TRUE;
vmss.filename = filename;
- fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
+ if (!(pc->flags & SILENT))
+ fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
free(vmem_filename);
}
--
2.30.2

View File

@ -1,31 +0,0 @@
From 6c5f0c6ff5d158f2ef4fa997a052b0643d0c25ee Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Fri, 19 Mar 2021 21:07:36 -0700
Subject: [PATCH 19/27] vmware_guestdump: add debugging of the init function
Dump memory and registers state after parsing.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
vmware_guestdump.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/vmware_guestdump.c b/vmware_guestdump.c
index 62da0a77a227..cf818e588a60 100644
--- a/vmware_guestdump.c
+++ b/vmware_guestdump.c
@@ -267,6 +267,11 @@ vmware_guestdump_init(char *filename, FILE *ofp)
fseek(vmss.dfp, 0L, SEEK_SET);
fprintf(ofp, LOGPRX"vmem file: %s\n\n", vmem_filename);
+ if (CRASHDEBUG(1)) {
+ vmware_guestdump_memory_dump(ofp);
+ dump_registers_for_vmss_dump();
+ }
+
exit:
if (fp)
fclose(fp);
--
2.30.2

View File

@ -1,65 +0,0 @@
From 8d6f677e54a2474b3da19402e29278b62603d71d Mon Sep 17 00:00:00 2001
From: Alexey Makhalov <amakhalov@vmware.com>
Date: Thu, 8 Jul 2021 16:14:02 -0700
Subject: [PATCH 20/27] Do not adjust addr by relocate offset(KASLR)
GBD symbol resolution already considers relocation (KASLR) offset.
So, there is no needs to adjust the function address before calling
GDB.
It fixes file name and line number output for 'dis -l' and 'sys -c'
commands.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
---
gdb_interface.c | 3 +--
kernel.c | 3 +--
symbols.c | 3 +--
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/gdb_interface.c b/gdb_interface.c
index d3e1484f8dd9..b098ed823d55 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -1013,8 +1013,7 @@ gdb_set_crash_scope(ulong vaddr, char *arg)
return FALSE;
}
}
- } else if (kt->flags2 & KASLR)
- vaddr -= (kt->relocate * -1);
+ }
}
req->command = GNU_SET_CRASH_BLOCK;
diff --git a/kernel.c b/kernel.c
index 6b586dbb05c1..6a812ac7b1bc 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1484,8 +1484,7 @@ list_source_code(struct gnu_request *req, int count_entered)
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();
diff --git a/symbols.c b/symbols.c
index 338af2ce5038..5d3c53a30abc 100644
--- a/symbols.c
+++ b/symbols.c
@@ -4296,8 +4296,7 @@ get_line_number(ulong addr, char *buf, int reserved)
if (module_symbol(addr, NULL, &lm, NULL, 0)) {
if (!(lm->mod_flags & MOD_LOAD_SYMS))
return(buf);
- } else if (kt->flags2 & KASLR)
- addr -= (kt->relocate * -1);
+ }
if ((lnh = machdep->line_number_hooks)) {
name = closest_symbol(addr);
--
2.30.2

View File

@ -1,44 +0,0 @@
From fce91bec5bef534e52f3261cc289a21a2cdb5fe3 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Sun, 11 Jul 2021 22:30:22 +0800
Subject: [PATCH 21/27] Fix the failure of reporting vmcore and vmlinux do not
match for kernels(<2.6.11)
There is a regression issue for kernels(<2.6.11) as below:
$ crash 2.6.9-68.9/vmcore 2.6.9-68.9/vmlinux.gz
...
GNU gdb (GDB) 10.2
...
crash: /var/tmp/vmlinux.gz_GLsAvX and 2.6.9-68.9/vmcore do not match!
The reason is that it needs to read out the address of linux banner with
readmem() first, and then the read_string() will be able to read the data
from linux banner. So, for the kernels(<2.6.11) case, lets still invoke
get_symbol_data() to accomplish this. See the changes:
[1] https://elixir.bootlin.com/linux/v2.6.10/source/init/version.c#L38
[2] https://elixir.bootlin.com/linux/v2.6.11/source/init/version.c#L38
Signed-off-by: Tao Liu <ltao@redhat.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel.c b/kernel.c
index 6a812ac7b1bc..a559f937980e 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1052,7 +1052,8 @@ verify_version(void)
if (!(sp = symbol_search("linux_banner")))
error(FATAL, "linux_banner symbol does not exist?\n");
- else if ((sp->type == 'R') || (sp->type == 'r') || (sp->type == 'D') ||
+ else if ((sp->type == 'R') || (sp->type == 'r') ||
+ (THIS_KERNEL_VERSION >= LINUX(2,6,11) && sp->type == 'D') ||
(machine_type("ARM") && sp->type == 'T') ||
(machine_type("ARM64")))
linux_banner = symbol_value("linux_banner");
--
2.30.2

View File

@ -1,90 +0,0 @@
From 51f21b0d1c91a4ae02ebf0d8c81460ec8b6c1283 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Thu, 15 Jul 2021 17:34:29 +0800
Subject: [PATCH 22/27] x86_64_irq_eframe_link_init: Fix wrong instruction
searching range calculation
In function x86_64_irq_eframe_link_init, instruction "push xxx" is searched in
addresses range from "common_interrupt" to the next nearby symbol, in order to
calculate the value of irq_eframe_link. The searching distance is given by
max_instructions, which is calculated by end ranging address minus start ranging
address. Then crash asks gdb to disassemble max_instructions quantity of instructions.
Taking max_instructions as the quantity of disassemble instructions is inappropriate,
because most x86_64 instructions have a length longer than 1, as a consequence, much
more than the actual needed instructions get disassembled.
In gdb-7.6 crash, the extra instructions are skipped by "if (!strstr(buf, sp->name))",
which breaks if one instruction doesn't belongs to a symbol:
0xffffffff8005d5b4 <common_interrupt+0>: cld
0xffffffff8005d5b5 <common_interrupt+1>: sub $0x48,%rsp
...
0xffffffff8005d61e <common_interrupt+106>: leaveq
0xffffffff8005d61f <exit_intr>: mov %gs:0x10,%rcx <--- searching stops here
...
In gdb-10.2 crash, "exit_intr" doesn't show, however it really exist. As a result,
searching for "push xxx" will go to a wrong place.
0xffffffff8005d5b4 <common_interrupt+0>: cld
0xffffffff8005d5b5 <common_interrupt+1>: sub $0x48,%rsp
...
0xffffffff8005d61e <common_interrupt+106>: leave
0xffffffff8005d61f <common_interrupt+107>: mov %gs:0x10,%rcx <--- searching continues
...
(gdb) p exit_intr
$1 = {<text variable, no debug info>} 0xffffffff8005d61f <common_interrupt+107>
(gdb) info symbol exit_intr
common_interrupt + 107 in section .text
The previous way to determine start and end searching range is not stable, otherwise we may
encounter regression that cmd "bt" prints wrong IRQ stack. This patch fix the bug by removing
max_instructions calculation, and directly ask gdb to disassemble addresses range from
"common_interrupt" to the next nearby symbol.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
x86_64.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index d0565ba26a0c..552d6194930b 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -6472,7 +6472,6 @@ x86_64_irq_eframe_link_init(void)
char buf[BUFSIZE];
char link_register[BUFSIZE];
char *arglist[MAXARGS];
- ulong max_instructions;
if (machdep->machspec->irq_eframe_link == UNINITIALIZED)
machdep->machspec->irq_eframe_link = 0;
@@ -6487,12 +6486,10 @@ x86_64_irq_eframe_link_init(void)
return;
}
- max_instructions = spn->value - sp->value;
-
open_tmpfile();
- sprintf(buf, "x/%ldi 0x%lx",
- max_instructions, sp->value);
+ sprintf(buf, "disassemble 0x%lx, 0x%lx",
+ sp->value, spn->value);
if (!gdb_pass_through(buf, pc->tmpfile, GNU_RETURN_ON_ERROR))
return;
@@ -6501,6 +6498,8 @@ x86_64_irq_eframe_link_init(void)
rewind(pc->tmpfile);
while (fgets(buf, BUFSIZE, pc->tmpfile)) {
+ if (STRNEQ(buf, "Dump of assembler code"))
+ continue;
if (!strstr(buf, sp->name))
break;
if ((c = parse_line(buf, arglist)) < 4)
--
2.30.2

View File

@ -1,49 +0,0 @@
From b8e1f2735b8dd1303aeb2affa309a2a409a82d38 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Mon, 26 Jul 2021 09:58:54 +0800
Subject: [PATCH 23/27] Add kernel version dependent check for getting length
of log_end
For kernels(>=2.4.9.11 [1] && <3.5 [2]), log_end was involved in the kernel sources.
For kernels(>=2.6.25 [3]), log_end was defined as:
static unsigned log_end;
For kernels(<2.6.25), log_end was defined as:
static unsigned long log_end;
Previously, the length of log_end is determined by get_symbol_length, but it can
be a regression when the returned length is 0 for some cases and value unchecked:
crash> help -t
...
help: invalid size request: 0 type: "log_end"
To solve the above issue, let's add a kernel version dependent check to get its
value appropriately when the length of the 'log_end' returns a value of zero.
[1]: https://elixir.bootlin.com/linux/2.4.9.11/source/kernel/printk.c#L74
[2]: https://elixir.bootlin.com/linux/v3.5/source/kernel/printk.c
[3]: https://elixir.bootlin.com/linux/v2.6.25/source/kernel/printk.c#L104
Signed-off-by: Tao Liu <ltao@redhat.com>
---
kernel.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel.c b/kernel.c
index a559f937980e..a8be7bb1947f 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5106,6 +5106,10 @@ dump_log(int msg_flags)
if ((len = get_symbol_length("log_end")) == sizeof(int)) {
get_symbol_data("log_end", len, &tmp);
log_end = (ulong)tmp;
+ } else if (len == 0) {
+ THIS_KERNEL_VERSION >= LINUX(2,6,25) ?
+ get_symbol_data("log_end", sizeof(unsigned), &log_end) :
+ get_symbol_data("log_end", sizeof(unsigned long), &log_end);
} else
get_symbol_data("log_end", len, &log_end);
--
2.30.2

View File

@ -1,39 +0,0 @@
From 5c2d8d2d9da6423eec076fd51049d7b4677b61c6 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Tue, 17 Aug 2021 16:21:43 +0800
Subject: [PATCH 24/27] Set gdb max-value-size to be unlimited
gdb-10.2 uses max-value-size as the maximum size in bytes that the contents
of a object may allocate. The default value of max-value-size is 64K. However,
it could be not enough for allocating an object which requires larger space, and
failed at the startup of crash.
In gdb-7.6, there is no max-value-size check and works fine. So in this patch,
let's just set max-value-size to be unlimited.
Signed-off-by: Tao Liu <ltao@redhat.com>
---
gdb_interface.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/gdb_interface.c b/gdb_interface.c
index b098ed823d55..2fe9ccde83a1 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -300,6 +300,13 @@ retry:
sprintf(req->buf, "set width 0");
gdb_interface(req);
+#ifdef GDB_10_2
+ req->command = GNU_PASS_THROUGH;
+ req->name = NULL, req->flags = 0;
+ sprintf(req->buf, "set max-value-size unlimited");
+ gdb_interface(req);
+#endif
+
#if 0
/*
* Patch gdb's symbol values with the correct values from either
--
2.30.2

View File

@ -1,55 +0,0 @@
From c1e256249426dd59ceea99038451a39e98a26790 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Thu, 19 Aug 2021 10:52:58 +0900
Subject: [PATCH 25/27] Fix tab completion issues
1. The maximum number of tab completion candidates is limited to 200
by default. Set it unlimited.
2. The output of tab completion is not wrapped with the screen width.
Get and use it when tab completion is invoked.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
gdb-10.2.patch | 11 +++++++++++
gdb_interface.c | 5 +++++
2 files changed, 16 insertions(+)
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index 4f8d418b17ed..1332b6638028 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -1580,3 +1580,14 @@
_rl_tracefp = 0;
return r;
}
+--- gdb-10.2/gdb/completer.c.orig
++++ gdb-10.2/gdb/completer.c
+@@ -2949,6 +2949,8 @@
+
+ /* How many items of MAX length can we fit in the screen window? */
+ cols = gdb_complete_get_screenwidth (displayer);
++ rl_reset_screen_size();
++ rl_get_screen_size(NULL, &cols);
+ max += 2;
+ limit = cols / max;
+ if (limit != 1 && (limit * max == cols))
diff --git a/gdb_interface.c b/gdb_interface.c
index 2fe9ccde83a1..ff45cdcd39ae 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -305,6 +305,11 @@ retry:
req->name = NULL, req->flags = 0;
sprintf(req->buf, "set max-value-size unlimited");
gdb_interface(req);
+
+ req->command = GNU_PASS_THROUGH;
+ req->name = NULL, req->flags = 0;
+ sprintf(req->buf, "set max-completions unlimited");
+ gdb_interface(req);
#endif
#if 0
--
2.30.2

View File

@ -1,402 +0,0 @@
From 05a3a328fcd8920e49926b6d1c9c81ce0b6acbca Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Thu, 9 Sep 2021 15:23:27 +0900
Subject: [PATCH 26/27] Remove text value cache code
The text value cache was implemented for analysis of remote dumpfiles
using the deprecated "crash daemon" running on the remote host. On
updating GDB to 10.2, a regression occurred when we tried to fix a
"help -x" command problem, and there was no performance degradation
even without the text cache, so let's drop this functionality.
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
alpha.c | 8 +-
cmdline.c | 1 -
defs.h | 4 -
gdb_interface.c | 14 ----
help.c | 8 +-
kernel.c | 1 -
symbols.c | 196 ------------------------------------------------
x86.c | 7 --
8 files changed, 3 insertions(+), 236 deletions(-)
diff --git a/alpha.c b/alpha.c
index fa2d5f5935c9..73497120b4bf 100644
--- a/alpha.c
+++ b/alpha.c
@@ -776,12 +776,8 @@ alpha_frame_offset(struct gnu_request *req, ulong alt_pc)
* Don't go any farther than "stq ra,0(sp)" (0xb75e0000)
*/
while (ival != 0xb75e0000) {
- if (!text_value_cache((ulong)ip, 0, &ival)) {
- readmem((ulong)ip, KVADDR, &ival,
- sizeof(uint), "uncached text value",
- FAULT_ON_ERROR);
- text_value_cache((ulong)ip, ival, NULL);
- }
+ readmem((ulong)ip, KVADDR, &ival, sizeof(uint),
+ "text value", FAULT_ON_ERROR);
if ((ival & 0xffe01fff) == 0x43c0153e) {
value = (ival & 0x1fe000) >> 13;
diff --git a/cmdline.c b/cmdline.c
index 796f7c58f243..ded6551c2597 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -1235,7 +1235,6 @@ restore_sanity(void)
if (CRASHDEBUG(5)) {
dump_filesys_table(0);
dump_vma_cache(0);
- dump_text_value_cache(0);
}
if (REMOTE())
diff --git a/defs.h b/defs.h
index b34c60e9a795..cbd45e52f9da 100644
--- a/defs.h
+++ b/defs.h
@@ -5327,10 +5327,6 @@ char *load_module_filter(char *, int);
long datatype_info(char *, char *, struct datatype_member *);
int get_symbol_type(char *, char *, struct gnu_request *);
int get_symbol_length(char *);
-int text_value_cache(ulong, uint32_t, uint32_t *);
-int text_value_cache_byte(ulong, unsigned char *);
-void dump_text_value_cache(int);
-void clear_text_value_cache(void);
void dump_numargs_cache(void);
int patch_kernel_symbol(struct gnu_request *);
struct syment *generic_machdep_value_to_symbol(ulong, ulong *);
diff --git a/gdb_interface.c b/gdb_interface.c
index ff45cdcd39ae..3a7fcc9e3ade 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -828,7 +828,6 @@ int
gdb_readmem_callback(ulong addr, void *buf, int len, int write)
{
char locbuf[SIZEOF_32BIT], *p1;
- uint32_t *p2;
int memtype;
ulong readflags;
@@ -885,19 +884,12 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
}
p1 = (char *)buf;
- if ((memtype == KVADDR) &&
- text_value_cache_byte(addr, (unsigned char *)p1))
- return TRUE;
if (!readmem(addr, memtype, locbuf, SIZEOF_32BIT,
"gdb_readmem_callback", readflags))
return FALSE;
*p1 = locbuf[0];
- if (memtype == KVADDR) {
- p2 = (uint32_t *)locbuf;
- text_value_cache(addr, *p2, 0);
- }
return TRUE;
case SIZEOF_32BIT:
@@ -907,16 +899,10 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
return TRUE;
}
- if ((memtype == KVADDR) && text_value_cache(addr, 0, buf))
- return TRUE;
-
if (!readmem(addr, memtype, buf, SIZEOF_32BIT,
"gdb_readmem callback", readflags))
return FALSE;
- if (memtype == KVADDR)
- text_value_cache(addr,
- (uint32_t)*((uint32_t *)buf), NULL);
return TRUE;
}
diff --git a/help.c b/help.c
index e67fde0018ab..c19b69b8b20c 100644
--- a/help.c
+++ b/help.c
@@ -535,7 +535,7 @@ cmd_help(void)
oflag = 0;
while ((c = getopt(argcnt, args,
- "efNDdmM:ngcaBbHhkKsvVoptTzLxOr")) != EOF) {
+ "efNDdmM:ngcaBbHhkKsvVoptTzLOr")) != EOF) {
switch(c)
{
case 'e':
@@ -551,10 +551,6 @@ cmd_help(void)
dumpfile_memory(DUMPFILE_MEM_DUMP);
return;
- case 'x':
- dump_text_value_cache(VERBOSE);
- return;
-
case 'd':
dump_dev_table();
return;
@@ -666,7 +662,6 @@ cmd_help(void)
fprintf(fp, " -T - task_table plus context_array\n");
fprintf(fp, " -v - vm_table\n");
fprintf(fp, " -V - vm_table (verbose)\n");
- fprintf(fp, " -x - text cache\n");
fprintf(fp, " -z - help options\n");
return;
@@ -1026,7 +1021,6 @@ char *help_help[] = {
" -T - task_table plus context_array",
" -v - vm_table",
" -V - vm_table (verbose)",
-" -x - text cache",
" -z - help options",
NULL
};
diff --git a/kernel.c b/kernel.c
index a8be7bb1947f..3ead4bbb172e 100644
--- a/kernel.c
+++ b/kernel.c
@@ -4661,7 +4661,6 @@ reinit_modules(void)
st->ext_module_symtable = NULL;
st->load_modules = NULL;
kt->mods_installed = 0;
- clear_text_value_cache();
module_init();
}
diff --git a/symbols.c b/symbols.c
index 5d3c53a30abc..69dccdb09d5f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -12824,202 +12824,6 @@ gnu_qsort(bfd *bfd,
qsort(minisyms, symcount, size, numeric_forward);
}
-/*
- * Keep a stash of commonly-accessed text locations checked by the
- * back_trace code. The saved values unsigned 32-bit values.
- * The same routine is used to store and query, based upon whether
- * the passed-in value and valptr args are non-zero.
- */
-#define TEXT_CACHE (50)
-#define MAX_TEXT_CACHE (TEXT_CACHE*4)
-
-struct text_cache_entry {
- ulong vaddr;
- uint32_t value;
-};
-
-static struct text_cache {
- int index;
- int entries;
- ulong hits;
- ulong refs;
- struct text_cache_entry *cache;
-} text_cache = { 0 };
-
-/*
- * Cache the contents of 32-bit text addresses. If "value" is set, the purpose
- * is to cache it. If "valptr" is set, a query is being made for the text
- * address.
- */
-int
-text_value_cache(ulong vaddr, uint32_t value, uint32_t *valptr)
-{
- int i;
- struct text_cache *tc;
-
- if (!is_kernel_text(vaddr))
- return FALSE;
-
- tc = &text_cache;
-
- if (!tc->cache) {
- if (!(tc->cache = (struct text_cache_entry *)
- malloc(sizeof(struct text_cache_entry) * TEXT_CACHE)))
- return FALSE;
- BZERO(tc->cache, sizeof(struct text_cache_entry) * TEXT_CACHE);
- tc->index = 0;
- tc->entries = TEXT_CACHE;
- }
-
- if (value) {
- for (i = 0; i < tc->entries; i++) {
- if (tc->cache[i].vaddr == vaddr)
- return TRUE;
- }
-
- i = tc->index;
- tc->cache[i].vaddr = vaddr;
- tc->cache[i].value = value;
- tc->index++;
- if (tc->index == MAX_TEXT_CACHE) {
- tc->index = 0;
- } else if (tc->index == tc->entries) {
- struct text_cache_entry *old_cache;
-
- old_cache = tc->cache;
- if ((tc->cache = (struct text_cache_entry *)
- realloc(old_cache, sizeof(struct text_cache_entry) *
- (TEXT_CACHE+tc->entries)))) {
- BZERO(&tc->cache[tc->index],
- sizeof(struct text_cache_entry) *
- TEXT_CACHE);
- tc->entries += TEXT_CACHE;
- } else {
- tc->cache = old_cache;
- tc->index = 0;
- }
- }
- return TRUE;
- }
-
- if (valptr) {
- tc->refs++;
-
- for (i = 0; i < tc->entries; i++) {
- if (!tc->cache[i].vaddr)
- return FALSE;
-
- if (tc->cache[i].vaddr == vaddr) {
- *valptr = tc->cache[i].value;
- tc->hits++;
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-/*
- * The gdb disassembler reads text memory byte-by-byte, so this routine
- * acts as a front-end to the 32-bit (4-byte) text storage.
- */
-
-int
-text_value_cache_byte(ulong vaddr, unsigned char *valptr)
-{
- int i;
- int shift;
- struct text_cache *tc;
- ulong valtmp;
-
- if (!is_kernel_text(vaddr))
- return FALSE;
-
- tc = &text_cache;
-
- tc->refs++;
-
- for (i = 0; i < tc->entries; i++) {
- if (!tc->cache[i].vaddr)
- return FALSE;
-
- if ((vaddr >= tc->cache[i].vaddr) &&
- (vaddr < (tc->cache[i].vaddr+SIZEOF_32BIT))) {
- valtmp = tc->cache[i].value;
- shift = (vaddr - tc->cache[i].vaddr) * 8;
- valtmp >>= shift;
- *valptr = valtmp & 0xff;
- tc->hits++;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-dump_text_value_cache(int verbose)
-{
- int i;
- struct syment *sp;
- ulong offset;
- struct text_cache *tc;
-
- tc = &text_cache;
-
- if (!verbose) {
- if (!tc->refs || !tc->cache)
- return;
-
- fprintf(stderr, " text hit rate: %2ld%% (%ld of %ld)\n",
- (tc->hits * 100)/tc->refs,
- (ulong)tc->hits, (ulong)tc->refs);
- return;
- }
-
- for (i = 0; tc->cache && (i < tc->entries); i++) {
- if (!tc->cache[i].vaddr)
- break;
- fprintf(fp, "[%2d]: %lx %08x ", i, tc->cache[i].vaddr,
- tc->cache[i].value);
- if ((sp = value_search(tc->cache[i].vaddr, &offset))) {
- fprintf(fp, "(%s+", sp->name);
- switch (pc->output_radix)
- {
- case 10:
- fprintf(fp, "%ld)", offset);
- break;
- case 16:
- fprintf(fp, "%lx)", offset);
- break;
- }
- }
- fprintf(fp, "\n");
- }
-
- fprintf(fp,
- "text_cache entries: %d index: %d hit rate: %ld%% (%ld of %ld)\n",
- tc->entries, tc->index,
- (tc->hits * 100)/(tc->refs ? tc->refs : 1),
- tc->hits, tc->refs);
-
-}
-
-void
-clear_text_value_cache(void)
-{
- int i;
- struct text_cache *tc;
-
- tc = &text_cache;
- tc->index = 0;
-
- for (i = 0; tc->cache && (i < tc->entries); i++) {
- tc->cache[i].vaddr = 0;
- tc->cache[i].value = 0;
- }
-}
-
/*
* If a System.map file or a debug kernel was specified, the name hash
* has been filled -- so sync up gdb's notion of symbol values with
diff --git a/x86.c b/x86.c
index a174bbc7737c..b36f44c54819 100644
--- a/x86.c
+++ b/x86.c
@@ -474,17 +474,10 @@ db_get_value(addr, size, is_signed, bt)
else
GET_STACK_DATA(addr, data, size);
} else {
- if ((size == sizeof(int)) &&
- text_value_cache(addr, 0, (uint32_t *)&value))
- return value;
-
if (!readmem(addr, KVADDR, &value, size, "db_get_value",
RETURN_ON_ERROR))
error(FATAL, "db_get_value: read error: address: %lx\n",
addr);
-
- if (size == sizeof(int))
- text_value_cache(addr, value, NULL);
}
#endif
--
2.30.2

View File

@ -1,25 +0,0 @@
From f7e3b2d9b753793e230a5242974a111cdf139e49 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Thu, 30 Sep 2021 11:04:31 +0900
Subject: [PATCH 27/27] .gitignore: add gdb-10.2 directory
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index b39832fa71df..f391c5d340f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ crash.spec
*.rpm
gdb.files
gdb-7.6/
+gdb-10.2/
extensions/defs.h
extensions/*.so
extensions/eppic
--
2.30.2

View File

@ -3,8 +3,8 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 7.3.0
Release: 5%{?dist}
Version: 8.0.0
Release: 1%{?dist}
License: GPLv3
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
@ -18,58 +18,6 @@ Requires: binutils
Provides: bundled(libiberty)
Provides: bundled(gdb) = 10.2
Patch0: lzo_snappy.patch
Patch1: 0001-arm64-Add-lowercase-tcr_el1_t1sz.patch
Patch2: 0002-Fix-for-kmem-s-S-option-on-Linux-5.7-and-later-kerne.patch
Patch3: 0003-memory-Add-support-for-SECTION_TAINT_ZONE_DEVICE-fla.patch
Patch4: 0004-memory-Fix-for-kmem-n-option-to-display-NID-correctl.patch
Patch5: 0005-defs.h-Fix-the-value-of-TIF_SIGPENDING-macro.patch
Patch6: 0006-MIPS32-64-Add-irq-command-support.patch
Patch7: 0007-MIPS64-three-fixes-for-MIPS64-kernels.patch
Patch8: 0008-extensions-eppic.mk-Enable-use-of-alternate-eppic-br.patch
Patch9: 0009-list-add-O-option-for-specifying-head-node-offset.patch
Patch10: 0010-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch
Patch11: 0011-Fix-pvops-Xen-detection-for-kernels-v4.20.patch
Patch12: 0012-Handle-task_struct-state-member-changes-for-kernels-.patch
Patch13: 0013-arm64-rename-ARM64_PAGE_OFFSET_ACTUAL-to-ARM64_FLIP_.patch
Patch14: 0014-arm64-assign-page_offset-with-VA_BITS-kernel-configu.patch
Patch15: 0015-arm64-use-dedicated-bits-to-record-the-VA-space-layo.patch
Patch16: 0016-arm64-implement-switchable-PTOV-VTOP-for-kernels-5.1.patch
Patch17: 0001-kmem-Add-support-to-S-option-to-specify-a-range-of-C.patch
Patch18: 0002-diskdump-Fail-readmem-early-if-dump-is-incomplete.patch
Patch19: 0003-netdump-Permit-zero_excluded-for-incomplete-ELF-dump.patch
Patch20: 0004-diskdump-Print-total-number-of-dumpable-pages.patch
Patch21: 0005-diskdump-Introduce-read_pd.patch
Patch22: 0006-x86_64-Fix-check-for-__per_cpu_offset-initialization.patch
Patch23: 0007-arm64-Get-CPU-registers-from-ELF-notes-even-without-.patch
Patch24: 0008-.gitignore-Add-cscope-ctags-compile_commands.json.patch
Patch25: 0009-ppc64-Add-MMU-type-info-in-machdep-command.patch
Patch26: 0010-mod-fix-module-object-file-lookup.patch
Patch27: 0011-diskdump-Add-support-for-reading-dumpfiles-compresse.patch
Patch28: 0012-Update-to-gdb-10.2.patch
Patch29: 0013-crash_get_nr_cpus-get-nr_cpus-from-the-dumps.patch
Patch30: 0014-whatis-m-fix-duplications-in-the-output.patch
Patch31: 0015-Fix-reduced-output-of-bt-command.patch
Patch32: 0016-crash_taget-fetch_registers-support.patch
Patch33: 0017-Allow-gdb-disassemble-command-for-relocated-kernel.patch
Patch34: 0018-vmware-backend-honor-silence-flag.patch
Patch35: 0019-vmware_guestdump-add-debugging-of-the-init-function.patch
Patch36: 0020-Do-not-adjust-addr-by-relocate-offset-KASLR.patch
Patch37: 0021-Fix-the-failure-of-reporting-vmcore-and-vmlinux-do-n.patch
Patch38: 0022-x86_64_irq_eframe_link_init-Fix-wrong-instruction-se.patch
Patch39: 0023-Add-kernel-version-dependent-check-for-getting-lengt.patch
Patch40: 0024-Set-gdb-max-value-size-to-be-unlimited.patch
Patch41: 0025-Fix-tab-completion-issues.patch
Patch42: 0026-Remove-text-value-cache-code.patch
Patch43: 0027-.gitignore-add-gdb-10.2-directory.patch
Patch44: 0001-symbols-Implement-install-and-remove-operations-for-.patch
Patch45: 0002-symbols-Integrate-symbol_search-with-mod_symname_has.patch
Patch46: 0003-symbols-Extend-symname_hash_search-with-hash-table-s.patch
Patch47: 0004-symbols-Intergrate-symbol_exists-with-mod_symname_ha.patch
Patch48: 0005-symbols-Sync-module-symbols-into-mod_symtable-whenev.patch
Patch49: 0006-symbols-Refactor-SYMNAME_HASH_INDEX-macro-to-be-a-fu.patch
Patch50: 0007-symbols-Add-mod_symname_hash-table-dump-to-help-s.patch
Patch51: 0008-arm64-Use-VA_BITS-for-page_offset-calculation.patch
Patch52: 0009-Handle-task_struct-cpu-member-changes-for-kernels-5..patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -90,58 +38,6 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%prep
%setup -n %{name}-%{version} -q
%patch0 -p1 -b lzo_snappy.patch
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%build
# This package has an internal copy of GDB which has broken configure code for
@ -175,6 +71,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Wed Nov 24 2021 Lianbo Jiang <lijiang@redhat.com> - 8.0.0-1
- Rebase to upstream 8.0.0
* Sat Nov 06 2021 Lianbo Jiang <lijiang@redhat.com> - 7.3.0-5
- Update to the latest upstream: commit <68870c83d299>

View File

@ -1,5 +1,5 @@
--- crash-7.3.0/diskdump.c.orig
+++ crash-7.3.0/diskdump.c
--- crash-8.0.0/diskdump.c.orig
+++ crash-8.0.0/diskdump.c
@@ -23,6 +23,8 @@
* GNU General Public License for more details.
*/
@ -9,8 +9,8 @@
#include "defs.h"
#include "diskdump.h"
#include "xen_dom0.h"
--- crash-7.3.0/Makefile.orig
+++ crash-7.3.0/Makefile
--- crash-8.0.0/Makefile.orig
+++ crash-8.0.0/Makefile
@@ -228,7 +228,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \

View File

@ -1,442 +0,0 @@
From a5531b24750e7949c35640d996ea14c0587938bc Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Fri, 20 Nov 2020 05:56:59 +0000
Subject: [PATCH 1/2] printk: add support for lockless ringbuffer
Linux 5.10 introduces a new lockless ringbuffer. The new ringbuffer
is structured completely different to the previous iterations.
Add support for dumping the ringbuffer with the "log" command.
The new ringbuffer is detected based on the availability of
the "prb" symbol.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
Makefile | 5 ++
defs.h | 30 +++++++
kernel.c | 7 +-
printk.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
symbols.c | 27 ++++++
5 files changed, 324 insertions(+), 1 deletion(-)
create mode 100644 printk.c
diff --git a/Makefile b/Makefile
index d1857190c2fb..f66eba7418d1 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ VMWARE_HFILES=vmware_vmss.h
CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \
+ printk.c \
alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \
arm.c arm64.c mips.c sparc64.c \
extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \
@@ -80,6 +81,7 @@ SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \
+ printk.o \
alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \
arm.o arm64.o mips.o sparc64.o \
extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \
@@ -363,6 +365,9 @@ task.o: ${GENERIC_HFILES} task.c
kernel.o: ${GENERIC_HFILES} kernel.c
${CC} -c ${CRASH_CFLAGS} kernel.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+printk.o: ${GENERIC_HFILES} printk.c
+ ${CC} -c ${CRASH_CFLAGS} printk.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+
gdb_interface.o: ${GENERIC_HFILES} gdb_interface.c
${CC} -c ${CRASH_CFLAGS} gdb_interface.c ${WARNING_OPTIONS} ${WARNING_ERROR}
diff --git a/defs.h b/defs.h
index 95949507cae4..e1a18e9d0b4d 100644
--- a/defs.h
+++ b/defs.h
@@ -2106,6 +2106,28 @@ struct offset_table { /* stash of commonly-used offsets */
long irq_common_data_affinity;
long irq_desc_irq_common_data;
long uts_namespace_name;
+ long printk_info_seq;
+ long printk_info_ts_nsec;
+ long printk_info_text_len;
+ long printk_info_level;
+ long printk_info_caller_id;
+ long printk_info_dev_info;
+ long dev_printk_info_subsystem;
+ long dev_printk_info_device;
+ long prb_desc_ring;
+ long prb_text_data_ring;
+ long prb_desc_ring_count_bits;
+ long prb_desc_ring_descs;
+ long prb_desc_ring_infos;
+ long prb_desc_ring_head_id;
+ long prb_desc_ring_tail_id;
+ long prb_desc_state_var;
+ long prb_desc_text_blk_lpos;
+ long prb_data_blk_lpos_begin;
+ long prb_data_blk_lpos_next;
+ long prb_data_ring_size_bits;
+ long prb_data_ring_data;
+ long atomic_long_t_counter;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2265,6 +2287,9 @@ struct size_table { /* stash of commonly-used sizes */
long xa_node;
long zram_table_entry;
long irq_common_data;
+ long printk_info;
+ long printk_ringbuffer;
+ long prb_desc;
};
struct array_table {
@@ -6696,6 +6721,11 @@ int vmware_guestdump_memory_dump(FILE *);
*/
int calc_kaslr_offset(ulong *, ulong *);
+/*
+ * printk.c
+ */
+void dump_lockless_record_log(int);
+
/*
* gnu_binutils.c
*/
diff --git a/kernel.c b/kernel.c
index 98716372c8be..e722ff941527 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5042,6 +5042,11 @@ dump_log(int msg_flags)
struct syment *nsp;
int log_wrap, loglevel, log_buf_len;
+ if (kernel_symbol_exists("prb")) {
+ dump_lockless_record_log(msg_flags);
+ return;
+ }
+
if (kernel_symbol_exists("log_first_idx") &&
kernel_symbol_exists("log_next_idx")) {
dump_variable_length_record_log(msg_flags);
@@ -5289,7 +5294,7 @@ dump_log_entry(char *logptr, int msg_flags)
}
/*
- * Handle the new variable-length-record log_buf.
+ * Handle the variable-length-record log_buf.
*/
static void
dump_variable_length_record_log(int msg_flags)
diff --git a/printk.c b/printk.c
new file mode 100644
index 000000000000..f6d54ce9d0d8
--- /dev/null
+++ b/printk.c
@@ -0,0 +1,256 @@
+#include "defs.h"
+#include <ctype.h>
+
+#define DESC_SV_BITS (sizeof(unsigned long) * 8)
+#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1))
+#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2))
+#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK)
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
+
+/* convenience struct for passing many values to helper functions */
+struct prb_map {
+ char *prb;
+
+ char *desc_ring;
+ unsigned long desc_ring_count;
+ char *descs;
+ char *infos;
+
+ char *text_data_ring;
+ unsigned long text_data_ring_size;
+ char *text_data;
+};
+
+static void
+init_offsets(void)
+{
+ char *n;
+
+ n = "printk_info";
+ STRUCT_SIZE_INIT(printk_info, n);
+ MEMBER_OFFSET_INIT(printk_info_seq, n, "seq");
+ MEMBER_OFFSET_INIT(printk_info_ts_nsec, n, "ts_nsec");
+ MEMBER_OFFSET_INIT(printk_info_text_len, n, "text_len");
+ MEMBER_OFFSET_INIT(printk_info_level, n, "level");
+ MEMBER_OFFSET_INIT(printk_info_caller_id, n, "caller_id");
+ MEMBER_OFFSET_INIT(printk_info_dev_info, n, "dev_info");
+
+ n = "dev_printk_info";
+ MEMBER_OFFSET_INIT(dev_printk_info_subsystem, n, "subsystem");
+ MEMBER_OFFSET_INIT(dev_printk_info_device, n, "device");
+
+ n = "printk_ringbuffer";
+ STRUCT_SIZE_INIT(printk_ringbuffer, n);
+ MEMBER_OFFSET_INIT(prb_desc_ring, n, "desc_ring");
+ MEMBER_OFFSET_INIT(prb_text_data_ring, n, "text_data_ring");
+
+ n = "prb_desc_ring";
+ MEMBER_OFFSET_INIT(prb_desc_ring_count_bits, n, "count_bits");
+ MEMBER_OFFSET_INIT(prb_desc_ring_descs, n, "descs");
+ MEMBER_OFFSET_INIT(prb_desc_ring_infos, n, "infos");
+ MEMBER_OFFSET_INIT(prb_desc_ring_head_id, n, "head_id");
+ MEMBER_OFFSET_INIT(prb_desc_ring_tail_id, n, "tail_id");
+
+ n = "prb_desc";
+ STRUCT_SIZE_INIT(prb_desc, n);
+ MEMBER_OFFSET_INIT(prb_desc_state_var, n, "state_var");
+ MEMBER_OFFSET_INIT(prb_desc_text_blk_lpos, n, "text_blk_lpos");
+
+ n = "prb_data_blk_lpos";
+ MEMBER_OFFSET_INIT(prb_data_blk_lpos_begin, n, "begin");
+ MEMBER_OFFSET_INIT(prb_data_blk_lpos_next, n, "next");
+
+ n = "prb_data_ring";
+ MEMBER_OFFSET_INIT(prb_data_ring_size_bits, n, "size_bits");
+ MEMBER_OFFSET_INIT(prb_data_ring_data, n, "data");
+
+ n = "atomic_long_t";
+ MEMBER_OFFSET_INIT(atomic_long_t_counter, n, "counter");
+}
+
+static void
+dump_record(struct prb_map *m, unsigned long id, int msg_flags)
+{
+ unsigned short text_len;
+ unsigned long state_var;
+ unsigned int caller_id;
+ unsigned char level;
+ unsigned long begin;
+ unsigned long next;
+ char buf[BUFSIZE];
+ uint64_t ts_nsec;
+ ulonglong nanos;
+ ulonglong seq;
+ int ilen = 0, i;
+ char *desc, *info, *text, *p;
+ ulong rem;
+
+ desc = m->descs + ((id % m->desc_ring_count) * SIZE(prb_desc));
+
+ /* skip non-committed record */
+ state_var = ULONG(desc + OFFSET(prb_desc_state_var) +
+ OFFSET(atomic_long_t_counter));
+ if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
+ return;
+
+ info = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
+
+ seq = ULONGLONG(info + OFFSET(printk_info_seq));
+ caller_id = UINT(info + OFFSET(printk_info_caller_id));
+ if (CRASHDEBUG(1))
+ fprintf(fp, "seq: %llu caller_id: %x (%s: %u)\n", seq, caller_id,
+ caller_id & 0x80000000 ? "cpu" : "pid", caller_id & ~0x80000000);
+
+ text_len = USHORT(info + OFFSET(printk_info_text_len));
+
+ begin = ULONG(desc + OFFSET(prb_desc_text_blk_lpos) +
+ OFFSET(prb_data_blk_lpos_begin)) %
+ m->text_data_ring_size;
+ next = ULONG(desc + OFFSET(prb_desc_text_blk_lpos) +
+ OFFSET(prb_data_blk_lpos_next)) %
+ m->text_data_ring_size;
+
+ /* skip data-less text blocks */
+ if (begin == next)
+ goto out;
+
+ if ((msg_flags & SHOW_LOG_TEXT) == 0) {
+ ts_nsec = ULONGLONG(info + OFFSET(printk_info_ts_nsec));
+ nanos = (ulonglong)ts_nsec / (ulonglong)1000000000;
+ rem = (ulonglong)ts_nsec % (ulonglong)1000000000;
+ if (msg_flags & SHOW_LOG_CTIME) {
+ time_t t = kt->boot_date.tv_sec + nanos;
+ sprintf(buf, "[%s] ", ctime_tz(&t));
+ } else
+ sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000);
+
+ ilen += strlen(buf);
+ fprintf(fp, "%s", buf);
+ }
+
+ if (msg_flags & SHOW_LOG_LEVEL) {
+ level = UCHAR(info + OFFSET(printk_info_level)) >> 5;
+ sprintf(buf, "<%x>", level);
+ ilen += strlen(buf);
+ fprintf(fp, "%s", buf);
+ }
+
+ /* handle wrapping data block */
+ if (begin > next)
+ begin = 0;
+
+ /* skip over descriptor ID */
+ begin += sizeof(unsigned long);
+
+ /* handle truncated messages */
+ if (next - begin < text_len)
+ text_len = next - begin;
+
+ text = m->text_data + begin;
+
+ for (i = 0, p = text; i < text_len; i++, p++) {
+ if (*p == '\n')
+ fprintf(fp, "\n%s", space(ilen));
+ else if (isprint(*p) || isspace(*p))
+ fputc(*p, fp);
+ else
+ fputc('.', fp);
+ }
+
+ if (msg_flags & SHOW_LOG_DICT) {
+ text = info + OFFSET(printk_info_dev_info) +
+ OFFSET(dev_printk_info_subsystem);
+ if (strlen(text))
+ fprintf(fp, "\n%sSUBSYSTEM=%s", space(ilen), text);
+
+ text = info + OFFSET(printk_info_dev_info) +
+ OFFSET(dev_printk_info_device);
+ if (strlen(text))
+ fprintf(fp, "\n%sDEVICE=%s", space(ilen), text);
+ }
+out:
+ fprintf(fp, "\n");
+}
+
+/*
+ * Handle the lockless printk_ringbuffer.
+ */
+void
+dump_lockless_record_log(int msg_flags)
+{
+ unsigned long head_id;
+ unsigned long tail_id;
+ unsigned long kaddr;
+ unsigned long id;
+ struct prb_map m;
+
+ if (INVALID_SIZE(printk_info))
+ init_offsets();
+
+ /* setup printk_ringbuffer */
+ get_symbol_data("prb", sizeof(char *), &kaddr);
+ m.prb = GETBUF(SIZE(printk_ringbuffer));
+ if (!readmem(kaddr, KVADDR, m.prb, SIZE(printk_ringbuffer),
+ "printk_ringbuffer contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read printk_ringbuffer contents\n");
+ goto out_prb;
+ }
+
+ /* setup descriptor ring */
+ m.desc_ring = m.prb + OFFSET(prb_desc_ring);
+ m.desc_ring_count = 1 << UINT(m.desc_ring + OFFSET(prb_desc_ring_count_bits));
+
+ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring_descs));
+ m.descs = GETBUF(SIZE(prb_desc) * m.desc_ring_count);
+ if (!readmem(kaddr, KVADDR, m.descs, SIZE(prb_desc) * m.desc_ring_count,
+ "prb_desc_ring contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read prb_desc_ring contents\n");
+ goto out_descs;
+ }
+
+ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring_infos));
+ m.infos = GETBUF(SIZE(printk_info) * m.desc_ring_count);
+ if (!readmem(kaddr, KVADDR, m.infos, SIZE(printk_info) * m.desc_ring_count,
+ "prb_info_ring contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read prb_info_ring contents\n");
+ goto out_infos;
+ }
+
+ /* setup text data ring */
+ m.text_data_ring = m.prb + OFFSET(prb_text_data_ring);
+ m.text_data_ring_size = 1 << UINT(m.text_data_ring + OFFSET(prb_data_ring_size_bits));
+
+ kaddr = ULONG(m.text_data_ring + OFFSET(prb_data_ring_data));
+ m.text_data = GETBUF(m.text_data_ring_size);
+ if (!readmem(kaddr, KVADDR, m.text_data, m.text_data_ring_size,
+ "prb_text_data_ring contents", RETURN_ON_ERROR|QUIET)) {
+ error(WARNING, "\ncannot read prb_text_data_ring contents\n");
+ goto out_text_data;
+ }
+
+ /* ready to go */
+
+ tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_tail_id) +
+ OFFSET(atomic_long_t_counter));
+ head_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring_head_id) +
+ OFFSET(atomic_long_t_counter));
+
+ hq_open();
+
+ for (id = tail_id; id != head_id; id = (id + 1) & DESC_ID_MASK)
+ dump_record(&m, id, msg_flags);
+
+ /* dump head record */
+ dump_record(&m, id, msg_flags);
+
+ hq_close();
+
+out_text_data:
+ FREEBUF(m.text_data);
+out_infos:
+ FREEBUF(m.infos);
+out_descs:
+ FREEBUF(m.descs);
+out_prb:
+ FREEBUF(m.prb);
+}
diff --git a/symbols.c b/symbols.c
index b2f4eb5402d1..a51078d58e6b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10426,6 +10426,30 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(log_level));
fprintf(fp, " log_flags_level: %ld\n",
OFFSET(log_flags_level));
+
+ fprintf(fp, " printk_info_seq: %ld\n", OFFSET(printk_info_seq));
+ fprintf(fp, " printk_info_ts_nseq: %ld\n", OFFSET(printk_info_ts_nsec));
+ fprintf(fp, " printk_info_text_len: %ld\n", OFFSET(printk_info_text_len));
+ fprintf(fp, " printk_info_level: %ld\n", OFFSET(printk_info_level));
+ fprintf(fp, " printk_info_caller_id: %ld\n", OFFSET(printk_info_caller_id));
+ fprintf(fp, " printk_info_dev_info: %ld\n", OFFSET(printk_info_dev_info));
+ fprintf(fp, " dev_printk_info_subsystem: %ld\n", OFFSET(dev_printk_info_subsystem));
+ fprintf(fp, " dev_printk_info_device: %ld\n", OFFSET(dev_printk_info_device));
+ fprintf(fp, " prb_desc_ring: %ld\n", OFFSET(prb_desc_ring));
+ fprintf(fp, " prb_text_data_ring: %ld\n", OFFSET(prb_text_data_ring));
+ fprintf(fp, " prb_desc_ring_count_bits: %ld\n", OFFSET(prb_desc_ring_count_bits));
+ fprintf(fp, " prb_desc_ring_descs: %ld\n", OFFSET(prb_desc_ring_descs));
+ fprintf(fp, " prb_desc_ring_infos: %ld\n", OFFSET(prb_desc_ring_infos));
+ fprintf(fp, " prb_desc_ring_head_id: %ld\n", OFFSET(prb_desc_ring_head_id));
+ fprintf(fp, " prb_desc_ring_tail_id: %ld\n", OFFSET(prb_desc_ring_tail_id));
+ fprintf(fp, " prb_desc_state_var: %ld\n", OFFSET(prb_desc_state_var));
+ fprintf(fp, " prb_desc_text_blk_lpos: %ld\n", OFFSET(prb_desc_text_blk_lpos));
+ fprintf(fp, " prb_data_blk_lpos_begin: %ld\n", OFFSET(prb_data_blk_lpos_begin));
+ fprintf(fp, " prb_data_blk_lpos_next: %ld\n", OFFSET(prb_data_blk_lpos_next));
+ fprintf(fp, " prb_data_ring_size_bits: %ld\n", OFFSET(prb_data_ring_size_bits));
+ fprintf(fp, " prb_data_ring_data: %ld\n", OFFSET(prb_data_ring_data));
+ fprintf(fp, " atomit_long_t_counter: %ld\n", OFFSET(atomic_long_t_counter));
+
fprintf(fp, " sched_rt_entity_my_q: %ld\n",
OFFSET(sched_rt_entity_my_q));
fprintf(fp, " task_group_parent: %ld\n",
@@ -10850,6 +10874,9 @@ dump_offset_table(char *spec, ulong makestruct)
SIZE(xarray));
fprintf(fp, " xa_node: %ld\n",
SIZE(xa_node));
+ fprintf(fp, " printk_info: %ld\n", SIZE(printk_info));
+ fprintf(fp, " printk_ringbuffer: %ld\n", SIZE(printk_ringbuffer));
+ fprintf(fp, " prb_desc: %ld\n", SIZE(prb_desc));
fprintf(fp, "\n array_table:\n");
--
2.17.1

View File

@ -1,100 +0,0 @@
From 71e159c64000467e94e08aefc144f5e1cdaa4aa0 Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Wed, 25 Nov 2020 05:27:53 +0106
Subject: [PATCH 2/2] printk: use committed/finalized state values
An addendum to the previous crash commit a5531b24750e.
The ringbuffer entries use 2 state values (committed and finalized)
rather than a single flag to represent being available for reading.
Copy the definitions and state lookup function directly from the
kernel source and use the new states.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
printk.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/printk.c b/printk.c
index f6d54ce9d0d8..8658016e65bf 100644
--- a/printk.c
+++ b/printk.c
@@ -1,12 +1,6 @@
#include "defs.h"
#include <ctype.h>
-#define DESC_SV_BITS (sizeof(unsigned long) * 8)
-#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1))
-#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2))
-#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK)
-#define DESC_ID_MASK (~DESC_FLAGS_MASK)
-
/* convenience struct for passing many values to helper functions */
struct prb_map {
char *prb;
@@ -21,6 +15,44 @@ struct prb_map {
char *text_data;
};
+/*
+ * desc_state and DESC_* definitions taken from kernel source:
+ *
+ * kernel/printk/printk_ringbuffer.h
+ */
+
+/* The possible responses of a descriptor state-query. */
+enum desc_state {
+ desc_miss = -1, /* ID mismatch (pseudo state) */
+ desc_reserved = 0x0, /* reserved, in use by writer */
+ desc_committed = 0x1, /* committed by writer, could get reopened */
+ desc_finalized = 0x2, /* committed, no further modification allowed */
+ desc_reusable = 0x3, /* free, not yet used by any writer */
+};
+
+#define DESC_SV_BITS (sizeof(unsigned long) * 8)
+#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
+#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
+#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
+#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
+
+/*
+ * get_desc_state() taken from kernel source:
+ *
+ * kernel/printk/printk_ringbuffer.c
+ */
+
+/* Query the state of a descriptor. */
+static enum desc_state get_desc_state(unsigned long id,
+ unsigned long state_val)
+{
+ if (id != DESC_ID(state_val))
+ return desc_miss;
+
+ return DESC_STATE(state_val);
+}
+
static void
init_offsets(void)
{
@@ -74,6 +106,7 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
unsigned short text_len;
unsigned long state_var;
unsigned int caller_id;
+ enum desc_state state;
unsigned char level;
unsigned long begin;
unsigned long next;
@@ -90,7 +123,8 @@ dump_record(struct prb_map *m, unsigned long id, int msg_flags)
/* skip non-committed record */
state_var = ULONG(desc + OFFSET(prb_desc_state_var) +
OFFSET(atomic_long_t_counter));
- if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK)
+ state = get_desc_state(id, state_var);
+ if (state != desc_committed && state != desc_finalized)
return;
info = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info));
--
2.17.1

View File

@ -1,2 +1,2 @@
SHA512 (crash-7.3.0.tar.gz) = bc288821892c3d7ecbf192d9fe6ea9e73216f8074a24d12a00fbcaf967a1faa38ee69c4a5a97aa93bf75426293f5b275f5ab496c154b4e7be265ba0e263b2bc8
SHA512 (crash-8.0.0.tar.gz) = c52afab6c8187dc0c44a13b2a5b33bd7df33d9ee12bcecc6b7e94e8bc98d9470c134cb0fbe941b750f36a66028aad718bfd6f1a00524ad38ce43d1f278048a3b
SHA512 (gdb-10.2.tar.gz) = aa89caf47c1c84366020377d47e7c51ddbc48e5b7686f244e38797c8eb88411cf57fcdc37eb669961efb41ceeac4181747f429625fd1acce7712cb9a1fea9c41