Re: [PATCH v5 3/5] add folio_order function
by Lianbo Jiang
On 3/18/26 8:24 PM, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Wed, 18 Mar 2026 20:23:38 +0800
> From: Huang Shijie<huangsj(a)hygon.cn>
> Subject: [Crash-utility] [PATCH v5 3/5] add folio_order function
> To:<ltao(a)redhat.com>,<k-hagio-ab(a)nec.com>,<lijiang(a)redhat.com>
> Cc:devel@lists.crash-utility.osci.io,zhongyuan@hygon.cn,
> fangbaoshun@hygon.cn,yingzhiwei@hygon.cn,1537577747(a)qq.com, Huang
> Shijie<huangsj(a)hygon.cn>
> Message-ID:<20260318122340.53291-4-huangsj(a)hygon.cn>
> Content-Type: text/plain
>
> The folio_order() was introduced to kernel at v5.16, but the first
> large folio support patch is in v5.17:
> 6795801366da "xfs: Support large folios"
>
> The folio_order() keeps the same logic as kernel code
> in different versions:
> 1.) In kernel v5.17, folio_order() uses page[1].compound_order to
> get the folio order.
>
> 2.) In kernel v6.1, the following patch introduces _folio_order:
> c3a15bff46cb5149 "mm: reimplement folio_order() and folio_nr_pages()"
>
> folio_order() uses _folio_order to get the folio order.
>
> 3.) In kernel v6.6, the following patch replaces the _folio_order with _flags_1:
> ebc1baf5c9b46c22 "mm: free up a word in the first tail page"
>
> folio_order() uses _flags_1 to get the folio order.
>
> This patch will be used in later patches.
>
> Signed-off-by: Huang Shijie<huangsj(a)hygon.cn>
> ---
> defs.h | 8 +++++++
> memory.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> symbols.c | 6 +++++
> 3 files changed, 84 insertions(+)
>
> diff --git a/defs.h b/defs.h
> index 8f6784e..e832ea6 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2290,6 +2290,9 @@ struct offset_table { /* stash of commonly-used offsets */
> long bpf_ringbuf_nr_pages;
> long hrtimer_clock_base_index;
> long klp_patch_list;
> + long page_compound_order;
> + long folio__folio_order;
> + long folio__flags_1;
> };
>
> struct size_table { /* stash of commonly-used sizes */
> @@ -2469,6 +2472,9 @@ struct size_table { /* stash of commonly-used sizes */
> long cpumask_t;
> long task_struct_exit_state;
> long bpf_ringbuf_map;
> + long page_compound_order;
> + long folio__folio_order;
> + long folio__flags_1;
> };
>
> struct array_table {
> @@ -6008,6 +6014,8 @@ ulong do_xarray(ulong, int, struct list_pair *, int);
> #define XARRAY_TAG_MASK (3UL)
> #define XARRAY_TAG_INTERNAL (2UL)
>
> +int folio_order(ulong folio);
> +
> int file_dump(ulong, ulong, ulong, int, int);
> #define DUMP_FULL_NAME 0x1
> #define DUMP_INODE_ONLY 0x2
> diff --git a/memory.c b/memory.c
> index 17423a5..3b272ad 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -547,6 +547,13 @@ vm_init(void)
> MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
> MEMBER_OFFSET_INIT(page_page_type, "page", "page_type");
>
> + MEMBER_OFFSET_INIT(page_compound_order, "page", "compound_order");
> + MEMBER_SIZE_INIT(page_compound_order, "page", "compound_order");
> + MEMBER_OFFSET_INIT(folio__folio_order, "folio", "_folio_order");
> + MEMBER_SIZE_INIT(folio__folio_order, "folio", "_folio_order");
> + MEMBER_OFFSET_INIT(folio__flags_1, "folio", "_flags_1");
> + MEMBER_SIZE_INIT(folio__flags_1, "folio", "_flags_1");
> +
> MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd");
>
> MEMBER_OFFSET_INIT(swap_info_struct_swap_file,
> @@ -20426,6 +20433,69 @@ static unsigned int oo_objects(ulong oo)
> return (oo & ((1 << 16) - 1));
> }
>
> +/*
> + * The folio_order() was introduced to kernel at v5.16, but the first
> + * large folio support patch is in v5.17:
> + * 6795801366da "xfs: Support large folios"
> + *
> + * 1.) In kernel v5.17, folio_order() uses page[1].compound_order to
> + * get the folio order.
> + *
> + * 2.) In kernel v6.1, the following patch introduces _folio_order:
> + * c3a15bff46cb5149 "mm: reimplement folio_order() and folio_nr_pages()"
> + *
> + * folio_order() uses _folio_order to get the folio order.
> + *
> + * 3.) In kernel v6.6, the following patch replaces the _folio_order with _flags_1:
> + * ebc1baf5c9b46c22 "mm: free up a word in the first tail page"
> + *
> + * folio_order() uses _flags_1 to get the folio order.
> + */
For this check condition, It's not very good to use kernel version.
Let's investigate if there is a better way to handle this issue.
Lianbo
> +int
> +folio_order(ulong folio)
> +{
> + ulong v = 0;
> + int PG_head = 16;
> +
> + if (THIS_KERNEL_VERSION < LINUX(5,17,0))
> + return 0;
> +
> + if (THIS_KERNEL_VERSION < LINUX(6,1,0)) {
> + readmem(folio + OFFSET(page_flags), KVADDR, &v, sizeof(ulong),
> + "folio.page.flags", FAULT_ON_ERROR);
> + if (!(v & (1 << PG_head)))
> + return 0;
> +
> + readmem(folio + SIZE(page) + OFFSET(page_compound_order), KVADDR, &v,
> + SIZE(page_compound_order), "page[1].compound_order", FAULT_ON_ERROR);
> +
> + return v;
> + } else if (THIS_KERNEL_VERSION < LINUX(6,6,0)) {
> + readmem(folio + OFFSET(page_flags), KVADDR, &v, sizeof(ulong),
> + "folio.page.flags", FAULT_ON_ERROR);
> + if (!(v & (1 << PG_head)))
> + return 0;
> +
> + readmem(folio + OFFSET(folio__folio_order), KVADDR, &v,
> + SIZE(folio__folio_order), "folio->_folio_order", FAULT_ON_ERROR);
> +
> + return v;
> + } else {
> + /* The PG_head changes to bit 6 at kernel v6.6 */
> + PG_head = 6;
> +
> + readmem(folio + OFFSET(page_flags), KVADDR, &v, sizeof(ulong),
> + "folio.page.flags", FAULT_ON_ERROR);
> + if (!(v & (1 << PG_head)))
> + return 0;
> +
> + readmem(folio + OFFSET(folio__flags_1), KVADDR, &v,
> + SIZE(folio__flags_1), "folio->_flags_1", FAULT_ON_ERROR);
> +
> + return v & 0xff;
> + }
> +}
> +
> #ifdef NOT_USED
> ulong
> slab_to_kmem_cache_node(struct meminfo *si, ulong slab_page)
> diff --git a/symbols.c b/symbols.c
> index e6865ca..08c07e9 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -10451,6 +10451,9 @@ dump_offset_table(char *spec, ulong makestruct)
> fprintf(fp, " page_private: %ld\n", OFFSET(page_private));
> fprintf(fp, " page_page_type: %ld\n",
> OFFSET(page_page_type));
> + fprintf(fp, " page_compound_order: %ld\n", OFFSET(page_compound_order));
> + fprintf(fp, " folio__folio_order: %ld\n", OFFSET(folio__folio_order));
> + fprintf(fp, " folio__flags_1: %ld\n", OFFSET(folio__flags_1));
>
> fprintf(fp, " trace_print_flags_mask: %ld\n",
> OFFSET(trace_print_flags_mask));
> @@ -11961,6 +11964,9 @@ dump_offset_table(char *spec, ulong makestruct)
> fprintf(fp, "\n size_table:\n");
> fprintf(fp, " page: %ld\n", SIZE(page));
> fprintf(fp, " page_flags: %ld\n", SIZE(page_flags));
> + fprintf(fp, " page_compound_order: %ld\n", SIZE(page_compound_order));
> + fprintf(fp, " folio__folio_order: %ld\n", SIZE(folio__folio_order));
> + fprintf(fp, " folio__flags_1: %ld\n", SIZE(folio__flags_1));
> fprintf(fp, " trace_print_flags: %ld\n", SIZE(trace_print_flags));
> fprintf(fp, " free_area_struct: %ld\n",
> SIZE(free_area_struct));
> -- 2.43.0
2 months, 3 weeks
[PATCH 0/1] struct: add -F source-file scoping for duplicate datatype names
by chahuan
When different source files define same-name struct/union tags, crash may
resolve an unintended candidate because default type lookup depends on symbol
lookup order/context.
This series adds `struct/union -F <file_name>` to constrain datatype lookup to
the compilation-unit scope matched by the requested source file.
For example, this avoids ambiguity for duplicate tags such as
`arm_smmu_device` defined in both `arm-smmu.c` and `arm-smmu-v3.c`.
Implementation summary:
- Parse `-F` in `struct`/`union` command path and propagate `source_file` in
gdb requests.
- In gdb-side patch code, map source file -> unique scope block
(`objfile -> compunit -> filetabs -> blockvector`), prefer `STATIC_BLOCK`
and fallback to `GLOBAL_BLOCK`.
- Apply the scope temporarily for the request and restore previous scope
automatically afterward.
- If file match is missing or ambiguous, fail explicitly instead of choosing a
random candidate.
- Note: `-F` may add a small lookup-time overhead due to extra scope scanning
and symbol-table expansion needed for deterministic file-scoped matching.
Compatibility:
- Existing behavior is unchanged when `-F` is not used.
- Existing `STRUCT_SIZE/MEMBER_OFFSET/...` call paths remain compatible.
- For external/plugin callers that need file-scoped lookup with minimal changes,
expose two helper APIs:
- `char *set_temporary_datatype_filename(const char *source_file);`
- `void restore_datatype_filename(char *saved_source_file);`
chahuan (1):
struct: add -F source-file scoping for duplicate datatype names
cmdline.c | 1 +
defs.h | 4 ++
gdb-16.2.patch | 166 ++++++++++++++++++++++++++++++++++++++++++++++--
gdb_interface.c | 6 ++
help.c | 8 ++-
symbols.c | 31 ++++++++-
6 files changed, 206 insertions(+), 10 deletions(-)
--
2.43.0
2 months, 3 weeks
[PATCH 0/2] RISCV64: optimize symbol handling for large kernel symbol tables
by Rui Qi
This patch series optimizes symbol handling in crash utility for RISCV64
architecture, particularly beneficial when debugging kernels with large
symbol tables (900K+ symbols).
Background:
On a 32-core RISCV64 physical machine running Linux 6.12.13, the kernel
symbol table contains over 900,000 entries (wc -l /proc/kallsyms). When
using crash utility to analyze vmcore or live system, significant time
is spent in symbol-related operations, specifically:
1. Symbol name hash lookups - the original simple hash function causes
high collision rates with large symbol tables
2. Processing of linker-generated mapping symbols (.L*, L0*, $*) which
are unnecessary for debugging but consume processing time
Patch 1: Optimize symname_hash with larger table and FNV-1a hash
- Increases SYMNAME_HASH from 512 to 16384 (32x) to reduce collisions
- Replaces simple hash with FNV-1a algorithm for better distribution
- Removes strlen() call by computing hash in single pass
This reduces average hash bucket chain length significantly, improving
symbol lookup performance at the cost of ~248KB additional memory.
Patch 2: Add mapping symbol filter in riscv64_verify_symbol
- Filters out linker mapping symbols (.L*, L0*, $*) that should not be
in the symbol list
- Also optimizes riscv64_verify_symbol() by consolidating name validity
checks
Together these patches improve crash utility startup and symbol lookup
performance on RISCV64 systems with large kernel symbol tables.
Rui Qi (2):
symbols: optimize symname_hash with larger table and FNV-1a hash
RISCV64: add mapping symbol filter in riscv64_verify_symbol
defs.h | 2 +-
riscv64.c | 14 +++++++++++---
symbols.c | 20 ++++++++++++++------
3 files changed, 27 insertions(+), 9 deletions(-)
--
2.43.0
2 months, 4 weeks
[PATCH 1/2] symbols: optimize symname_hash with larger table and FNV-1a hash
by Rui Qi
Optimize the symbol name hash table to reduce collision and improve
performance, especially on RISC-V architecture where symbol lookup
is a hotspot.
Changes:
- Increase SYMNAME_HASH from 512 to 16384 (32x) to reduce collisions
- Replace simple hash with FNV-1a algorithm for better distribution
- Remove strlen() call, compute hash in single pass
This reduces the average chain length in hash buckets significantly,
improving symbol lookup performance at the cost of ~248KB additional
memory.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
defs.h | 2 +-
symbols.c | 15 +++++++++------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/defs.h b/defs.h
index a6f43725b6b8..4cf062894ebe 100644
--- a/defs.h
+++ b/defs.h
@@ -2900,7 +2900,7 @@ struct downsized {
#define SYMVAL_HASH_INDEX(vaddr) \
(((vaddr) >> machdep->pageshift) % SYMVAL_HASH)
-#define SYMNAME_HASH (512)
+#define SYMNAME_HASH (16384)
#define PATCH_KERNEL_SYMBOLS_START ((char *)(1))
#define PATCH_KERNEL_SYMBOLS_STOP ((char *)(2))
diff --git a/symbols.c b/symbols.c
index e6865cabef74..afdf4a61cea2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1170,16 +1170,19 @@ symname_hash_init(void)
static unsigned int
symname_hash_index(char *name)
{
- unsigned int len, value;
- unsigned char *array = (unsigned char *)name;
+ unsigned int hash = 2166136261U;
+ unsigned char *p = (unsigned char *)name;
- len = strlen(name);
- if (!len)
+ if (!*p)
error(FATAL, "The length of the symbol name is zero!\n");
- value = array[len - 1] * array[len / 2];
+ /* FNV-1a hash algorithm for better distribution */
+ while (*p) {
+ hash ^= *p++;
+ hash *= 16777619;
+ }
- return (array[0] ^ value) % SYMNAME_HASH;
+ return hash % SYMNAME_HASH;
}
/*
--
2.20.1
2 months, 4 weeks
[PATCH] Support module memory layout change on linux 6.18 by kernel commit b4760ff ("module: deprecate usage of *_gpl sections in module loader")[1]. Without the patch, crash cannot start a session with an error message like this:
by yangshiguang1011@163.com
From: yangshiguang <yangshiguang(a)xiaomi.com>
crash: invalid structure member offset: module_num_gpl_syms
FILE: kernel.c LINE: 3834 FUNCTION: module_init()
[1]
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?...
Signed-off-by: yangshiguang <yangshiguang(a)xiaomi.com>
---
kernel.c | 5 +++--
symbols.c | 18 ++++++++++++++----
2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
index 8781d6a..786eb73 100644
--- a/kernel.c
+++ b/kernel.c
@@ -3830,8 +3830,9 @@ module_init(void)
nsyms = UINT(modbuf + OFFSET(module_nsyms));
break;
case KMOD_V2:
- nsyms = UINT(modbuf + OFFSET(module_num_syms)) +
- UINT(modbuf + OFFSET(module_num_gpl_syms));
+ nsyms = UINT(modbuf + OFFSET(module_num_syms));
+ if (VALID_MEMBER(module_num_gpl_syms))
+ nsyms += UINT(modbuf + OFFSET(module_num_gpl_syms));
break;
}
diff --git a/symbols.c b/symbols.c
index e6865ca..189fe3e 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1976,9 +1976,14 @@ store_module_symbols_6_4(ulong total, int mods_installed)
"module buffer", FAULT_ON_ERROR);
syms = ULONG(modbuf + OFFSET(module_syms));
- gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
nsyms = UINT(modbuf + OFFSET(module_num_syms));
- ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ if (VALID_MEMBER(module_gpl_syms) && VALID_MEMBER(module_num_gpl_syms)) {
+ gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
+ ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ } else {
+ gpl_syms = 0;
+ ngplsyms = 0;
+ }
nksyms = UINT(modbuf + OFFSET(module_num_symtab));
@@ -2336,9 +2341,14 @@ store_module_symbols_v2(ulong total, int mods_installed)
"module buffer", FAULT_ON_ERROR);
syms = ULONG(modbuf + OFFSET(module_syms));
- gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
nsyms = UINT(modbuf + OFFSET(module_num_syms));
- ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ if (VALID_MEMBER(module_gpl_syms) && VALID_MEMBER(module_num_gpl_syms)) {
+ gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
+ ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ } else {
+ gpl_syms = 0;
+ ngplsyms = 0;
+ }
if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
nksyms = UINT(modbuf + OFFSET(module_num_symtab));
--
2.43.0
2 months, 4 weeks
[Resend][PATCH] RISCV64: fix pmd address calculation in riscv64_vtop_4level_4k
by Rui Qi
Fix a bug in the PMD address calculation where the operator was
incorrectly using '+' instead of '*'. This caused the PMD index
to be added as an offset rather than multiplied by the entry size,
resulting in incorrect page table traversal for 4-level 4KB paging.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
riscv64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/riscv64.c b/riscv64.c
index eceae70c2377..bfe1fb88621a 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -1241,7 +1241,7 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
/* PMD */
FILL_PMD(PAGEBASE(pmd_base), PHYSADDR, PAGESIZE());
- pmd_addr = pmd_base + sizeof(pmd_t) + pmd_index_l4_4k(vaddr);
+ pmd_addr = pmd_base + sizeof(pmd_t) * pmd_index_l4_4k(vaddr);
pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_addr));
if (verbose)
fprintf(fp, " PMD: %016lx => %016lx\n", pmd_addr, pmd_val);
--
2.20.1
2 months, 4 weeks
[PATCH] RISCV64: fix pmd address calculation in riscv64_vtop_4level_4k
by Rui Qi
Fix a bug in the PMD address calculation where the operator was
incorrectly using '+' instead of '*'. This caused the PMD index
to be added as an offset rather than multiplied by the entry size,
resulting in incorrect page table traversal for 4-level 4KB paging.
Signed-off-by: Rui Qi <qirui.001(a)bytedance.com>
---
riscv64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/riscv64.c b/riscv64.c
index eceae70c2377..bfe1fb88621a 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -1241,7 +1241,7 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
/* PMD */
FILL_PMD(PAGEBASE(pmd_base), PHYSADDR, PAGESIZE());
- pmd_addr = pmd_base + sizeof(pmd_t) + pmd_index_l4_4k(vaddr);
+ pmd_addr = pmd_base + sizeof(pmd_t) * pmd_index_l4_4k(vaddr);
pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_addr));
if (verbose)
fprintf(fp, " PMD: %016lx => %016lx\n", pmd_addr, pmd_val);
--
2.20.1
2 months, 4 weeks
[PATCH v1 1/1] symbols: Add support for mod symtab with combined GPL and non-GPL symbols
by Alexander Egorenkov
The patch series 'scalable symbol flags with __kflagstab'
(https://lore.kernel.org/all/20260326-kflagstab-v5-4-fa0796fe88d9@google.com)
eliminated separate GPL symbol sections representing GPL only symbols.
Therefore, depending on whether the member gpl_syms is present
in struct module, decide whether GPL module symbols are separated or not.
Signed-off-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
---
kernel.c | 13 ++++++++-----
symbols.c | 9 +++++++--
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/kernel.c b/kernel.c
index 8781d6a22414..35e6fd61f077 100644
--- a/kernel.c
+++ b/kernel.c
@@ -3634,9 +3634,11 @@ module_init(void)
case KMOD_V2:
MEMBER_OFFSET_INIT(module_num_syms, "module", "num_syms");
MEMBER_OFFSET_INIT(module_list, "module", "list");
- MEMBER_OFFSET_INIT(module_gpl_syms, "module", "gpl_syms");
- MEMBER_OFFSET_INIT(module_num_gpl_syms, "module",
- "num_gpl_syms");
+ if (MEMBER_EXISTS("module", "gpl_syms")) {
+ MEMBER_OFFSET_INIT(module_gpl_syms, "module", "gpl_syms");
+ MEMBER_OFFSET_INIT(module_num_gpl_syms, "module",
+ "num_gpl_syms");
+ }
if (MEMBER_EXISTS("module", "mem")) { /* 6.4 and later */
kt->flags2 |= KMOD_MEMORY; /* MODULE_MEMORY() can be used. */
@@ -3830,8 +3832,9 @@ module_init(void)
nsyms = UINT(modbuf + OFFSET(module_nsyms));
break;
case KMOD_V2:
- nsyms = UINT(modbuf + OFFSET(module_num_syms)) +
- UINT(modbuf + OFFSET(module_num_gpl_syms));
+ nsyms = UINT(modbuf + OFFSET(module_num_syms));
+ if (VALID_MEMBER(module_num_gpl_syms))
+ nsyms += UINT(modbuf + OFFSET(module_num_gpl_syms));
break;
}
diff --git a/symbols.c b/symbols.c
index e6865cabef74..7b00e26ab0cf 100644
--- a/symbols.c
+++ b/symbols.c
@@ -1976,9 +1976,14 @@ store_module_symbols_6_4(ulong total, int mods_installed)
"module buffer", FAULT_ON_ERROR);
syms = ULONG(modbuf + OFFSET(module_syms));
- gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
nsyms = UINT(modbuf + OFFSET(module_num_syms));
- ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ if (VALID_MEMBER(module_gpl_syms)) {
+ gpl_syms = ULONG(modbuf + OFFSET(module_gpl_syms));
+ ngplsyms = UINT(modbuf + OFFSET(module_num_gpl_syms));
+ } else {
+ gpl_syms = 0;
+ ngplsyms = 0;
+ }
nksyms = UINT(modbuf + OFFSET(module_num_symtab));
--
2.51.0
3 months
[PATCH v2] RISC-V: improve error message for search command failure
by Austin Kim
The search command currently fails on RISC-V based vmcores
without providing specific details, only printing a generic 'invalid' message.
This patch enhances the debug output by including the specific virtual address
(before)
crash> search ffffffd8c2b42280
invalid
(after)
crash> search ffffffd8c2b42280
invalid for ffffffd800000000 address
Signed-off-by: Austin Kim <austindh.kim(a)gmail.com>
---
riscv64.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/riscv64.c b/riscv64.c
index eceae70..ee9d4e3 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -687,7 +687,7 @@ riscv64_vtop_3level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
return TRUE;
no_page:
- fprintf(fp, "invalid\n");
+ fprintf(fp, "invalid for %lx address\n", vaddr);
return FALSE;
}
@@ -1279,7 +1279,7 @@ riscv64_vtop_4level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
return TRUE;
no_page:
- fprintf(fp, "invalid\n");
+ fprintf(fp, "invalid for %lx address\n", vaddr);
return FALSE;
}
@@ -1368,7 +1368,7 @@ riscv64_vtop_5level_4k(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
return TRUE;
no_page:
- fprintf(fp, "invalid\n");
+ fprintf(fp, "invalid for %lx address\n", vaddr);
return FALSE;
}
--
2.34.1
3 months
[PATCH] fix eheader overflow
by Bruno Faccini
crash-utility live session fails solid with a SEGV, where it seems
that with some (new ?) Kernels and configurations /proc/kcore
exposes a first “Note” program-header along with a big number of
other headers (particularly when direct-map area generated from
physical memory map have a lot of entries), causing eheader[]
overflow (a stack underflow in fact since it is an automatic
variable!) because the whole size exceeds MAX_KCORE_ELF_HEADER_SIZE.
This problem still occur with latest utility version, and the
following patch has been proven to fix.
Signed-off-by: Bruno Faccini <bfaccini(a)nvidia.com>
diff --git a/netdump.c b/netdump.c
index 452ef72..7697613 100644
--- a/netdump.c
+++ b/netdump.c
@@ -4664,7 +4664,12 @@ proc_kcore_init_32(FILE *fp, int kcore_fd)
clean_exit(1);
}
- BCOPY(&eheader[0], &pkd->elf_header[0], pkd->header_size);
+ if (read(fd, pkd->elf_header, pkd->header_size) != pkd->header_size) {
+ sprintf(buf, "/proc/kcore: read");
+ perror(buf);
+ goto bailout;
+ }
+
pkd->notes32 = (Elf32_Phdr *)&pkd->elf_header[elf32->e_phoff];
pkd->load32 = pkd->notes32 + 1;
pkd->flags |= KCORE_ELF32;
@@ -4738,7 +4743,12 @@ proc_kcore_init_64(FILE *fp, int kcore_fd)
clean_exit(1);
}
- BCOPY(&eheader[0], &pkd->elf_header[0], pkd->header_size);
+ if (read(fd, pkd->elf_header, pkd->header_size) != pkd->header_size) {
+ sprintf(buf, "/proc/kcore: read");
+ perror(buf);
+ goto bailout;
+ }
+
pkd->notes64 = (Elf64_Phdr *)&pkd->elf_header[elf64->e_phoff];
pkd->load64 = pkd->notes64 + 1;
pkd->flags |= KCORE_ELF64;
3 months