Subject: [PATCH 09/18] Estimate phys_base based on linux_banner position This is a backport of commit 5054dd829ea155b6147b693c498439c018925618 Author: HATAYAMA Daisuke Date: Fri Dec 16 10:52:59 2011 +0900 [PATCH v2 09/14] Estimate phys_base based on linux_banner position sadump doesn't save phys_base, so we must estimate it in any way. Here we borrow the method in crash utility that we search a certain range of addresses for linux_banner symbol value. Signed-off-by: HATAYAMA Daisuke --- diff -Nrup kexec-tools-2.0.0.old/makedumpfile-1.3.5/makedumpfile.c kexec-tools-2.0.0/makedumpfile-1.3.5/makedumpfile.c --- kexec-tools-2.0.0.old/makedumpfile-1.3.5/makedumpfile.c 2012-04-05 04:16:01.284497737 -0400 +++ kexec-tools-2.0.0/makedumpfile-1.3.5/makedumpfile.c 2012-04-05 04:21:56.697586034 -0400 @@ -4463,6 +4463,15 @@ initial(void) (void) sadump_set_timestamp(&info->timestamp); + /* + * NOTE: phys_base is never saved by sadump and so + * must be computed in some way. We here choose the + * way of looking at linux_banner. See + * sadump_virt_phys_base(). The processing is + * postponed until debug information becomes + * available. + */ + } else if (!get_phys_base()) return FALSE; @@ -4538,6 +4547,9 @@ out: return FALSE; if (debug_info) { + if (info->flag_sadump) + (void) sadump_virt_phys_base(); + if (!get_machdep_info()) return FALSE; diff -Nrup kexec-tools-2.0.0.old/makedumpfile-1.3.5/sadump_info.c kexec-tools-2.0.0/makedumpfile-1.3.5/sadump_info.c --- kexec-tools-2.0.0.old/makedumpfile-1.3.5/sadump_info.c 2012-04-05 04:16:01.284497737 -0400 +++ kexec-tools-2.0.0/makedumpfile-1.3.5/sadump_info.c 2012-04-05 04:21:56.697586034 -0400 @@ -21,6 +21,12 @@ #include "makedumpfile.h" #include "sadump_mod.h" +#ifdef __x86_64__ + +#define MEGABYTES(x) ((x) * (1048576)) + +#endif + struct sadump_diskset_info { char *name_memory; int fd_memory; @@ -665,6 +671,47 @@ sadump_get_max_mapnr(void) return si->sh_memory->max_mapnr; } +#ifdef __x86_64__ + +int +sadump_virt_phys_base(void) +{ + char buf[BUFSIZE]; + unsigned long phys, linux_banner_phys; + + if (SYMBOL(linux_banner) == NOT_FOUND_SYMBOL) { + DEBUG_MSG("sadump: symbol linux_banner is not found\n"); + goto failed; + } + + linux_banner_phys = SYMBOL(linux_banner) - __START_KERNEL_map; + + if (readmem(PADDR, linux_banner_phys + info->phys_base, buf, + strlen("Linux version")) && STRNEQ(buf, "Linux version")) + return TRUE; + + for (phys = (-MEGABYTES(16)); phys != MEGABYTES(16+1); + phys += MEGABYTES(1)) { + if (readmem(PADDR, linux_banner_phys + phys, buf, + strlen("Linux version")) && + STRNEQ(buf, "Linux version")) { + DEBUG_MSG("sadump: phys_base: %lx %s\n", phys, + info->phys_base != phys ? "override" : ""); + info->phys_base = phys; + return TRUE; + } + } + +failed: + info->phys_base = 0; + + DEBUG_MSG("sadump: failed to calculate phys_base; default to 0\n"); + + return FALSE; +} + +#endif /* __x86_64__ */ + int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size) { diff -Nrup kexec-tools-2.0.0.old/makedumpfile-1.3.5/sadump_info.h kexec-tools-2.0.0/makedumpfile-1.3.5/sadump_info.h --- kexec-tools-2.0.0.old/makedumpfile-1.3.5/sadump_info.h 2012-04-05 04:16:01.283497660 -0400 +++ kexec-tools-2.0.0/makedumpfile-1.3.5/sadump_info.h 2012-04-05 04:21:56.698508274 -0400 @@ -22,6 +22,19 @@ #include "makedumpfile.h" +#ifdef __x86_64__ + +int sadump_virt_phys_base(void); + +#else + +static inline int sadump_virt_phys_base(void) +{ + return TRUE; +} + +#endif + #if defined(__x86__) || defined(__x86_64__) int check_and_get_sadump_header_info(char *filename);