|
|
06c2a2 |
From 09288f2058c8066a2729588ec668eed3e1140028 Mon Sep 17 00:00:00 2001
|
|
|
06c2a2 |
From: Takao Indoh <indou.takao@jp.fujitsu.com>
|
|
|
06c2a2 |
Date: Thu, 26 Oct 2017 20:33:01 +0900
|
|
|
06c2a2 |
Subject: [PATCH 4/4] [PATCH v3 4/4] sadump: Fix a KASLR problem of sadump
|
|
|
06c2a2 |
while kdump is working
|
|
|
06c2a2 |
|
|
|
06c2a2 |
In the calc_kaslr_offset(), kaslr_offset and phys_base are calculated
|
|
|
06c2a2 |
using IDTR and CR3, but this solution does not work in the following
|
|
|
06c2a2 |
cases.
|
|
|
06c2a2 |
|
|
|
06c2a2 |
1) If the dump is captured on early stage of kernel boot, IDTR points
|
|
|
06c2a2 |
early IDT table(early_idts) instead of normal IDT(idt_table).
|
|
|
06c2a2 |
2) If the dump is captured whle kdump is working, IDTR points IDT table
|
|
|
06c2a2 |
of 2nd kernel, not 1st kernel.
|
|
|
06c2a2 |
|
|
|
06c2a2 |
This patch fixes the case 2). Current implementation does not support
|
|
|
06c2a2 |
the case 1), need enhancement in the future. This patch gets kernel boot
|
|
|
06c2a2 |
parameter from "saved_command_line" and check if "elfcorehdr=" is
|
|
|
06c2a2 |
included in the parameter. If it's included, we are in the 2nd kernel.
|
|
|
06c2a2 |
Retrieve vmcoreinfo from address of "elfcorehdr=" and get kaslr_offset
|
|
|
06c2a2 |
and phys_base from vmcoreinfo.
|
|
|
06c2a2 |
|
|
|
06c2a2 |
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
|
|
06c2a2 |
---
|
|
|
06c2a2 |
makedumpfile.c | 1 +
|
|
|
06c2a2 |
makedumpfile.h | 1 +
|
|
|
06c2a2 |
sadump_info.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
06c2a2 |
3 files changed, 273 insertions(+)
|
|
|
06c2a2 |
|
|
|
06c2a2 |
diff --git a/makedumpfile.c b/makedumpfile.c
|
|
|
06c2a2 |
index 41438a344574..6d5fc8b95415 100644
|
|
|
06c2a2 |
--- a/makedumpfile-1.6.2/makedumpfile.c
|
|
|
06c2a2 |
+++ b/makedumpfile-1.6.2/makedumpfile.c
|
|
|
06c2a2 |
@@ -1556,6 +1556,7 @@ get_symbol_info(void)
|
|
|
06c2a2 |
|
|
|
06c2a2 |
SYMBOL_INIT(divide_error, "divide_error");
|
|
|
06c2a2 |
SYMBOL_INIT(idt_table, "idt_table");
|
|
|
06c2a2 |
+ SYMBOL_INIT(saved_command_line, "saved_command_line");
|
|
|
06c2a2 |
|
|
|
06c2a2 |
return TRUE;
|
|
|
06c2a2 |
}
|
|
|
06c2a2 |
diff --git a/makedumpfile.h b/makedumpfile.h
|
|
|
06c2a2 |
index 5f814e7bc3c1..db753792bca6 100644
|
|
|
06c2a2 |
--- a/makedumpfile-1.6.2/makedumpfile.h
|
|
|
06c2a2 |
+++ b/makedumpfile-1.6.2/makedumpfile.h
|
|
|
06c2a2 |
@@ -1602,6 +1602,7 @@ struct symbol_table {
|
|
|
06c2a2 |
unsigned long long kexec_crash_image;
|
|
|
06c2a2 |
unsigned long long divide_error;
|
|
|
06c2a2 |
unsigned long long idt_table;
|
|
|
06c2a2 |
+ unsigned long long saved_command_line;
|
|
|
06c2a2 |
|
|
|
06c2a2 |
/*
|
|
|
06c2a2 |
* symbols on ppc64 arch
|
|
|
06c2a2 |
diff --git a/sadump_info.c b/sadump_info.c
|
|
|
06c2a2 |
index 29ccef881370..148d4baaa538 100644
|
|
|
06c2a2 |
--- a/makedumpfile-1.6.2/sadump_info.c
|
|
|
06c2a2 |
+++ b/makedumpfile-1.6.2/sadump_info.c
|
|
|
06c2a2 |
@@ -1059,6 +1059,241 @@ get_vec0_addr(ulong idtr)
|
|
|
06c2a2 |
}
|
|
|
06c2a2 |
|
|
|
06c2a2 |
/*
|
|
|
06c2a2 |
+ * Parse a string of [size[KMG]@]offset[KMG]
|
|
|
06c2a2 |
+ * Import from Linux kernel(lib/cmdline.c)
|
|
|
06c2a2 |
+ */
|
|
|
06c2a2 |
+static ulong memparse(char *ptr, char **retptr)
|
|
|
06c2a2 |
+{
|
|
|
06c2a2 |
+ char *endptr;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ unsigned long long ret = strtoull(ptr, &endptr, 0);
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ switch (*endptr) {
|
|
|
06c2a2 |
+ case 'E':
|
|
|
06c2a2 |
+ case 'e':
|
|
|
06c2a2 |
+ ret <<= 10;
|
|
|
06c2a2 |
+ case 'P':
|
|
|
06c2a2 |
+ case 'p':
|
|
|
06c2a2 |
+ ret <<= 10;
|
|
|
06c2a2 |
+ case 'T':
|
|
|
06c2a2 |
+ case 't':
|
|
|
06c2a2 |
+ ret <<= 10;
|
|
|
06c2a2 |
+ case 'G':
|
|
|
06c2a2 |
+ case 'g':
|
|
|
06c2a2 |
+ ret <<= 10;
|
|
|
06c2a2 |
+ case 'M':
|
|
|
06c2a2 |
+ case 'm':
|
|
|
06c2a2 |
+ ret <<= 10;
|
|
|
06c2a2 |
+ case 'K':
|
|
|
06c2a2 |
+ case 'k':
|
|
|
06c2a2 |
+ ret <<= 10;
|
|
|
06c2a2 |
+ endptr++;
|
|
|
06c2a2 |
+ default:
|
|
|
06c2a2 |
+ break;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (retptr)
|
|
|
06c2a2 |
+ *retptr = endptr;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ return ret;
|
|
|
06c2a2 |
+}
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+/*
|
|
|
06c2a2 |
+ * Find "elfcorehdr=" in the boot parameter of kernel and return the address
|
|
|
06c2a2 |
+ * of elfcorehdr.
|
|
|
06c2a2 |
+ */
|
|
|
06c2a2 |
+static ulong
|
|
|
06c2a2 |
+get_elfcorehdr(ulong cr3)
|
|
|
06c2a2 |
+{
|
|
|
06c2a2 |
+ char cmdline[BUFSIZE], *ptr;
|
|
|
06c2a2 |
+ ulong cmdline_vaddr;
|
|
|
06c2a2 |
+ ulong cmdline_paddr;
|
|
|
06c2a2 |
+ ulong buf_vaddr, buf_paddr;
|
|
|
06c2a2 |
+ char *end;
|
|
|
06c2a2 |
+ ulong elfcorehdr_addr = 0, elfcorehdr_size = 0;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (SYMBOL(saved_command_line) == NOT_FOUND_SYMBOL) {
|
|
|
06c2a2 |
+ ERRMSG("Can't get the symbol of saved_command_line.\n");
|
|
|
06c2a2 |
+ return 0;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+ cmdline_vaddr = SYMBOL(saved_command_line);
|
|
|
06c2a2 |
+ if ((cmdline_paddr = vtop4_x86_64_pagetable(cmdline_vaddr, cr3)) == NOT_PADDR)
|
|
|
06c2a2 |
+ return 0;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: cmdline vaddr: %lx\n", cmdline_vaddr);
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: cmdline paddr: %lx\n", cmdline_paddr);
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!readmem(PADDR, cmdline_paddr, &buf_vaddr, sizeof(ulong)))
|
|
|
06c2a2 |
+ return 0;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if ((buf_paddr = vtop4_x86_64_pagetable(buf_vaddr, cr3)) == NOT_PADDR)
|
|
|
06c2a2 |
+ return 0;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: cmdline buf vaddr: %lx\n", buf_vaddr);
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: cmdline buf paddr: %lx\n", buf_paddr);
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ memset(cmdline, 0, BUFSIZE);
|
|
|
06c2a2 |
+ if (!readmem(PADDR, buf_paddr, cmdline, BUFSIZE))
|
|
|
06c2a2 |
+ return 0;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ ptr = strstr(cmdline, "elfcorehdr=");
|
|
|
06c2a2 |
+ if (!ptr)
|
|
|
06c2a2 |
+ return 0;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: 2nd kernel detected.\n");
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ ptr += strlen("elfcorehdr=");
|
|
|
06c2a2 |
+ elfcorehdr_addr = memparse(ptr, &end;;
|
|
|
06c2a2 |
+ if (*end == '@') {
|
|
|
06c2a2 |
+ elfcorehdr_size = elfcorehdr_addr;
|
|
|
06c2a2 |
+ elfcorehdr_addr = memparse(end + 1, &end;;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: elfcorehdr_addr: %lx\n", elfcorehdr_addr);
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: elfcorehdr_size: %lx\n", elfcorehdr_size);
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ return elfcorehdr_addr;
|
|
|
06c2a2 |
+}
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+/*
|
|
|
06c2a2 |
+ * Get vmcoreinfo from elfcorehdr.
|
|
|
06c2a2 |
+ * Some codes are imported from Linux kernel(fs/proc/vmcore.c)
|
|
|
06c2a2 |
+ */
|
|
|
06c2a2 |
+static int
|
|
|
06c2a2 |
+get_vmcoreinfo_in_kdump_kernel(ulong elfcorehdr, ulong *addr, int *len)
|
|
|
06c2a2 |
+{
|
|
|
06c2a2 |
+ unsigned char e_ident[EI_NIDENT];
|
|
|
06c2a2 |
+ Elf64_Ehdr ehdr;
|
|
|
06c2a2 |
+ Elf64_Phdr phdr;
|
|
|
06c2a2 |
+ Elf64_Nhdr nhdr;
|
|
|
06c2a2 |
+ ulong ptr;
|
|
|
06c2a2 |
+ ulong nhdr_offset = 0;
|
|
|
06c2a2 |
+ int i;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!readmem(PADDR, elfcorehdr, e_ident, EI_NIDENT))
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (e_ident[EI_CLASS] != ELFCLASS64) {
|
|
|
06c2a2 |
+ ERRMSG("Only ELFCLASS64 is supportd\n");
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!readmem(PADDR, elfcorehdr, &ehdr, sizeof(ehdr)))
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ /* Sanity Check */
|
|
|
06c2a2 |
+ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
|
|
|
06c2a2 |
+ (ehdr.e_type != ET_CORE) ||
|
|
|
06c2a2 |
+ ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
|
|
|
06c2a2 |
+ ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
|
|
|
06c2a2 |
+ ehdr.e_version != EV_CURRENT ||
|
|
|
06c2a2 |
+ ehdr.e_ehsize != sizeof(Elf64_Ehdr) ||
|
|
|
06c2a2 |
+ ehdr.e_phentsize != sizeof(Elf64_Phdr) ||
|
|
|
06c2a2 |
+ ehdr.e_phnum == 0) {
|
|
|
06c2a2 |
+ ERRMSG("Invalid elf header\n");
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ ptr = elfcorehdr + ehdr.e_phoff;
|
|
|
06c2a2 |
+ for (i = 0; i < ehdr.e_phnum; i++) {
|
|
|
06c2a2 |
+ ulong offset;
|
|
|
06c2a2 |
+ char name[16];
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!readmem(PADDR, ptr, &phdr, sizeof(phdr)))
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ ptr += sizeof(phdr);
|
|
|
06c2a2 |
+ if (phdr.p_type != PT_NOTE)
|
|
|
06c2a2 |
+ continue;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ offset = phdr.p_offset;
|
|
|
06c2a2 |
+ if (!readmem(PADDR, offset, &nhdr, sizeof(nhdr)))
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ offset += divideup(sizeof(Elf64_Nhdr), sizeof(Elf64_Word))*
|
|
|
06c2a2 |
+ sizeof(Elf64_Word);
|
|
|
06c2a2 |
+ memset(name, 0, sizeof(name));
|
|
|
06c2a2 |
+ if (!readmem(PADDR, offset, name, sizeof(name)))
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if(!strcmp(name, "VMCOREINFO")) {
|
|
|
06c2a2 |
+ nhdr_offset = offset;
|
|
|
06c2a2 |
+ break;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!nhdr_offset)
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ *addr = nhdr_offset +
|
|
|
06c2a2 |
+ divideup(nhdr.n_namesz, sizeof(Elf64_Word))*
|
|
|
06c2a2 |
+ sizeof(Elf64_Word);
|
|
|
06c2a2 |
+ *len = nhdr.n_descsz;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: vmcoreinfo addr: %lx\n", *addr);
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: vmcoreinfo len: %d\n", *len);
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ return TRUE;
|
|
|
06c2a2 |
+}
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+/*
|
|
|
06c2a2 |
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd kernel.
|
|
|
06c2a2 |
+ * If we are in 2nd kernel, get kaslr_offset/phys_base from vmcoreinfo.
|
|
|
06c2a2 |
+ *
|
|
|
06c2a2 |
+ * 1. Get command line and try to retrieve "elfcorehdr=" boot parameter
|
|
|
06c2a2 |
+ * 2. If "elfcorehdr=" is not found in command line, we are in 1st kernel.
|
|
|
06c2a2 |
+ * There is nothing to do.
|
|
|
06c2a2 |
+ * 3. If "elfcorehdr=" is found, we are in 2nd kernel. Find vmcoreinfo
|
|
|
06c2a2 |
+ * using "elfcorehdr=" and retrieve kaslr_offset/phys_base from vmcoreinfo.
|
|
|
06c2a2 |
+ */
|
|
|
06c2a2 |
+int
|
|
|
06c2a2 |
+get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong *kaslr_offset,
|
|
|
06c2a2 |
+ ulong *phys_base)
|
|
|
06c2a2 |
+{
|
|
|
06c2a2 |
+ ulong elfcorehdr_addr = 0;
|
|
|
06c2a2 |
+ ulong vmcoreinfo_addr;
|
|
|
06c2a2 |
+ int vmcoreinfo_len;
|
|
|
06c2a2 |
+ char *buf, *pos;
|
|
|
06c2a2 |
+ int ret = FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ elfcorehdr_addr = get_elfcorehdr(cr3);
|
|
|
06c2a2 |
+ if (!elfcorehdr_addr)
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!get_vmcoreinfo_in_kdump_kernel(elfcorehdr_addr, &vmcoreinfo_addr,
|
|
|
06c2a2 |
+ &vmcoreinfo_len))
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!vmcoreinfo_len)
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ DEBUG_MSG("sadump: Find vmcoreinfo in kdump memory\n");
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!(buf = malloc(vmcoreinfo_len))) {
|
|
|
06c2a2 |
+ ERRMSG("Can't allocate vmcoreinfo buffer.\n");
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ if (!readmem(PADDR, vmcoreinfo_addr, buf, vmcoreinfo_len))
|
|
|
06c2a2 |
+ goto finish;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ pos = strstr(buf, STR_NUMBER("phys_base"));
|
|
|
06c2a2 |
+ if (!pos)
|
|
|
06c2a2 |
+ goto finish;
|
|
|
06c2a2 |
+ *phys_base = strtoull(pos + strlen(STR_NUMBER("phys_base")), NULL, 0);
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ pos = strstr(buf, STR_KERNELOFFSET);
|
|
|
06c2a2 |
+ if (!pos)
|
|
|
06c2a2 |
+ goto finish;
|
|
|
06c2a2 |
+ *kaslr_offset = strtoull(pos + strlen(STR_KERNELOFFSET), NULL, 16);
|
|
|
06c2a2 |
+ ret = TRUE;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+finish:
|
|
|
06c2a2 |
+ free(buf);
|
|
|
06c2a2 |
+ return ret;
|
|
|
06c2a2 |
+}
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+/*
|
|
|
06c2a2 |
* Calculate kaslr_offset and phys_base
|
|
|
06c2a2 |
*
|
|
|
06c2a2 |
* kaslr_offset:
|
|
|
06c2a2 |
@@ -1106,6 +1341,26 @@ get_vec0_addr(ulong idtr)
|
|
|
06c2a2 |
*
|
|
|
06c2a2 |
* Note that the address (A) cannot be used instead of (E) because (A) is
|
|
|
06c2a2 |
* not direct map address, it's a fixed map address.
|
|
|
06c2a2 |
+ *
|
|
|
06c2a2 |
+ * This solution works in most every case, but does not work in the
|
|
|
06c2a2 |
+ * following case.
|
|
|
06c2a2 |
+ *
|
|
|
06c2a2 |
+ * 1) If the dump is captured on early stage of kernel boot, IDTR points
|
|
|
06c2a2 |
+ * early IDT table(early_idts) instead of normal IDT(idt_table).
|
|
|
06c2a2 |
+ * 2) If the dump is captured whle kdump is working, IDTR points
|
|
|
06c2a2 |
+ * IDT table of 2nd kernel, not 1st kernel.
|
|
|
06c2a2 |
+ *
|
|
|
06c2a2 |
+ * Current implementation does not support the case 1), need
|
|
|
06c2a2 |
+ * enhancement in the future. For the case 2), get kaslr_offset and
|
|
|
06c2a2 |
+ * phys_base as follows.
|
|
|
06c2a2 |
+ *
|
|
|
06c2a2 |
+ * 1) Get kaslr_offset and phys_base using the above solution.
|
|
|
06c2a2 |
+ * 2) Get kernel boot parameter from "saved_command_line"
|
|
|
06c2a2 |
+ * 3) If "elfcorehdr=" is not included in boot parameter, we are in the
|
|
|
06c2a2 |
+ * first kernel, nothing to do any more.
|
|
|
06c2a2 |
+ * 4) If "elfcorehdr=" is included in boot parameter, we are in the 2nd
|
|
|
06c2a2 |
+ * kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and
|
|
|
06c2a2 |
+ * get kaslr_offset and phys_base from vmcoreinfo.
|
|
|
06c2a2 |
*/
|
|
|
06c2a2 |
int
|
|
|
06c2a2 |
calc_kaslr_offset(void)
|
|
|
06c2a2 |
@@ -1116,6 +1371,7 @@ calc_kaslr_offset(void)
|
|
|
06c2a2 |
int apicid;
|
|
|
06c2a2 |
unsigned long divide_error_vmcore, divide_error_vmlinux;
|
|
|
06c2a2 |
unsigned long kaslr_offset, phys_base;
|
|
|
06c2a2 |
+ unsigned long kaslr_offset_kdump, phys_base_kdump;
|
|
|
06c2a2 |
|
|
|
06c2a2 |
memset(&zero, 0, sizeof(zero));
|
|
|
06c2a2 |
for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
|
|
|
06c2a2 |
@@ -1161,6 +1417,21 @@ calc_kaslr_offset(void)
|
|
|
06c2a2 |
if (!get_symbol_info())
|
|
|
06c2a2 |
return FALSE;
|
|
|
06c2a2 |
|
|
|
06c2a2 |
+ /*
|
|
|
06c2a2 |
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd
|
|
|
06c2a2 |
+ * kernel. If we are in 2nd kernel, get kaslr_offset/phys_base
|
|
|
06c2a2 |
+ * from vmcoreinfo
|
|
|
06c2a2 |
+ */
|
|
|
06c2a2 |
+ if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump,
|
|
|
06c2a2 |
+ &phys_base_kdump)) {
|
|
|
06c2a2 |
+ info->kaslr_offset = kaslr_offset_kdump;
|
|
|
06c2a2 |
+ info->phys_base = phys_base_kdump;
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
+ /* Reload symbol */
|
|
|
06c2a2 |
+ if (!get_symbol_info())
|
|
|
06c2a2 |
+ return FALSE;
|
|
|
06c2a2 |
+ }
|
|
|
06c2a2 |
+
|
|
|
06c2a2 |
DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset);
|
|
|
06c2a2 |
DEBUG_MSG("sadump: phys_base=%lx\n", info->phys_base);
|
|
|
06c2a2 |
|
|
|
06c2a2 |
--
|
|
|
06c2a2 |
2.5.5
|
|
|
06c2a2 |
|