[PATCH] [makedumpfile] Implement memory regions on IA64
Bernhard Walle
bwalle at suse.de
Thu Apr 26 15:37:25 EDT 2007
This patch fixes an error in vaddr_to_offset_ia64() which happened on
a SGI machine here while retrieving the utsname from the kernel dump
image. It implements memory region support for IA64.
The code is mainly from crash (http://people.redhat.com/~anderson/).
Signed-off-by: Bernhard Walle <bwalle at suse.de>
---
ia64.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
makedumpfile.c | 4 ++++
makedumpfile.h | 9 ++++++++-
3 files changed, 69 insertions(+), 1 deletion(-)
--- a/ia64.c
+++ b/ia64.c
@@ -23,6 +23,8 @@ get_phys_base_ia64(struct DumpInfo *info
int i;
struct pt_load_segment *pls;
+ info->phys_base = 0;
+
/*
* Default to 64MB.
*/
@@ -48,5 +50,60 @@ get_machdep_info_ia64(struct DumpInfo *i
return TRUE;
}
+/*
+ * Convert Virtual Address to File Offest.
+ */
+off_t
+vaddr_to_offset_ia64(struct DumpInfo *info, unsigned long long vaddr)
+{
+ int i;
+ off_t offset;
+ struct pt_load_segment *pls;
+ unsigned long paddr;
+
+
+ switch (VADDR_REGION(vaddr)) {
+ case KERNEL_CACHED_REGION:
+ paddr = vaddr - (ulong)(KERNEL_CACHED_BASE);
+ break;
+
+ case KERNEL_UNCACHED_REGION:
+ paddr = vaddr - (ulong)(KERNEL_UNCACHED_BASE);
+ break;
+
+ case KERNEL_VMALLOC_REGION:
+ paddr = vaddr - info->kernel_start +
+ (info->phys_base & KERNEL_TR_PAGE_MASK);
+ break;
+
+ default:
+ ERRMSG("Unknown region (%d)\n", VADDR_REGION(vaddr));
+ return 0;
+ }
+
+ for (i = offset = 0; i < info->num_load_memory; i++) {
+ pls = &info->pt_load_segments[i];
+ if ((paddr >= pls->phys_start)
+ && (paddr < pls->phys_end)) {
+ offset = (off_t)(paddr - pls->phys_start) +
+ pls->file_offset;
+ break;
+ }
+ }
+
+ return offset;
+}
+
+int
+get_machdep_kernel_start_ia64(struct DumpInfo *info)
+{
+ if (SYMBOL(_stext) != NOT_FOUND_SYMBOL)
+ info->kernel_start = SYMBOL(_stext);
+
+ /* TODO: fallback */
+
+ return TRUE;
+}
+
#endif /* ia64 */
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2206,6 +2206,10 @@ initial(struct DumpInfo *info)
if (!get_structure_info(info))
return FALSE;
}
+
+ if (!get_machdep_kernel_start(info))
+ return FALSE;
+
if (!check_release(info))
return FALSE;
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -377,6 +377,7 @@ int get_machdep_info_x86();
#define get_phys_base(X) TRUE
#define get_machdep_info(X) get_machdep_info_x86(X)
#define vaddr_to_offset(X, Y) vaddr_to_offset_general(X,Y)
+#define get_machdep_kernel_start(X) TRUE
#endif /* x86 */
#ifdef __x86_64__
@@ -386,6 +387,7 @@ off_t vaddr_to_offset_x86_64();
#define get_phys_base(X) get_phys_base_x86_64(X)
#define get_machdep_info(X) get_machdep_info_x86_64(X)
#define vaddr_to_offset(X, Y) vaddr_to_offset_x86_64(X, Y)
+#define get_machdep_kernel_start(X) TRUE
#endif /* x86_64 */
#ifdef __powerpc__ /* powerpc */
@@ -393,14 +395,18 @@ int get_machdep_info_ppc64();
#define get_machdep_info(X) get_machdep_info_ppc64(X)
#define get_phys_base(X) TRUE
#define vaddr_to_offset(X, Y) vaddr_to_offset_general(X, Y)
+#define get_machdep_kernel_start(X) TRUE
#endif /* powerpc */
#ifdef __ia64__ /* ia64 */
int get_phys_base_ia64();
int get_machdep_info_ia64();
+int get_machdep_kernel_start_ia64();
+off_t vaddr_to_offset_ia64();
#define get_machdep_info(X) get_machdep_info_ia64(X)
#define get_phys_base(X) get_phys_base_ia64(X)
-#define vaddr_to_offset(X, Y) vaddr_to_offset_general(X, Y)
+#define get_machdep_kernel_start(X) get_machdep_kernel_start_ia64(X)
+#define vaddr_to_offset(X, Y) vaddr_to_offset_ia64(X, Y)
#define VADDR_REGION(X) ((X) >> REGION_SHIFT)
#endif /* ia64 */
@@ -491,6 +497,7 @@ struct DumpInfo {
unsigned long max_physmem_bits;
unsigned long sections_per_root;
unsigned long phys_base;
+ unsigned long kernel_start;
/*
* diskdimp info:
More information about the kexec
mailing list