Previously for x86_64, when memory is randomized, the region addresses
such as vmalloc_start_addr/vmemmap_vaddr/modules_vaddr are firstly set
to a default value before POST_RELOC phase, then get refreshed with the
actual value in POST_GDB phase.
However for crash mininal mode, POST_GDB phase is not called, which
leaving the region addresses unrefreshed and incorrect. As a consequence,
the x86_64_IS_VMALLOC_ADDR check will give a faulty result when
value_search tries to search a symbol by address.
For example, in crash minimal mode we can observe the following issue:
crash> dis -f panic
dis: cannot resolve address: ffffffffb20e0d30
crash> sym panic
ffffffffb20e0d30 (T) panic
/usr/src/debug/kernel-4.18.0-290/linux-4.18.0-290/kernel/panic.c: 168
crash> sym ffffffffb20e0d30
symbol not found: ffffffffb20e0d30
In this patch, we will move the code which update the region addresses into
POST_RELOC phase, so in mininal mode the regions can get the correct
addresses.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
x86_64.c | 52 ++++++++++++++++++++++++++--------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 552d619..2fb1277 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -384,6 +384,31 @@ x86_64_init(int when)
"page_offset_base", QUIET|FAULT_ON_ERROR);
machdep->kvbase = machdep->machspec->page_offset;
machdep->identity_map_base = machdep->machspec->page_offset;
+
+ readmem(symbol_value("vmalloc_base"), KVADDR,
+ &machdep->machspec->vmalloc_start_addr,
+ sizeof(ulong), "vmalloc_base", FAULT_ON_ERROR);
+ if (machdep->flags & VM_5LEVEL)
+ machdep->machspec->vmalloc_end =
+ machdep->machspec->vmalloc_start_addr + TERABYTES(1280) - 1;
+ else
+ machdep->machspec->vmalloc_end =
+ machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
+ if (kernel_symbol_exists("vmemmap_base")) {
+ readmem(symbol_value("vmemmap_base"), KVADDR,
+ &machdep->machspec->vmemmap_vaddr, sizeof(ulong),
+ "vmemmap_base", FAULT_ON_ERROR);
+ machdep->machspec->vmemmap_end =
+ machdep->machspec->vmemmap_vaddr +
+ TERABYTES(1) - 1;
+ } else {
+ machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_2_6_31;
+ machdep->machspec->vmemmap_end = VMEMMAP_END_2_6_31;
+ }
+ machdep->machspec->modules_vaddr = __START_KERNEL_map +
+ (machdep->machspec->kernel_image_size ?
+ machdep->machspec->kernel_image_size : GIGABYTES(1));
+ machdep->machspec->modules_end = MODULES_END_2_6_31;
}
break;
@@ -414,32 +439,7 @@ x86_64_init(int when)
machdep->machspec->modules_end = MODULES_END_2_6_27;
}
if (THIS_KERNEL_VERSION >= LINUX(2,6,31)) {
- if (machdep->flags & RANDOMIZED) {
- readmem(symbol_value("vmalloc_base"), KVADDR,
- &machdep->machspec->vmalloc_start_addr,
- sizeof(ulong), "vmalloc_base", FAULT_ON_ERROR);
- if (machdep->flags & VM_5LEVEL)
- machdep->machspec->vmalloc_end =
- machdep->machspec->vmalloc_start_addr + TERABYTES(1280) - 1;
- else
- machdep->machspec->vmalloc_end =
- machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
- if (kernel_symbol_exists("vmemmap_base")) {
- readmem(symbol_value("vmemmap_base"), KVADDR,
- &machdep->machspec->vmemmap_vaddr, sizeof(ulong),
- "vmemmap_base", FAULT_ON_ERROR);
- machdep->machspec->vmemmap_end =
- machdep->machspec->vmemmap_vaddr +
- TERABYTES(1) - 1;
- } else {
- machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_2_6_31;
- machdep->machspec->vmemmap_end = VMEMMAP_END_2_6_31;
- }
- machdep->machspec->modules_vaddr = __START_KERNEL_map +
- (machdep->machspec->kernel_image_size ?
- machdep->machspec->kernel_image_size : GIGABYTES(1));
- machdep->machspec->modules_end = MODULES_END_2_6_31;
- } else {
+ if (!(machdep->flags & RANDOMIZED)) {
machdep->machspec->vmalloc_start_addr = VMALLOC_START_ADDR_2_6_31;
machdep->machspec->vmalloc_end = VMALLOC_END_2_6_31;
machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_2_6_31;
--
2.33.1