Patch for Optimize extensions's compilation
by 高建云
Hello, When I tried to build crash extensions for arm64, I found that the
default compiler is fixed with gcc. I try to optimize it ,so I send this
patch. Looking forward to hearing from you.
Best wishes,Thank u
3 weeks, 2 days
Re: [PATCH RFC][makedumpfile 02/10] dwarf_info: Fix a infinite recursion bug for search_domain
by Tao Liu
Hi YAMAZAKI,
On Fri, Oct 3, 2025 at 8:23 PM YAMAZAKI MASAMITSU(山崎 真光)
<yamazaki-msmt(a)nec.com> wrote:
>
> On 2025/06/10 18:57, Tao Liu wrote:
> > There is an infinite recursion bug noticed in rust symbols. The root cause is
> > unclear to me. This patch will avoid the bug by skip the recursion of rust
> > symbols, since currently we don't need to deal with those.
> >
> > Signed-off-by: Tao Liu <ltao(a)redhat.com>
> > ---
> > dwarf_info.c | 15 ++++++++-------
> > 1 file changed, 8 insertions(+), 7 deletions(-)
> >
> > diff --git a/dwarf_info.c b/dwarf_info.c
> > index a3a2fd6..73842ab 100644
> > --- a/dwarf_info.c
> > +++ b/dwarf_info.c
> > @@ -837,7 +837,7 @@ search_symbol(Dwarf_Die *die, int *found)
> > }
> >
> > static void
> > -search_domain(Dwarf_Die *die, int *found)
> > +search_domain(Dwarf_Die *die, int *found, int lang)
> > {
> > int tag;
> > const char *name;
> > @@ -859,10 +859,11 @@ search_domain(Dwarf_Die *die, int *found)
> > if (is_container(&die_type)) {
> > Dwarf_Die child;
> >
> > - if (dwarf_child(&die_type, &child) != 0)
> > + if (dwarf_child(&die_type, &child) != 0 ||
> > + lang == DW_LANG_Rust)
> > continue;
> >
> > - search_domain(&child, found);
> > + search_domain(&child, found, lang);
> >
> > if (*found)
> > return;
> > @@ -924,7 +925,7 @@ search_die(Dwarf_Die *die, int *found)
> > }
> >
> > static void
> > -search_die_tree(Dwarf_Die *die, int *found)
> > +search_die_tree(Dwarf_Die *die, int *found, int lang)
> > {
> > Dwarf_Die child;
> >
> > @@ -932,7 +933,7 @@ search_die_tree(Dwarf_Die *die, int *found)
> > * start by looking at the children
> > */
> > if (dwarf_child(die, &child) == 0)
> > - search_die_tree(&child, found);
> > + search_die_tree(&child, found, lang);
> >
> > if (*found)
> > return;
> > @@ -950,7 +951,7 @@ search_die_tree(Dwarf_Die *die, int *found)
> > search_typedef(die, found);
> >
> > else if (is_search_domain(dwarf_info.cmd))
> > - search_domain(die, found);
> > + search_domain(die, found, lang);
> >
> > else if (is_search_die(dwarf_info.cmd))
> > search_die(die, found);
> > @@ -1007,7 +1008,7 @@ get_debug_info(void)
> > ERRMSG("Can't get CU die.\n");
> > goto out;
> > }
> > - search_die_tree(&cu_die, &found);
> > + search_die_tree(&cu_die, &found, dwarf_srclang(&cu_die));
> > if (found)
> > break;
> > off = next_off;
>
> Hi Liu
>
> This problem need to be solve. But I don't know how to reproduce.
> If Your server is running rust program. Or Or is it running as a
> module by rust? Please tell me how to reproduce it.
Sure
E.g. using the following eppic program: /tmp/test.c:
string test_opt(){return "";}
string test_usage(){return "";}
static void test_showusage(){printf("");}
string test_help(){return "";}
int test()
{
struct task_struct *p;
unsigned long offset;
p = (struct task_struct *)&init_task;
offset = (unsigned long)&(p->tasks) - (unsigned long)p;
do {
printf("%d\n", (int)(p->pid));
p = (struct task_struct *)((unsigned long)(p->tasks.next) - (unsigned long)p);
} while (p != &init_task);
return 1;
}
$ ./makedumpfile --dry-run -d 31 -l
/var/crash/127.0.0.1-2025-06-10-18\:03\:12/vmcore /tmp/out -x
/lib/debug/lib/modules/6.11.8-300.fc41.x86_64/vmlinux --eppic
/tmp/test.c
Segmentation fault (core dumped)
With the patch, no segfault.
The vmcore/vmlinux should contain rust symbols: CONFIG_RUST=y, you can
use the following vmcore https://people.redhat.com/~ltao/core/vmcore +
https://kojipkgs.fedoraproject.org//packages/kernel/6.11.8/300.fc41/x86_6...
for vmlinux and vmcore to test.
Thanks,
Tao Liu
>
> Thanks,
> Masa
>
3 weeks, 3 days
[PATCH] vtop: Translate IEP flag for s390 region and and segment entries.
by Mikhail Zaslonko
Translate and print the IEP (Instruction Execution Protection) flag for
Region-Third-Table entries and Segment-Table entries of Format
Control 1 for the S390X 'vtop' command like shown below.
STE: 0000000033be8ac0 => 0000000015803503 (flags = 03503)
flags in binary : AV=0; ACC=0011; F=0; FC=1; P=0; IEP=1; I=0; CS=0; TT=0
Signed-off-by: Mikhail Zaslonko <zaslonko(a)linux.ibm.com>
---
s390x.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/s390x.c b/s390x.c
index 0e8e2b3..4a462e3 100644
--- a/s390x.c
+++ b/s390x.c
@@ -65,6 +65,7 @@
#define S390X_RTE_TF 0xc0ULL
#define S390X_RTE_TF_10 0x80ULL
#define S390X_RTE_TF_01 0x40ULL
+#define S390X_RTE_IEP 0x100ULL
#define S390X_RTE_P 0x200ULL
#define S390X_RTE_FC 0x400ULL
#define S390X_RTE_F 0x800ULL
@@ -82,6 +83,7 @@
#define S390X_STE_TT_01 0x4ULL
#define S390X_STE_CS 0x10ULL
#define S390X_STE_I 0x20ULL
+#define S390X_STE_IEP 0x100ULL
#define S390X_STE_P 0x200ULL
#define S390X_STE_FC 0x400ULL
#define S390X_STE_F 0x800ULL
@@ -979,7 +981,7 @@ static inline int s390x_pte_present(unsigned long x){
/* Print flags of Segment-Table entry with format control = 1 */
static void print_segment_entry_fc1(ulong val)
{
- fprintf(fp, "AV=%u; ACC=%u%u%u%u; F=%u; FC=%u; P=%u; I=%u; CS=%u; TT=%u%u\n",
+ fprintf(fp, "AV=%u; ACC=%u%u%u%u; F=%u; FC=%u; P=%u; IEP=%u; I=%u; CS=%u; TT=%u%u\n",
!!(val & S390X_STE_AV),
!!(val & S390X_STE_ACC_1000),
!!(val & S390X_STE_ACC_0100),
@@ -988,6 +990,7 @@ static void print_segment_entry_fc1(ulong val)
!!(val & S390X_STE_F),
!!(val & S390X_STE_FC),
!!(val & S390X_STE_P),
+ !!(val & S390X_STE_IEP),
!!(val & S390X_STE_I),
!!(val & S390X_STE_CS),
!!(val & S390X_STE_TT_10),
@@ -1009,7 +1012,7 @@ static void print_segment_entry_fc0(ulong val)
/* Print flags of Region-Third-Table entry with format control = 1 */
static void print_region_third_entry_fc1(ulong val)
{
- fprintf(fp, "AV=%u; ACC=%u%u%u%u; F=%u; FC=%u; P=%u; I=%u; CR=%u; TT=%u%u\n",
+ fprintf(fp, "AV=%u; ACC=%u%u%u%u; F=%u; FC=%u; P=%u; IEP=%u; I=%u; CR=%u; TT=%u%u\n",
!!(val & S390X_RTE_AV),
!!(val & S390X_RTE_ACC_1000),
!!(val & S390X_RTE_ACC_0100),
@@ -1018,6 +1021,7 @@ static void print_region_third_entry_fc1(ulong val)
!!(val & S390X_RTE_F),
!!(val & S390X_RTE_FC),
!!(val & S390X_RTE_P),
+ !!(val & S390X_RTE_IEP),
!!(val & S390X_RTE_I),
!!(val & S390X_RTE_CR),
!!(val & S390X_RTE_TT_10),
--
2.49.0
3 weeks, 3 days
✅ Need Help with Assignment Service – Reliable Academic Assistance
by edithharrison571@gmail.com
Before I learnt about the Need Help with Assignment Service, I was feeling overburdened by the deadline for my research paper. Their procedure was clear-cut and easy, and I was paired with an experienced writer who genuinely understood my needs. The well-researched, flawlessly formatted draft was delivered ahead of schedule. More significantly, it transformed my anxiety into confidence and helped me comprehend difficult ideas. To any student who is struggling academically, I heartily recommend this dependable service.
Visit Site: https://assignmenthelpinuk.co.uk/help-with-my-assignment/
4 weeks
[PATCH v2] vmcoreinfo: read vmcoreinfo using 'vmcoreinfo_data' when unavailable in elf note
by Aditya Gupta
Few vmcores don't have vmcoreinfo elf note, such as those created using
virsh-dump.
On architectures such as PowerPC64, vmcoreinfo is mandatory to fetch the
first_vmalloc_address, for vmcores of upstream linux, since crash-utility commit:
commit 5b24e363a898 ("get vmalloc start address from vmcoreinfo")
Try reading from the 'vmcoreinfo_data' symbol instead, if the vmcoreinfo
crash tries to read in case of diskdump/netdump is empty/missing.
The approach to read 'vmcoreinfo_data' was used for a live kernel, which can be
reused in the case of missing vmcoreinfo note also, as the
'vmcoreinfo_data' symbol is available with vmcore too
Note though, till GDB interface is not initialised, reading from
vmcoreinfo_data symbol is not done, so behaviour is same as previously
with no vmcoreinfo (only till GDB interface is not initialised)
Hence rename 'vmcoreinfo_read_string' in kernel.c to
'vmcoreinfo_read_from_memory', and use it in netdump.c and diskdump.c
too.
Reported-by: Anushree Mathur <anushree.mathur(a)linux.ibm.com>
Tested-by: Anushree Mathur <anushree.mathur(a)linux.ibm.com>
Signed-off-by: Aditya Gupta <adityag(a)linux.ibm.com>
---
Changelog
=========
v2:
+ rename 'is_vmcoreinfo_empty' to netdump/diskdump variants in
netdump.c and diskdump.c respectively
---
---
defs.h | 1 +
diskdump.c | 18 ++++++++++++++++++
kernel.c | 17 ++++++++++++-----
netdump.c | 19 +++++++++++++++++++
4 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index 156ac0232906..d28484ec44f9 100644
--- a/defs.h
+++ b/defs.h
@@ -6218,6 +6218,7 @@ void dump_kernel_table(int);
void dump_bt_info(struct bt_info *, char *where);
void dump_log(int);
void parse_kernel_version(char *);
+char *vmcoreinfo_read_from_memory(const char *);
#define LOG_LEVEL(v) ((v) & 0x07)
#define SHOW_LOG_LEVEL (0x1)
diff --git a/diskdump.c b/diskdump.c
index ce3cbb7b12dd..de907551153d 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -1041,6 +1041,13 @@ pfn_to_pos(ulong pfn)
return desc_pos;
}
+/**
+ * Check if vmcoreinfo in vmcore is missing/empty
+ */
+static bool is_diskdump_vmcoreinfo_empty(void)
+{
+ return (dd->sub_header_kdump->size_vmcoreinfo == 0);
+}
/*
* Determine whether a file is a diskdump creation, and if TRUE,
@@ -1088,6 +1095,17 @@ is_diskdump(char *file)
pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ /*
+ * vmcoreinfo can be empty in case of dump collected via virsh-dump
+ *
+ * check if vmcoreinfo is not available in vmcore, and try to read
+ * the vmcoreinfo from memory, using "vmcoreinfo_data" symbol
+ */
+ if (is_diskdump_vmcoreinfo_empty()) {
+ error(WARNING, "vmcoreinfo is empty, will read from symbols\n");
+ pc->read_vmcoreinfo = vmcoreinfo_read_from_memory;
+ }
+
if ((pc->flags2 & GET_LOG) && KDUMP_CMPRS_VALID()) {
pc->dfd = dd->dfd;
pc->readmem = read_diskdump;
diff --git a/kernel.c b/kernel.c
index e4213d7a663e..0e17874c503c 100644
--- a/kernel.c
+++ b/kernel.c
@@ -99,7 +99,6 @@ static ulong dump_audit_skb_queue(ulong);
static ulong __dump_audit(char *);
static void dump_audit(void);
static void dump_printk_safe_seq_buf(int);
-static char *vmcoreinfo_read_string(const char *);
static void check_vmcoreinfo(void);
static int is_pvops_xen(void);
static int get_linux_banner_from_vmlinux(char *, size_t);
@@ -11892,8 +11891,8 @@ dump_printk_safe_seq_buf(int msg_flags)
* Returns a string (that has to be freed by the caller) that contains the
* value for key or NULL if the key has not been found.
*/
-static char *
-vmcoreinfo_read_string(const char *key)
+char *
+vmcoreinfo_read_from_memory(const char *key)
{
char *buf, *value_string, *p1, *p2;
size_t value_length;
@@ -11903,6 +11902,14 @@ vmcoreinfo_read_string(const char *key)
buf = value_string = NULL;
+ if (!(pc->flags & GDB_INIT)) {
+ /*
+ * GDB interface hasn't been initialised yet, so can't
+ * access vmcoreinfo_data
+ */
+ return NULL;
+ }
+
switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
{
case TYPE_CODE_PTR:
@@ -11958,10 +11965,10 @@ check_vmcoreinfo(void)
switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
{
case TYPE_CODE_PTR:
- pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ pc->read_vmcoreinfo = vmcoreinfo_read_from_memory;
break;
case TYPE_CODE_ARRAY:
- pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ pc->read_vmcoreinfo = vmcoreinfo_read_from_memory;
break;
}
}
diff --git a/netdump.c b/netdump.c
index c7ff009e7f90..69100a92e067 100644
--- a/netdump.c
+++ b/netdump.c
@@ -111,6 +111,14 @@ map_cpus_to_prstatus(void)
FREEBUF(nt_ptr);
}
+/**
+ * Check if vmcoreinfo in vmcore is missing/empty
+ */
+static bool is_netdump_vmcoreinfo_empty(void)
+{
+ return (nd->size_vmcoreinfo == 0);
+}
+
/*
* Determine whether a file is a netdump/diskdump/kdump creation,
* and if TRUE, initialize the vmcore_data structure.
@@ -464,6 +472,17 @@ is_netdump(char *file, ulong source_query)
pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ /*
+ * vmcoreinfo can be empty in case of dump collected via virsh-dump
+ *
+ * check if vmcoreinfo is not available in vmcore, and try to read
+ * the vmcoreinfo from memory, using "vmcoreinfo_data" symbol
+ */
+ if (is_netdump_vmcoreinfo_empty()) {
+ error(WARNING, "vmcoreinfo is empty, will read from symbols\n");
+ pc->read_vmcoreinfo = vmcoreinfo_read_from_memory;
+ }
+
if ((source_query == KDUMP_LOCAL) &&
(pc->flags2 & GET_OSRELEASE))
kdump_get_osrelease();
--
2.50.1
4 weeks
Reliable Take Online Class Help Service for Students
by nancynicholas440@gmail.com
Before I discovered the Take Online Class Help Service, I was struggling to balance my work and accelerated online courses, and it fundamentally altered my academic experience. I was given a qualified expert by their courteous and professional staff who was aware of my course requirements and regularly produced excellent work on schedule. Regular updates and progress tracking gave me peace of mind that everything was being handled dependably. I was able to succeed because of this service, which also helped me feel less stressed and free up time to concentrate on my studies.
Visit Site: https://domyclassesonline.com/online-class-help/
4 weeks, 1 day
[PATCH] help: Add 'help -l' to show memory layout
by Rongwei Wang
From: Rongwei Wang <rongwei.wrw(a)gmail.com>
'help -m' can show most of variables which
relates to memory layout, e.g. userspace_top,
page_offset, vmalloc_start_addr, etc. They
aren't a visual way to show a memory layout
for kernel space.
This patch provides 'help -l' to show memory
layout, usage likes:
crash> help -l
Gap Hole: 0xffffffffff7ff001 - 0xffffffffffffffff Size: 8.0 MB
Fixmap Area: 0xffffffffff578000 - 0xffffffffff7ff000 Size: 2.5 MB
Gap Hole: 0xffffffffff000001 - 0xffffffffff577fff Size: 5.5 MB
Module Area: 0xffffffffa0000000 - 0xffffffffff000000 Size: 1.5 GB
Gap Hole: 0xffffffff84826001 - 0xffffffff9fffffff Size: 439.9 MB
Kernel Image: 0xffffffff81000000 - 0xffffffff84826000 Size: 56.1 MB
Gap Hole: 0xffffeb0000000000 - 0xffffffff80ffffff Size: 21.0 TB
Vmemmap Area: 0xffffea0000000000 - 0xffffeaffffffffff Size: 1.0 TB
Gap Hole: 0xffffe90000000000 - 0xffffe9ffffffffff Size: 1.0 TB
Vmalloc Area: 0xffffc90000000000 - 0xffffe8ffffffffff Size: 32.0 TB
Gap Hole: 0xffffc88000000000 - 0xffffc8ffffffffff Size: 512.0 GB
Linear Mapping: 0xffff888000000000 - 0xffffc87fffffffff Size: 64.0 TB
Linear Gap: 0xffff800000000000 - 0xffff887fffffffff Size: 8.5 TB
Gap Hole: 0x0000800000000000 - 0xffff7fffffffffff Size: 16776960.0 TB
User Space: 0x0000000000000000 - 0x00007fffffffffff Size: 128.0 TB
Signed-off-by: Rongwei Wang <rongwei.wrw(a)gmail.com>
---
defs.h | 14 +++-
help.c | 7 +-
memory.c | 11 +++
x86_64.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 266 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 4fecb83..a3f00d5 100644
--- a/defs.h
+++ b/defs.h
@@ -4100,12 +4100,23 @@ typedef signed int s32;
#define __PHYSICAL_MASK_SHIFT_5LEVEL 52
#define __PHYSICAL_MASK_SHIFT (machdep->machspec->physical_mask_shift)
#define __PHYSICAL_MASK ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
-#define __VIRTUAL_MASK_SHIFT 48
+#define __VIRTUAL_MASK_SHIFT 47
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PHYSICAL_PAGE_MASK (~(PAGE_SIZE-1) & __PHYSICAL_MASK )
+
+#define KASAN_SHADOW_OFFSET 0xdffffc0000000000
+#define KASAN_SHADOW_SCALE_SHIFT 3
+
+#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
+ ((-1UL << __VIRTUAL_MASK_SHIFT) >> \
+ KASAN_SHADOW_SCALE_SHIFT))
+#define KASAN_SHADOW_END (KASAN_SHADOW_START + \
+ (1ULL << (__VIRTUAL_MASK_SHIFT - \
+ KASAN_SHADOW_SCALE_SHIFT)))
+
#define _PAGE_BIT_NX 63
#define _PAGE_PRESENT 0x001
#define _PAGE_RW 0x002
@@ -5911,6 +5922,7 @@ int phys_to_page(physaddr_t, ulong *);
int generic_get_kvaddr_ranges(struct vaddr_range *);
int l1_cache_size(void);
int dumpfile_memory(int);
+void dump_memory_layout(void);
#define DUMPFILE_MEM_USED (1)
#define DUMPFILE_FREE_MEM (2)
#define DUMPFILE_MEM_DUMP (3)
diff --git a/help.c b/help.c
index 5d61e0d..cd54744 100644
--- a/help.c
+++ b/help.c
@@ -538,7 +538,7 @@ cmd_help(void)
oflag = 0;
while ((c = getopt(argcnt, args,
- "efNDdmM:ngcaBbHhkKsvVoptTzLOr")) != EOF) {
+ "efNDdmM:ngcaBbHhkKsvVoptTzLOrl")) != EOF) {
switch(c)
{
case 'e':
@@ -666,6 +666,7 @@ cmd_help(void)
fprintf(fp, " -v - vm_table\n");
fprintf(fp, " -V - vm_table (verbose)\n");
fprintf(fp, " -z - help options\n");
+ fprintf(fp, " -l - show memory layout\n");
return;
case 'L':
@@ -676,6 +677,10 @@ cmd_help(void)
dump_registers();
return;
+ case 'l':
+ dump_memory_layout();
+ return;
+
default:
argerrs++;
break;
diff --git a/memory.c b/memory.c
index 400d31a..55ed2f1 100644
--- a/memory.c
+++ b/memory.c
@@ -17657,6 +17657,17 @@ dumpfile_memory(int cmd)
return retval;
}
+#ifdef X86_64
+extern void x86_64_dump_memory_layout(void);
+#endif
+
+void dump_memory_layout(void)
+{
+#ifdef X86_64
+ x86_64_dump_memory_layout();
+#endif
+}
+
/*
* Functions for sparse mem support
*/
diff --git a/x86_64.c b/x86_64.c
index d7da536..bfb53b4 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -1151,6 +1151,242 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "excpetion_functions_orig\n");
}
+#define MAX_LAYOUT 32
+struct mem_segment {
+ char name[64];
+ char desc[64];
+ unsigned long start;
+ unsigned long end;
+};
+
+struct mem_layout {
+ int count;
+ struct mem_segment segs[MAX_LAYOUT];
+};
+
+char* format_bytes(unsigned long bytes, char* buffer, int buffer_size)
+{
+ const char* units[] = {"B", "KB", "MB", "GB", "TB"};
+ int i = 0;
+ double readable_size = (double)bytes;
+
+ /* Handle the edge case of zero bytes */
+ if (bytes == 0) {
+ snprintf(buffer, buffer_size, "0 B");
+ return buffer;
+ }
+
+ /* Handle negative values if necessary, though size is typically non-negative */
+ if (bytes < 0) {
+ snprintf(buffer, buffer_size, "Invalid size");
+ return buffer;
+ }
+
+ while (readable_size >= 1024 && i < (sizeof(units) / sizeof(units[0]) - 1)) {
+ readable_size /= 1024;
+ i++;
+ }
+
+ memset(buffer, '\0', buffer_size);
+ snprintf(buffer, buffer_size, "%.1f %s", readable_size, units[i]);
+
+ return buffer;
+}
+
+int compare_segments(const void *a, const void *b)
+{
+ const struct mem_segment *seg_a = (const struct mem_segment *)a;
+ const struct mem_segment *seg_b = (const struct mem_segment *)b;
+
+ if (seg_a->start > seg_b->start) return -1;
+ if (seg_a->start < seg_b->start) return 1;
+ return 0;
+}
+
+void print_layout(struct mem_layout *layout)
+{
+ struct mem_segment *segs = layout->segs;
+ struct mem_segment seg;
+ int i;
+
+ if (layout == NULL)
+ return;
+
+ for (i=0; i<layout->count; i++) {
+ seg = segs[i];
+
+ fprintf(fp, "%s:\t 0x%016lx - 0x%016lx\t Size: %s\n", seg.name, seg.start,
+ seg.end, seg.desc);
+ }
+}
+
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
+/*
+ * memory layout:
+ *
+ * Gap Area: 0xffffffffff7ff001 - 0xffffffffffffffff Size: 8.0 MB
+ * Fixmap Area: 0xffffffffff578000 - 0xffffffffff7ff000 Size: 2.5 MB
+ * Gap Area: 0xffffffffff000001 - 0xffffffffff577fff Size: 5.5 MB
+ * Module Area: 0xffffffffa0000000 - 0xffffffffff000000 Size: 1.5 GB
+ * Gap Area: 0xffffffff84826001 - 0xffffffff9fffffff Size: 439.9 MB
+ * Kernel Image: 0xffffffff81000000 - 0xffffffff84826000 Size: 56.1 MB
+ * Gap Area: 0xffffeb0000000000 - 0xffffffff80ffffff Size: 21.0 TB
+ * Vmemmap Area: 0xffffea0000000000 - 0xffffeaffffffffff Size: 1.0 TB
+ * Gap Area: 0xffffe90000000000 - 0xffffe9ffffffffff Size: 1.0 TB
+ * Vmalloc Area: 0xffffc90000000000 - 0xffffe8ffffffffff Size: 32.0 TB
+ * Gap Area: 0xffffc88000000000 - 0xffffc8ffffffffff Size: 512.0 GB
+ * Linear Mapping: 0xffff888000000000 - 0xffffc87fffffffff Size: 64.0 TB
+ * Linear Gap: 0xffff800000000000 - 0xffff887fffffffff Size: 8.5 TB
+ * Gap Area: 0x0000800000000000 - 0xffff7fffffffffff Size:16776960.0 TB
+ * User Space: 0x0000000000000000 - 0x00007fffffffffff Size: 128.0 TB
+ *
+ * kernel space:
+ * _end, _text
+ * vmemmap_end: ms->vmemmap_end
+ * vmemmap_vaddr: ms->vmemmap_vaddr
+ * vmalloc_end: ms->vmalloc_end
+ * vmalloc_start_addr: ms->vmalloc_start_addr
+ * page_offset_base: ms->page_offset
+ *
+ * user space:
+ * userspace_top: ms->userspace_top
+ *
+ */
+void x86_64_dump_memory_layout(void)
+{
+ struct mem_layout *layout = NULL;
+ ulong text_start, text_end;
+ struct machine_specific *ms = machdep->machspec;
+ int i, next_idx;
+ char size_buf[20];
+ long value = 0;
+
+ layout = malloc(sizeof(struct mem_layout));
+ if (layout == NULL || layout->count == 0) {
+ printf("Layout is empty, nothing to print.\n");
+ return;
+ }
+
+ /* Create a temporary copy to sort for printing, preserving the original order. */
+ struct mem_segment *segments = layout->segs;
+ if(!segments) {
+ perror("Failed to allocate memory for sorting");
+ return;
+ }
+
+ if (!symbol_exists("_text"))
+ return;
+ else
+ text_start = symbol_value("_text");
+
+ if (!symbol_exists("_end"))
+ return;
+ else
+ text_end = symbol_value("_end");
+
+ snprintf(segments[0].name, 64, "Kernel Image");
+ snprintf(segments[0].desc, 64, "%s",
+ format_bytes(text_end - text_start + 1, size_buf, 20));
+ segments[0].start = text_start;
+ segments[0].end = text_end;
+
+ snprintf(segments[1].name, 64, "Vmemmap Area");
+ snprintf(segments[1].desc, 64, "%s",
+ format_bytes(ms->vmemmap_end - ms->vmemmap_vaddr + 1, size_buf, 20));
+ segments[1].start = (ulong)ms->vmemmap_vaddr;
+ segments[1].end = (ulong)ms->vmemmap_end;
+
+ snprintf(segments[2].name, 64, "Module Area");
+ snprintf(segments[2].desc, 64, "%s",
+ format_bytes(ms->modules_end - ms->modules_vaddr + 1, size_buf, 20));
+ segments[2].start = (ulong)ms->modules_vaddr;
+ segments[2].end = (ulong)ms->modules_end;
+
+ snprintf(segments[3].name, 64, "Vmalloc Area");
+ snprintf(segments[3].desc, 64, "%s",
+ format_bytes(ms->vmalloc_end - ms->vmalloc_start_addr + 1, size_buf, 20));
+ segments[3].start = (ulong)ms->vmalloc_start_addr;
+ segments[3].end = (ulong)ms->vmalloc_end;
+
+ snprintf(segments[4].name, 64, "Linear Mapping");
+ segments[4].start = (ulong)ms->page_offset;
+ segments[4].end = (ulong)ms->page_offset + (1UL << machdep->max_physmem_bits) - 1;
+ snprintf(segments[4].desc, 64, "%s",
+ format_bytes(1UL << machdep->max_physmem_bits, size_buf, 20));
+
+ snprintf(segments[5].name, 64, "User Space");
+ snprintf(segments[5].desc, 64, "%s",
+ format_bytes((ulong)ms->userspace_top, size_buf, 20));
+ segments[5].start = 0UL;
+ segments[5].end = (ulong)ms->userspace_top - 1;
+
+ snprintf(segments[6].name, 64, "Linear Gap");
+ segments[6].start = -1UL - (1UL << __VIRTUAL_MASK_SHIFT) + 1;
+ segments[6].end = (ulong)ms->page_offset - 1;
+ snprintf(segments[6].desc, 64, "%s",
+ format_bytes(segments[6].end - segments[6].start + 1, size_buf, 20));
+
+ layout->count = 7;
+ if (kernel_symbol_exists("kasan_init")) {
+ snprintf(segments[7].name, 64, "KASAN");
+ segments[7].start = KASAN_SHADOW_START;
+ segments[7].end = KASAN_SHADOW_END;
+ snprintf(segments[7].desc, 64, "%s",
+ format_bytes(segments[7].end - segments[7].start + 1, size_buf, 20));
+ layout->count++;
+ }
+
+ if (enumerator_value("__end_of_permanent_fixed_addresses", &value)) {
+ unsigned fixaddr_size = 0;
+ int idx = layout->count;
+
+ fixaddr_size = value << PAGE_SHIFT;
+
+ snprintf(segments[7].name, 64, "Fixmap Area");
+ segments[idx].end = round_up(VSYSCALL_START + PAGE_SIZE, 1 << PMD_SHIFT) - PAGE_SIZE;
+ segments[idx].start = segments[idx].end - fixaddr_size;
+
+ snprintf(segments[idx].desc, 64, "%s",
+ format_bytes(segments[idx].end - segments[idx].start + 1, size_buf, 20));
+ layout->count++;
+ }
+
+ /* Sort segments from highest address to lowest. */
+ qsort(segments, layout->count, sizeof(struct mem_segment), compare_segments);
+
+ next_idx = layout->count;
+ /* Insert gap area */
+ for (i=0; i<layout->count; i++) {
+ unsigned long prev_start;
+ unsigned long end = segments[i].end;
+
+ if (i == 0)
+ prev_start = -1UL;
+ else
+ prev_start = segments[i-1].start;
+
+ if (prev_start == (end + 1))
+ continue;
+
+ snprintf(segments[next_idx].name, 64, "Gap Hole");
+ segments[next_idx].start = end + 1;
+ segments[next_idx].end = (i == 0) ? prev_start : prev_start - 1;
+ snprintf(segments[next_idx].desc, 64, "%s",
+ format_bytes(segments[next_idx].end - segments[next_idx].start + 1, size_buf, 20));
+
+ next_idx++;
+ }
+
+ layout->count = next_idx;
+ qsort(segments, layout->count, sizeof(struct mem_segment), compare_segments);
+
+ print_layout(layout);
+ free(layout);
+}
+
/*
* Gather the cpu_pda array info, updating any smp-related items that
* were possibly bypassed or improperly initialized in kernel_init().
--
2.43.5
4 weeks, 1 day