FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Crash Utility

 
 
LinkBack Thread Tools
 
Old 05-25-2010, 02:25 PM
Vitaly Kuzmichev
 
Default Patch to add LKCD vmcore validation feature

Hello,
Attached is the patch to add separate tool for validating LKCD netdumps
and blockdumps.
We are planning to add this feature in our fork of crash-3.10.
Our customers requested this feature, but we have found that the 'crash'
does not print any warnings when someone tries to load incomplete
vmcore. They need a simple way to verify if core file generated from
LKCD is complete.


--
Best regards,
Vitaly Kuzmichev, Software Engineer,
MontaVista Software, LLC.
Source: MontaVista Software, Inc.
MR: 37433
Type: Enhancement
Disposition: needs submitting to lkcd.sourceforge.net
Signed-off-by: Vitaly Kuzmichev <vkuzmichev@mvista.com>
Description:
Adding LKCD Vmcore validation (completeness checking) feature.

diff -urpN crash-3.10-11.orig/check.c crash-3.10-11.new/check.c
--- crash-3.10-11.orig/check.c 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/check.c 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,234 @@
+/* check.c - core analysis suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "check_defs.h"
+
+int check_pages = 0, only_header = 0, endless = 0,
+ verbose = 0, silent = 0,
+ print_header = 1, print_asmheader = 0, print_pages = 0;
+off_t dump_header_offset = 0;
+
+void usage(const char *argv0)
+{
+ printf("
");
+ printf("%s %s - LKCD vmcore files validation feature
",
+ basename(argv0), build_version);
+ printf("Usage: %s [-abhHpPsSv] FILE
", argv0);
+ printf(" -h This help page
");
+ printf(" -a Print asm header
");
+ printf(" -b The FILE is device or device raw dump
");
+ printf(" -H Do not check end page, print only dump header
");
+ printf(" -p Check all pages in the dump
");
+ printf(" -P Print each page header verbosely
");
+ printf(" -s Be silent, print only result
");
+ printf(" -S Do not print anything (result will be in return code)
");
+ printf(" -v Be verbose, print all information from dump headers
");
+ printf(" FILE Vmcore or device file to check
");
+ printf("
");
+}
+
+int main(int argc, char **argv)
+{
+ uint64_t magic;
+ uint32_t version;
+ int fd, opt, result;
+ char *file;
+ struct stat sb;
+
+ lkcd_helper
+ lkcd_check_header = 0,
+ lkcd_check_asmheader = 0,
+ lkcd_check_pages = 0,
+ lkcd_check_end = 0;
+ /*
+ * Get and verify command line options.
+ */
+ opterr = 0;
+ optind = 0;
+ while((opt = getopt(argc, argv, "abhHpPsSv")) != -1) {
+ switch (opt) {
+ case 'a':
+ print_asmheader = 1;
+ break;
+ case 'b':
+ dump_header_offset = LKCD_DUMP_HEADER_OFFSET;
+ endless = 1;
+ break;
+ case 'h':
+ usage(argv[0]);
+ return E_BADARGS;
+ case 'H':
+ only_header = 1;
+ break;
+ case 'p':
+ check_pages = 1;
+ break;
+ case 'P':
+ check_pages = 1;
+ print_pages = 1;
+ break;
+ case 's':
+ silent = 1;
+ verbose = 0;
+ break;
+ case 'S':
+ silent = 2;
+ verbose = 0;
+ break;
+ case 'v':
+ silent = 0;
+ verbose = 1;
+ break;
+ default:
+ usage(argv[0]);
+ return E_BADARGS;
+ }
+ }
+
+ if (optind + 1 != argc) {
+ usage(argv[0]);
+ return E_BADARGS;
+ }
+ file = argv[optind];
+
+ if (stat(file, &sb)) {
+ perror(file);
+ return E_NOFILE;
+ }
+ switch (sb.st_mode & S_IFMT) {
+ case S_IFBLK:
+ case S_IFCHR:
+ dump_header_offset = LKCD_DUMP_HEADER_OFFSET;
+ endless = 1;
+ break;
+ case S_IFREG:
+ break;
+ case S_IFLNK:
+ case S_IFIFO:
+ case S_IFSOCK:
+ case S_IFDIR:
+ default:
+ usage(argv[0]);
+ return E_BADARGS;
+ }
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ perror(file);
+ return E_NOFILE;
+ }
+ if (silent < 2) {
+ field("File name");
+ printf("%s
", file);
+ }
+
+ if (lseek(fd, dump_header_offset, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the dump header at " PRI2offs,
+ dump_header_offset, dump_header_offset);
+ goto bad;
+ }
+ if (read(fd, &magic, sizeof(uint64_t)) != sizeof(uint64_t)) {
+ incomplete("Can not read dump magic number");
+ goto bad;
+ }
+
+ if ((magic == LKCD_DUMP_MAGIC_NUMBER) ||
+ (magic == LKCD_DUMP_MAGIC_LIVE))
+ init_target_endianess(0);
+ else {
+ uint64_t magic2 = bswap_u64(magic);
+ if ((magic2 == LKCD_DUMP_MAGIC_NUMBER) ||
+ (magic2 == LKCD_DUMP_MAGIC_LIVE))
+ init_target_endianess(1);
+ else {
+ corrupted("Invalid magic number %" PRIu64 , magic);
+ goto bad;
+ }
+ }
+ magic = from_target_u64(magic);
+
+ if (read(fd, &version, sizeof(uint32_t)) != sizeof(uint32_t)) {
+ incomplete("Can not find dump header");
+ goto bad;
+ }
+ version = from_target_u32(version);
+ switch (version & ~(LKCD_DUMP_MCLX_V0|LKCD_DUMP_MCLX_V1)) {
+ case LKCD_DUMP_V1:
+ lkcd_check_header = lkcd_dump_check_header_v1;
+ lkcd_check_asmheader = lkcd_dump_check_asmheader_v1;
+ lkcd_check_pages = lkcd_dump_check_pages_v1;
+ lkcd_check_end = lkcd_dump_check_end_page_v1;
+ break;
+
+ case LKCD_DUMP_V2:
+ case LKCD_DUMP_V3:
+ lkcd_check_header = lkcd_dump_check_header_v3;
+ lkcd_check_asmheader = lkcd_dump_check_asmheader_v3;
+ lkcd_check_pages = lkcd_dump_check_pages_v3;
+ lkcd_check_end = lkcd_dump_check_end_page_v3;
+ break;
+
+ case LKCD_DUMP_V5:
+ case LKCD_DUMP_V6:
+ case LKCD_DUMP_V7:
+ lkcd_check_header = lkcd_dump_check_header_v5;
+ lkcd_check_asmheader = lkcd_dump_check_asmheader_v5;
+ lkcd_check_pages = lkcd_dump_check_pages_v5;
+ lkcd_check_end = lkcd_dump_check_end_page_v5;
+ break;
+
+ case LKCD_DUMP_V8:
+ lkcd_check_header = lkcd_dump_check_header_v8;
+ lkcd_check_asmheader = lkcd_dump_check_asmheader_v8;
+ lkcd_check_pages = lkcd_dump_check_pages_v8;
+ lkcd_check_end = lkcd_dump_check_end_page_v8;
+ break;
+
+ default:
+ corrupted("Unsupported LKCD dump version: %" PRIu32 " (%#" PRIx32 ")",
+ version & ~(LKCD_DUMP_MCLX_V0|LKCD_DUMP_MCLX_V1), version);
+ goto bad;
+ }
+
+ result = lkcd_check_header(fd);
+ if(!result)
+ goto broken;
+ if(only_header)
+ goto done;
+
+ result = lkcd_check_asmheader(fd);
+ if(!result)
+ goto broken;
+
+ if (check_pages || endless)
+ result = lkcd_check_pages(fd);
+ else
+ result = lkcd_check_end(fd);
+ if (!result)
+ goto broken;
+
+ complete();
+done:
+ close(fd);
+ return E_SUCCESS;
+broken:
+ close(fd);
+ return E_BROKEN;
+bad:
+ close(fd);
+ return E_BADFORMAT;
+}
+
diff -urpN crash-3.10-11.orig/check_defs.h crash-3.10-11.new/check_defs.h
--- crash-3.10-11.orig/check_defs.h 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/check_defs.h 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,172 @@
+/* check_defs.h - core check suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifndef __USE_GNU
+#define __USE_GNU
+#include <string.h>
+#undef __USE_GNU
+#else
+#include <string.h>
+#endif
+
+#include "target_types.h"
+#undef from_target_u16
+#undef from_target_u32
+#undef from_target_u64
+
+#define E_SUCCESS 0
+#define E_BROKEN 1
+#define E_BADFORMAT 2
+#define E_NOFILE 3
+#define E_BADARGS 4
+
+#define LKCD_DUMP_MAGIC_NUMBER (0xa8190173618f23edULL)
+#define LKCD_DUMP_MAGIC_LIVE (0xa8190173618f23cdULL)
+
+#define LKCD_DUMP_V1 (0x1)
+#define LKCD_DUMP_V2 (0x2)
+#define LKCD_DUMP_V3 (0x3)
+#define LKCD_DUMP_V5 (0x5)
+#define LKCD_DUMP_V6 (0x6)
+#define LKCD_DUMP_V7 (0x7)
+#define LKCD_DUMP_V8 (0x8)
+#define LKCD_DUMP_VERSION_NUMBER_MASK (0xf)
+
+#define LKCD_DUMP_MCLX_V0 (0x80000000) /* MCLX mod of LKCD */
+#define LKCD_DUMP_MCLX_V1 (0x40000000) /* Extra page header data */
+#define LKCD_OFFSET_TO_FIRST_PAGE (64 * 1024)
+#define LKCD_OFFSET_TO_FIRST_BIG_PAGE (256 * 1024)
+#define LKCD_DUMP_HEADER_OFFSET (1 << 16)
+
+#if (defined(__USE_FILE_OFFSET64) || _FILE_OFFSET_BITS == 64 || __WORDSIZE == 64)
+#define PRI_off_t(c) __PRI64_PREFIX c
+#else
+#define PRI_off_t(c) c
+#endif
+#define PRIuoff_t PRI_off_t("u")
+#define PRIxoff_t PRI_off_t("x")
+#define PRI2offs "%" PRIuoff_t " (%#" PRIxoff_t ")"
+#define PRI2offsNL PRI2offs "
"
+
+#undef TRUE
+#undef FALSE
+
+#define TRUE (1)
+#define FALSE (0)
+
+#ifdef CRASH_X86
+#define NR_CPUS (32)
+#endif
+#ifdef CRASH_X86_64
+#define NR_CPUS (32)
+#endif
+#ifdef CRASH_ALPHA
+#define NR_CPUS (64)
+#endif
+#ifdef CRASH_PPC
+#define NR_CPUS (32)
+#endif
+#ifdef CRASH_IA64
+#define NR_CPUS (512)
+#endif
+#ifdef CRASH_PPC64
+#define NR_CPUS (128)
+#endif
+#ifdef CRASH_S390
+#define NR_CPUS (64)
+#endif
+#ifdef CRASH_S390X
+#define NR_CPUS (64)
+#endif
+#ifdef CRASH_ARM
+#define NR_CPUS (32)
+#endif
+
+struct new_utsname {
+ char sysname[65];
+ char nodename[65];
+ char release[65];
+ char version[65];
+ char machine[65];
+ char domainname[65];
+};
+
+typedef int (*lkcd_helper)(int fd);
+
+extern int silent;
+extern int verbose;
+extern int print_header;
+extern int print_asmheader;
+extern int print_pages;
+extern int check_pages;
+extern int only_header;
+extern int endless;
+extern off_t dump_header_offset;
+extern char *build_version;
+
+uint16_t bswap_u16(uint16_t v);
+uint32_t bswap_u32(uint32_t v);
+uint64_t bswap_u64(uint64_t v);
+uint16_t dummy_u16(uint16_t v);
+uint32_t dummy_u32(uint32_t v);
+uint64_t dummy_u64(uint64_t v);
+
+typedef uint16_t (*target_conv_u16)(uint16_t v);
+typedef uint32_t (*target_conv_u32)(uint32_t v);
+typedef uint64_t (*target_conv_u64)(uint64_t v);
+extern target_conv_u16 from_target_u16;
+extern target_conv_u32 from_target_u32;
+extern target_conv_u64 from_target_u64;
+
+void init_target_endianess(int swap);
+
+int field(const char *str);
+int corrupted(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+int incomplete(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+int complete();
+
+void arch_print_pt_regs(struct target_pt_regs *regs);
+
+int lkcd_dump_check_header_v1(int fd);
+int lkcd_dump_check_asmheader_v1(int fd);
+int lkcd_dump_check_pages_v1(int fd);
+int lkcd_dump_check_end_page_v1(int fd);
+
+int lkcd_dump_check_header_v3(int fd);
+int lkcd_dump_check_asmheader_v3(int fd);
+int lkcd_dump_check_pages_v3(int fd);
+int lkcd_dump_check_end_page_v3(int fd);
+
+int lkcd_dump_check_header_v5(int fd);
+int lkcd_dump_check_asmheader_v5(int fd);
+int lkcd_dump_check_pages_v5(int fd);
+int lkcd_dump_check_end_page_v5(int fd);
+
+int lkcd_dump_check_header_v8(int fd);
+int lkcd_dump_check_asmheader_v8(int fd);
+int lkcd_dump_check_pages_v8(int fd);
+int lkcd_dump_check_end_page_v8(int fd);
+
diff -urpN crash-3.10-11.orig/check_tools.c crash-3.10-11.new/check_tools.c
--- crash-3.10-11.orig/check_tools.c 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/check_tools.c 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,125 @@
+/* check_tools.c - core analysis suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "check_defs.h"
+
+target_conv_u16 from_target_u16 = NULL;
+target_conv_u32 from_target_u32 = NULL;
+target_conv_u64 from_target_u64 = NULL;
+
+uint16_t bswap_u16(uint16_t v)
+{
+ return swap_target_u16(v);
+}
+
+uint16_t dummy_u16(uint16_t v)
+{
+ return v;
+}
+
+uint32_t bswap_u32(uint32_t v)
+{
+ return swap_target_u32(v);
+}
+
+uint32_t dummy_u32(uint32_t v)
+{
+ return v;
+}
+
+uint64_t bswap_u64(uint64_t v)
+{
+ return swap_target_u64(v);
+}
+
+uint64_t dummy_u64(uint64_t v)
+{
+ return v;
+}
+
+void init_target_endianess(int swap)
+{
+ if (swap) {
+ from_target_u16 = bswap_u16;
+ from_target_u32 = bswap_u32;
+ from_target_u64 = bswap_u64;
+ } else {
+ from_target_u16 = dummy_u16;
+ from_target_u32 = dummy_u32;
+ from_target_u64 = dummy_u64;
+ }
+}
+
+int field(const char *str)
+{
+ int r;
+
+ r = printf("%20s: ", str);
+
+ return r;
+}
+
+int corrupted(const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+ if (silent > 1)
+ return 0;
+
+ field("Result");
+ printf("Vmcore file is corrupted
");
+ field("Details");
+ va_start(args, fmt);
+ r = vprintf(fmt, args);
+ va_end(args);
+ printf("

");
+
+ return r;
+}
+
+int incomplete(const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+ if (silent > 1)
+ return 0;
+
+ field("Result");
+ printf("Vmcore file is incomplete
");
+ field("Details");
+ va_start(args, fmt);
+ r = vprintf(fmt, args);
+ va_end(args);
+ printf("

");
+
+ return r;
+}
+
+int complete()
+{
+ int r;
+
+ if (silent > 1)
+ return 0;
+
+ field("Result");
+ r = printf("Vmcore file is complete

");
+
+ return r;
+}
+
diff -urpN crash-3.10-11.orig/lkcd_dump_v5.h crash-3.10-11.new/lkcd_dump_v5.h
--- crash-3.10-11.orig/lkcd_dump_v5.h 2010-02-12 20:12:36.000000000 +0300
+++ crash-3.10-11.new/lkcd_dump_v5.h 2010-03-03 22:07:19.000000000 +0300
@@ -241,7 +241,7 @@ typedef struct __dump_header_asm {
uint32_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
-} dump_header_asm_t __attribute__((packed));
+} __attribute__((packed)) dump_header_asm_t;

/* Take care of target/host endians */
static void inline swap_asm_header(dump_header_asm_t *dh_asm) {
diff -urpN crash-3.10-11.orig/lkcd_dump_v8.h crash-3.10-11.new/lkcd_dump_v8.h
--- crash-3.10-11.orig/lkcd_dump_v8.h 2010-02-12 20:12:36.000000000 +0300
+++ crash-3.10-11.new/lkcd_dump_v8.h 2010-03-10 20:45:19.000000000 +0300
@@ -323,7 +323,7 @@ typedef struct __dump_header_asm {
uint32_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
-} dump_header_asm_t __attribute__((packed));
+} __attribute__((packed)) dump_header_asm_t;

/* Take care of target/host endians */
static void inline swap_asm_header(dump_header_asm_t *dh_asm) {
@@ -345,12 +345,15 @@ static void inline swap_asm_header(dump_
reg = (uint32_t *)dh_asm->dha_smp_regs[cpu].dha_ARM_regs.uregs;
for(i=0; i<len; i++)
reg[i]=from_target_u32(reg[i]);
+ dh_asm->dha_smp_regs[cpu].dha_ARM_spsr = from_target_u32(
+ dh_asm->dha_smp_regs[cpu].dha_ARM_spsr);
}
}
/*end of CRASH_ARM*/
#elif defined (CRASH_PPC)

-#define DUMP_MAX_NUM_CPUS 1
+#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */
+#define DUMP_MAX_NUM_CPUS NR_CPUS

typedef struct __dump_header_asm {

@@ -379,7 +382,7 @@ typedef struct __dump_header_asm {
uint32_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
-} dump_header_asm_t __attribute__((packed));
+} __attribute__((packed)) dump_header_asm_t;

/* Take care of target/host endians */
static void inline swap_asm_header(dump_header_asm_t *dh_asm) {
@@ -407,7 +410,8 @@ static void inline swap_asm_header(dump_

#elif defined (CRASH_X86)

-#define DUMP_MAX_NUM_CPUS 32
+#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */
+#define DUMP_MAX_NUM_CPUS NR_CPUS

typedef struct __dump_header_asm {
/* the dump magic number -- unique to verify dump is valid */
@@ -435,7 +439,7 @@ typedef struct __dump_header_asm {
uint32_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack[DUMP_MAX_NUM_CPUS];
uint32_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
-} dump_header_asm_t __attribute__((packed));
+} __attribute__((packed)) dump_header_asm_t;

/* Take care of target/host endians */
static void inline swap_asm_header(dump_header_asm_t *dh_asm) {
@@ -464,7 +468,8 @@ static void inline swap_asm_header(dump_

#elif defined(CRASH_PPC64)

-#define DUMP_MAX_NUM_CPUS 2
+#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */
+#define DUMP_MAX_NUM_CPUS NR_CPUS

typedef struct __dump_header_asm {

@@ -487,7 +492,7 @@ typedef struct __dump_header_asm {
uint64_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
uint64_t dha_stack[DUMP_MAX_NUM_CPUS];
uint64_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
-} dump_header_asm_t __attribute__((packed));
+} __attribute__((packed)) dump_header_asm_t;

static inline void swap_asm_header(dump_header_asm_t *dh_asm) {
int i, cpu, len;
@@ -507,6 +512,123 @@ static inline void swap_asm_header(dump_
reg[i] = from_target_u64(reg[i]);
}

+#elif defined (CRASH_X86_64)
+
+#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */
+#define DUMP_MAX_NUM_CPUS NR_CPUS
+
+typedef struct __dump_header_asm {
+
+ /* the dump magic number -- unique to verify dump is valid */
+ uint64_t dha_magic_number;
+
+ /* the version number of this dump */
+ uint32_t dha_version;
+
+ /* the size of this header (in case we can't read it) */
+ uint32_t dha_header_size;
+
+ /* the dump registers */
+ struct target_pt_regs dha_regs;
+
+ /* smp specific */
+ uint32_t dha_smp_num_cpus;
+ int dha_dumping_cpu;
+ struct target_pt_regs dha_smp_regs[DUMP_MAX_NUM_CPUS];
+ uint64_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
+ uint64_t dha_stack[DUMP_MAX_NUM_CPUS];
+ uint64_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
+} __attribute__((packed)) dump_header_asm_t;
+
+/* Take care of target/host endians */
+static void inline swap_asm_header(dump_header_asm_t *dh_asm) {
+ int i, cpu, len;
+ uint64_t *reg;
+
+ /* Convert only fileds we're carry about */
+ dh_asm->dha_magic_number = from_target_u64(dh_asm->dha_magic_number);
+ dh_asm->dha_version = from_target_u32(dh_asm->dha_version);
+ dh_asm->dha_header_size = from_target_u32(dh_asm->dha_header_size);
+
+ dh_asm->dha_smp_num_cpus = from_target_u32(dh_asm->dha_smp_num_cpus);
+ if (dh_asm->dha_smp_num_cpus > DUMP_MAX_NUM_CPUS)
+ dh_asm->dha_smp_num_cpus = DUMP_MAX_NUM_CPUS;
+ dh_asm->dha_dumping_cpu = from_target_u32(dh_asm->dha_dumping_cpu);
+ len = sizeof(struct target_pt_regs) / sizeof(target_ulong);
+ for (cpu=0; cpu<dh_asm->dha_smp_num_cpus; cpu++) {
+ reg = (uint64_t *) (&dh_asm->dha_smp_regs[cpu]);
+ for(i=0; i<len; i++)
+ reg[i]=from_target_u64(reg[i]);
+ }
+}
+
+#elif defined (CRASH_IA64)
+
+#define DUMP_ASM_MAGIC_NUMBER 0xdeaddeadULL /* magic number */
+#define DUMP_MAX_NUM_CPUS NR_CPUS
+
+typedef struct __dump_header_asm {
+
+ /* the dump magic number -- unique to verify dump is valid */
+ uint64_t dha_magic_number;
+
+ /* the version number of this dump */
+ uint32_t dha_version;
+
+ /* the size of this header (in case we can't read it) */
+ uint32_t dha_header_size;
+
+ /* pointer to pt_regs, (OLD: (struct pt_regs *, NEW: (uint64_t)) */
+ uint64_t dha_pt_regs;
+
+ /* the dump registers */
+ struct target_pt_regs dha_regs;
+
+ /* the rnat register saved after flushrs */
+ uint64_t dha_rnat;
+
+ /* the pfs register saved after flushrs */
+ uint64_t dha_pfs;
+
+ /* the bspstore register saved after flushrs */
+ uint64_t dha_bspstore;
+
+ /* smp specific */
+ uint32_t dha_smp_num_cpus;
+ uint32_t dha_dumping_cpu;
+ struct target_pt_regs dha_smp_regs[DUMP_MAX_NUM_CPUS];
+ uint64_t dha_smp_current_task[DUMP_MAX_NUM_CPUS];
+ uint64_t dha_stack[DUMP_MAX_NUM_CPUS];
+ uint64_t dha_stack_ptr[DUMP_MAX_NUM_CPUS];
+
+} __attribute__((packed)) dump_header_asm_t;
+
+/* Take care of target/host endians */
+static void inline swap_asm_header(dump_header_asm_t *dh_asm) {
+ int i, cpu, len;
+ uint64_t *reg;
+
+ /* Convert only fileds we're carry about */
+ dh_asm->dha_magic_number = from_target_u64(dh_asm->dha_magic_number);
+ dh_asm->dha_version = from_target_u32(dh_asm->dha_version);
+ dh_asm->dha_header_size = from_target_u32(dh_asm->dha_header_size);
+ dh_asm->dha_pt_regs = from_target_u64(dh_asm->dha_pt_regs);
+ dh_asm->dha_rnat = from_target_u64(dh_asm->dha_rnat);
+ dh_asm->dha_pfs = from_target_u64(dh_asm->dha_pfs);
+ dh_asm->dha_bspstore = from_target_u64(dh_asm->dha_bspstore);
+
+ dh_asm->dha_smp_num_cpus = from_target_u32(dh_asm->dha_smp_num_cpus);
+ if (dh_asm->dha_smp_num_cpus > DUMP_MAX_NUM_CPUS)
+ dh_asm->dha_smp_num_cpus = DUMP_MAX_NUM_CPUS;
+ dh_asm->dha_dumping_cpu = from_target_u32(dh_asm->dha_dumping_cpu);
+ len = sizeof(struct target_pt_regs) / sizeof(target_ulong);
+ for (cpu=0; cpu<dh_asm->dha_smp_num_cpus; cpu++) {
+ reg = (uint64_t *) (&dh_asm->dha_smp_regs[cpu]);
+ for(i=0; i<len; i++)
+ reg[i]=from_target_u64(reg[i]);
+ }
+}
+
#else

/*
@@ -517,7 +639,7 @@ typedef struct __dump_header_asm {
uint64_t dha_magic_number;
uint32_t dha_dumping_cpu;
uint32_t dha_smp_regs[1];
-} dump_header_asm_t __attribute__((packed));
+} __attribute__((packed)) dump_header_asm_t;

#define swap_asm_header(x)

diff -urpN crash-3.10-11.orig/lkcd_v1_check.c crash-3.10-11.new/lkcd_v1_check.c
--- crash-3.10-11.orig/lkcd_v1_check.c 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/lkcd_v1_check.c 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,404 @@
+/* lkcd_v1_check.c - core analysis suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "check_defs.h"
+#define CONFIG_VMDUMP
+#include "lkcd_vmdump_v1.h"
+
+static dump_header_t dump_header_v1 = { 0 };
+static dump_page_t dump_page = { 0 };
+static int arch_print_asmheader_v1(dump_header_t *dh);
+
+int lkcd_dump_check_header_v1(int fd)
+{
+ int others;
+ time_t sec;
+ uint16_t host, target;
+ char buf[64];
+ dump_header_t *dh;
+ dh = &dump_header_v1;
+
+ if (lseek(fd, dump_header_offset, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the dump header at " PRI2offs,
+ dump_header_offset, dump_header_offset);
+ return FALSE;
+ }
+
+ if (read(fd, dh, sizeof(dump_header_t)) != sizeof(dump_header_t)) {
+ incomplete("Could not read dump header");
+ return FALSE;
+ }
+
+ /* Swap everything from the target endian to mine.*/
+ dh->dh_magic_number = from_target_u64(dh->dh_magic_number);
+ dh->dh_version = from_target_u32(dh->dh_version);
+ dh->dh_header_size = from_target_u32(dh->dh_header_size);
+ dh->dh_dump_level = from_target_u32(dh->dh_dump_level);
+ dh->dh_page_size = from_target_u32(dh->dh_page_size);
+ dh->dh_memory_size = from_target_u64(dh->dh_memory_size);
+ dh->dh_memory_start = from_target_u64(dh->dh_memory_start);
+ dh->dh_memory_end = from_target_u64(dh->dh_memory_end);
+ dh->dh_num_pages = from_target_u32(dh->dh_num_pages);
+ dh->dh_time.tv_sec = from_target_u64(dh->dh_time.tv_sec);
+ dh->dh_time.tv_usec = from_target_u64(dh->dh_time.tv_usec);
+ *(uint32_t *)(&dh->dh_current_task) =
+ from_target_u32(*(uint32_t *)(&dh->dh_current_task));
+
+ if (dh->dh_header_size != sizeof(dump_header_t)) {
+ corrupted("Header size paradox: dh_header_size = %" PRIu32
+ ", sizeof(dump_header_t) = %zu",
+ dh->dh_header_size, sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ if (silent || !print_header)
+ return TRUE;
+
+ if (dump_header_offset != 0 || verbose) {
+ field("Dump header offset");
+ printf(PRI2offsNL, dump_header_offset, dump_header_offset);
+ }
+ if (verbose) {
+ field("Magic number");
+ printf("%#" PRIx64 " ", dh->dh_magic_number);
+ if (dh->dh_magic_number == DUMP_MAGIC_NUMBER)
+ printf("(DUMP_MAGIC_NUMBER)
");
+ else
+ printf("(?)
");
+
+ field("Version");
+ printf("%#" PRIx32 " (", dh->dh_version);
+ others = 0;
+ switch (dh->dh_version & LKCD_DUMP_VERSION_NUMBER_MASK) {
+ case LKCD_DUMP_V1:
+ printf("%sLKCD_DUMP_V1", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V2:
+ printf("%sLKCD_DUMP_V2", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V3:
+ printf("%sLKCD_DUMP_V3", others++ ? "|" : "");
+ break;
+ }
+ if (dh->dh_version & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ if (dh->dh_version & LKCD_DUMP_MCLX_V1)
+ printf("%sLKCD_DUMP_MCLX_V1", others++ ? "|" : "");
+ printf(")
");
+
+ field("Header size");
+ printf("%" PRIu32 "
", dh->dh_header_size);
+ }
+
+ field("Dump level");
+ printf("%#" PRIx32 " (", dh->dh_dump_level);
+ others = 0;
+ if (dh->dh_dump_level & DUMP_HEADER)
+ printf("%sDUMP_HEADER", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_KERN)
+ printf("%sDUMP_KERN", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_USED)
+ printf("%sDUMP_USED", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_ALL)
+ printf("%sDUMP_ALL", others++ ? "|" : "");
+ printf(")
");
+
+ field("Dump compression");
+ printf("DUMP_COMPRESS_RLE
");
+
+ if (verbose) {
+ field("Page size");
+ printf("%" PRIu32 "
", dh->dh_page_size);
+
+ field("Memory size");
+ printf("%#" PRIx64 "
", dh->dh_memory_size);
+
+ field("Memory start");
+ printf("%#" PRIx64 "
", dh->dh_memory_start);
+
+ field("Memory end");
+ printf("%#" PRIx64 "
", dh->dh_memory_end);
+
+ field("Num pages");
+ printf("%" PRIu32 "
", dh->dh_num_pages);
+
+ field("Current task");
+ printf("%#llx
", (unsigned long long) dh->dh_current_task);
+ }
+
+ field("Crash time");
+ sec = dh->dh_time.tv_sec;
+ strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
+ localtime(&sec));
+ printf("%s
", buf);
+
+ field("Kernel name");
+ printf("%s
", dh->dh_utsname.sysname);
+ field("Node name");
+ printf("%s
", dh->dh_utsname.nodename);
+ field("Domain name");
+ printf("%s
", dh->dh_utsname.domainname);
+ field("Kernel release");
+ printf("%s
", dh->dh_utsname.release);
+ field("Kernel version");
+ printf("%s
", dh->dh_utsname.version);
+ field("Machine name");
+ printf("%s
", dh->dh_utsname.machine);
+
+ field("Machine type");
+ host = 1;
+ target = from_target_u16(host);
+ if ((*(char *) &host) && host == target)
+ printf("little endian
");
+ else
+ printf("big endian
");
+
+ field("Panic message");
+ printf("%s
", dh->dh_panic_string);
+
+ return TRUE;
+}
+
+static void inline swap_asm_header(dump_header_t *dh) {
+ int i, len;
+ target_ulong *reg;
+
+ /* Convert only fileds we're carry about */
+ dh->dh_esp = from_target_u32(dh->dh_esp);
+ dh->dh_eip = from_target_u32(dh->dh_eip);
+
+ len = sizeof(struct target_pt_regs) / sizeof(target_ulong);
+ reg = (target_ulong *) (&dh->dh_regs);
+ if (sizeof(target_ulong) == 64)
+ for(i=0; i<len; i++)
+ reg[i]=from_target_u64(reg[i]);
+ else
+ for(i=0; i<len; i++)
+ reg[i]=from_target_u32(reg[i]);
+}
+
+int lkcd_dump_check_asmheader_v1(int fd)
+{
+ dump_header_t *dh;
+ dh = &dump_header_v1;
+
+ swap_asm_header(dh);
+
+ if (silent || !print_asmheader)
+ return TRUE;
+
+ return arch_print_asmheader_v1(dh);
+}
+
+int lkcd_dump_check_pages_v1(int fd)
+{
+ int others;
+ unsigned long pgcnt = 0, cpgs = 0;
+ ssize_t i, rd;
+ off_t offs;
+ char buf[1024];
+ dump_page_t *dp;
+ dump_header_t *dh;
+ dh = &dump_header_v1;
+ dp = &dump_page;
+
+ offs = dump_header_offset;
+ if (dh->dh_page_size < LKCD_OFFSET_TO_FIRST_PAGE)
+ offs += LKCD_OFFSET_TO_FIRST_PAGE;
+ else
+ offs += LKCD_OFFSET_TO_FIRST_BIG_PAGE;
+ if (lseek(fd, offs, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the page No %lu (%#lx) at "
+ "%#" PRIxoff_t, pgcnt, pgcnt, offs);
+ return FALSE;
+ }
+
+ if (!silent)
+ printf("
");
+ do {
+ if (read(fd, dp, sizeof(dump_page_t)) != sizeof(dump_page_t)) {
+ incomplete("Could not read page header for page No "
+ "%lu (%#lx)", pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ dp->dp_address = from_target_u64(dp->dp_address);
+ dp->dp_size = from_target_u32(dp->dp_size);
+ dp->dp_flags = from_target_u32(dp->dp_flags);
+
+ if (dp->dp_flags & ~(DUMP_COMPRESSED|DUMP_RAW|
+ DUMP_END|LKCD_DUMP_MCLX_V0)) {
+ corrupted("Unknown page flag in the dump: %#" PRIx32
+ ", page No %lu (%#lx)",
+ dp->dp_flags, pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ if (dp->dp_size > dh->dh_page_size) {
+ corrupted("Page size paradox: dp_size = %#" PRIx32
+ ", dh_page_size = %#" PRIx32
+ ", page No %lu (%#lx)", dp->dp_flags,
+ dh->dh_page_size, pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ if ((print_pages || (verbose && !pgcnt)) && !silent) {
+ field("Page No");
+ printf("%lu (%#lx)
", pgcnt, pgcnt);
+
+ field("Page offset");
+ printf(PRI2offsNL, offs, offs);
+
+ field("Page address");
+ printf("%#" PRIx64 "
", dp->dp_address);
+
+ field("Page size");
+ printf("%" PRIu32 "
", dp->dp_size);
+
+ field("Page flags");
+ printf("%#" PRIx32 " (", dp->dp_flags);
+ others = 0;
+ if (dp->dp_flags & DUMP_COMPRESSED) {
+ printf("%sDUMP_COMPRESSED", others++ ? "|" : "");
+ cpgs++;
+ }
+ if (dp->dp_flags & DUMP_RAW)
+ printf("%sDUMP_RAW", others++ ? "|" : "");
+ if (dp->dp_flags & DUMP_END)
+ printf("%sDUMP_END", others++ ? "|" : "");
+ if (dp->dp_flags & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ printf(")
");
+ }
+
+ if (dp->dp_flags & DUMP_END)
+ break;
+
+ pgcnt++;
+ if (lseek(fd, dp->dp_size, SEEK_CUR) == ((off_t)-1)) {
+ incomplete("Could not jump to the page No %lu (%#lx)",
+ pgcnt, pgcnt);
+ return FALSE;
+ }
+ offs += dp->dp_size + sizeof(dump_page_t);
+ } while (1);
+
+ if (pgcnt > dh->dh_num_pages) {
+ corrupted("Page count paradox: pgcnt = %lu, dh_num_pages = "
+ "%" PRIu32, pgcnt, dh->dh_num_pages);
+ return FALSE;
+ }
+
+ if (pgcnt < dh->dh_num_pages) {
+ incomplete("%lu pages lost",
+ (unsigned long) dh->dh_num_pages - pgcnt);
+ return FALSE;
+ }
+
+ if (!silent) {
+ field("Total pages found");
+ printf("%lu (%#lx)
", pgcnt, pgcnt);
+ field("Compressed pages");
+ printf("%lu
", cpgs);
+ field("End-page offset");
+ printf(PRI2offsNL, offs, offs);
+ }
+
+ offs += sizeof(dump_page_t);
+ do {
+ rd = read(fd, buf, sizeof(buf));
+
+ for (i = 0; i < rd; i++)
+ if (buf[i] != 'm') {
+ offs += i;
+ if (endless && !silent) {
+ field("Dump end");
+ printf(PRI2offsNL, offs, offs);
+
+ return TRUE;
+ }
+ corrupted("Found wrong symbol inside end page "
+ "at %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+
+ offs += rd;
+ } while (rd > 0);
+
+ return TRUE;
+}
+
+int lkcd_dump_check_end_page_v1(int fd)
+{
+ dump_page_t *dp;
+ char buf[1024];
+ ssize_t i, len = 0;
+ off_t offs;
+
+ offs = lseek(fd, 0, SEEK_END);
+ while (offs > 0) {
+ offs -= sizeof(buf);
+ if (lseek(fd, offs, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the offset %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
+ incomplete("Could not read last page at %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+ for (i = sizeof(buf); i--; )
+ if (buf[i] != 'm') {
+ i++;
+ if (i < sizeof(dump_page_t)) {
+ offs += sizeof(buf) / 2;
+ len -= sizeof(buf) / 2;
+ break;
+ }
+ i -= sizeof(dump_page_t);
+ goto found;
+ }
+ len += sizeof(buf);
+ }
+found:
+ dp = (dump_page_t *)(buf + i);
+ offs += i;
+ if (from_target_u32(dp->dp_flags) == DUMP_END)
+ if(len) {
+ if (!silent) {
+ printf("
");
+ field("End-page offset");
+ printf(PRI2offsNL, offs, offs);
+ }
+
+ return TRUE;
+ }
+
+ if(!len)
+ incomplete("Could not find final marker and page header for it.");
+ else
+ corrupted("Invalid page header before final marker.");
+ return FALSE;
+}
+
+static int arch_print_asmheader_v1(dump_header_t *dh)
+{
+ if (verbose) {
+ printf("
");
+ arch_print_pt_regs(&dh->dh_regs);
+ }
+ return TRUE;
+}
+
diff -urpN crash-3.10-11.orig/lkcd_v3_check.c crash-3.10-11.new/lkcd_v3_check.c
--- crash-3.10-11.orig/lkcd_v3_check.c 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/lkcd_v3_check.c 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,435 @@
+/* lkcd_v3_check.c - core analysis suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "check_defs.h"
+#define CONFIG_VMDUMP
+#include "lkcd_vmdump_v2_v3.h"
+
+static dump_header_t dump_header_v3 = { 0 };
+static dump_header_asm_t dump_header_asm_v3 = { 0 };
+static dump_page_t dump_page = { 0 };
+static int arch_print_asmheader_v3(dump_header_asm_t *dha);
+
+int lkcd_dump_check_header_v3(int fd)
+{
+ int others;
+ time_t sec;
+ uint16_t host, target;
+ char buf[64];
+ dump_header_t *dh;
+ dh = &dump_header_v3;
+
+ if (lseek(fd, dump_header_offset, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the dump header at " PRI2offs,
+ dump_header_offset, dump_header_offset);
+ return FALSE;
+ }
+
+ if (read(fd, dh, sizeof(dump_header_t)) != sizeof(dump_header_t)) {
+ incomplete("Could not read dump header");
+ return FALSE;
+ }
+
+ /* Swap everything from the target endian to mine.*/
+ dh->dh_magic_number = from_target_u64(dh->dh_magic_number);
+ dh->dh_version = from_target_u32(dh->dh_version);
+ dh->dh_header_size = from_target_u32(dh->dh_header_size);
+ dh->dh_dump_level = from_target_u32(dh->dh_dump_level);
+ dh->dh_page_size = from_target_u32(dh->dh_page_size);
+ dh->dh_memory_size = from_target_u64(dh->dh_memory_size);
+ dh->dh_memory_start = from_target_u64(dh->dh_memory_start);
+ dh->dh_memory_end = from_target_u64(dh->dh_memory_end);
+ dh->dh_num_pages = from_target_u32(dh->dh_num_pages);
+ dh->dh_time.tv_sec = from_target_u64(dh->dh_time.tv_sec);
+ dh->dh_time.tv_usec = from_target_u64(dh->dh_time.tv_usec);
+ *(uint32_t *)(&dh->dh_current_task) =
+ from_target_u32(*(uint32_t *)(&dh->dh_current_task));
+
+ if (dh->dh_header_size != sizeof(dump_header_t)) {
+ corrupted("Header size paradox: dh_header_size = %" PRIu32
+ ", sizeof(dump_header_t) = %zu",
+ dh->dh_header_size, sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ if (silent || !print_header)
+ return TRUE;
+
+ if (dump_header_offset != 0 || verbose) {
+ field("Dump header offset");
+ printf(PRI2offsNL, dump_header_offset, dump_header_offset);
+ }
+ if (verbose) {
+ field("Magic number");
+ printf("%#" PRIx64 " ", dh->dh_magic_number);
+ if (dh->dh_magic_number == DUMP_MAGIC_NUMBER)
+ printf("(DUMP_MAGIC_NUMBER)
");
+ else
+ printf("(?)
");
+
+ field("Version");
+ printf("%#" PRIx32 " (", dh->dh_version);
+ others = 0;
+ switch (dh->dh_version & LKCD_DUMP_VERSION_NUMBER_MASK) {
+ case LKCD_DUMP_V1:
+ printf("%sLKCD_DUMP_V1", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V2:
+ printf("%sLKCD_DUMP_V2", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V3:
+ printf("%sLKCD_DUMP_V3", others++ ? "|" : "");
+ break;
+ }
+ if (dh->dh_version & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ if (dh->dh_version & LKCD_DUMP_MCLX_V1)
+ printf("%sLKCD_DUMP_MCLX_V1", others++ ? "|" : "");
+ printf(")
");
+
+ field("Header size");
+ printf("%" PRIu32 "
", dh->dh_header_size);
+ }
+
+ field("Dump level");
+ printf("%#" PRIx32 " (", dh->dh_dump_level);
+ others = 0;
+ if (dh->dh_dump_level & DUMP_HEADER)
+ printf("%sDUMP_HEADER", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_KERN)
+ printf("%sDUMP_KERN", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_USED)
+ printf("%sDUMP_USED", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_ALL)
+ printf("%sDUMP_ALL", others++ ? "|" : "");
+ printf(")
");
+
+ field("Dump compression");
+ printf("DUMP_COMPRESS_RLE
");
+
+ if (verbose) {
+ field("Page size");
+ printf("%" PRIu32 "
", dh->dh_page_size);
+
+ field("Memory size");
+ printf("%#" PRIx64 "
", dh->dh_memory_size);
+
+ field("Memory start");
+ printf("%#" PRIx64 "
", dh->dh_memory_start);
+
+ field("Memory end");
+ printf("%#" PRIx64 "
", dh->dh_memory_end);
+
+ field("Num pages");
+ printf("%" PRIu32 "
", dh->dh_num_pages);
+
+ field("Current task");
+ printf("%#llx
", (unsigned long long) dh->dh_current_task);
+ }
+
+ field("Crash time");
+ sec = dh->dh_time.tv_sec;
+ strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
+ localtime(&sec));
+ printf("%s
", buf);
+
+ field("Kernel name");
+ printf("%s
", dh->dh_utsname.sysname);
+ field("Node name");
+ printf("%s
", dh->dh_utsname.nodename);
+ field("Domain name");
+ printf("%s
", dh->dh_utsname.domainname);
+ field("Kernel release");
+ printf("%s
", dh->dh_utsname.release);
+ field("Kernel version");
+ printf("%s
", dh->dh_utsname.version);
+ field("Machine name");
+ printf("%s
", dh->dh_utsname.machine);
+
+ field("Machine type");
+ host = 1;
+ target = from_target_u16(host);
+ if ((*(char *) &host) && host == target)
+ printf("little endian
");
+ else
+ printf("big endian
");
+
+ field("Panic message");
+ printf("%s
", dh->dh_panic_string);
+
+ return TRUE;
+}
+
+static void inline swap_asm_header(dump_header_asm_t *dh_asm)
+{
+ int i, len;
+ target_ulong *reg;
+
+ /* Convert only fileds we're carry about */
+ dh_asm->dha_magic_number = from_target_u64(dh_asm->dha_magic_number);
+ dh_asm->dha_version = from_target_u32(dh_asm->dha_version);
+ dh_asm->dha_header_size = from_target_u32(dh_asm->dha_header_size);
+ dh_asm->dha_esp = from_target_u32(dh_asm->dha_esp);
+ dh_asm->dha_eip = from_target_u32(dh_asm->dha_eip);
+
+ len = sizeof(struct target_pt_regs) / sizeof(target_ulong);
+ reg = (target_ulong *) (&dh_asm->dha_regs);
+ if (sizeof(target_ulong) == 64)
+ for(i=0; i<len; i++)
+ reg[i]=from_target_u64(reg[i]);
+ else
+ for(i=0; i<len; i++)
+ reg[i]=from_target_u32(reg[i]);
+}
+
+int lkcd_dump_check_asmheader_v3(int fd)
+{
+ dump_header_asm_t *dh_asm;
+ dh_asm = &dump_header_asm_v3;
+
+ if (lseek(fd, dump_header_offset + sizeof(dump_header_t), SEEK_SET)
+ == ((off_t)-1)) {
+ incomplete("Could not jump to the asm header at %#" PRIxoff_t,
+ dump_header_offset + sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ if (read(fd, dh_asm, sizeof(dump_header_asm_t)) !=
+ sizeof(dump_header_asm_t)) {
+ incomplete("Could not read asm header at %#" PRIxoff_t,
+ dump_header_offset + sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ swap_asm_header(dh_asm);
+
+ if (silent || !print_asmheader)
+ return TRUE;
+
+ return arch_print_asmheader_v3(dh_asm);
+}
+
+int lkcd_dump_check_pages_v3(int fd)
+{
+ int others;
+ unsigned long pgcnt = 0, cpgs = 0;
+ ssize_t i, rd;
+ off_t offs;
+ char buf[1024];
+ dump_page_t *dp;
+ dump_header_t *dh;
+ dh = &dump_header_v3;
+ dp = &dump_page;
+
+ offs = dump_header_offset;
+ if (dh->dh_page_size < LKCD_OFFSET_TO_FIRST_PAGE)
+ offs += LKCD_OFFSET_TO_FIRST_PAGE;
+ else
+ offs += LKCD_OFFSET_TO_FIRST_BIG_PAGE;
+ if (lseek(fd, offs, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the page No %lu (%#lx) at "
+ "%#" PRIxoff_t, pgcnt, pgcnt, offs);
+ return FALSE;
+ }
+
+ if (!silent)
+ printf("
");
+ do {
+ if (read(fd, dp, sizeof(dump_page_t)) != sizeof(dump_page_t)) {
+ incomplete("Could not read page header for page No "
+ "%lu (%#lx)", pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ dp->dp_address = from_target_u64(dp->dp_address);
+ dp->dp_size = from_target_u32(dp->dp_size);
+ dp->dp_flags = from_target_u32(dp->dp_flags);
+
+ if (dp->dp_flags & ~(DUMP_COMPRESSED|DUMP_RAW|
+ DUMP_END|LKCD_DUMP_MCLX_V0)) {
+ corrupted("Unknown page flag in the dump: %#" PRIx32
+ ", page No %lu (%#lx)",
+ dp->dp_flags, pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ if (dp->dp_size > dh->dh_page_size) {
+ corrupted("Page size paradox: dp_size = %#" PRIx32
+ ", dh_page_size = %#" PRIx32
+ ", page No %lu (%#lx)", dp->dp_flags,
+ dh->dh_page_size, pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ if ((print_pages || (verbose && !pgcnt)) && !silent) {
+ field("Page No");
+ printf("%lu (%#lx)
", pgcnt, pgcnt);
+
+ field("Page offset");
+ printf(PRI2offsNL, offs, offs);
+
+ field("Page address");
+ printf("%#" PRIx64 "
", dp->dp_address);
+
+ field("Page size");
+ printf("%" PRIu32 "
", dp->dp_size);
+
+ field("Page flags");
+ printf("%#" PRIx32 " (", dp->dp_flags);
+ others = 0;
+ if (dp->dp_flags & DUMP_COMPRESSED) {
+ printf("%sDUMP_COMPRESSED", others++ ? "|" : "");
+ cpgs++;
+ }
+ if (dp->dp_flags & DUMP_RAW)
+ printf("%sDUMP_RAW", others++ ? "|" : "");
+ if (dp->dp_flags & DUMP_END)
+ printf("%sDUMP_END", others++ ? "|" : "");
+ if (dp->dp_flags & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ printf(")
");
+ }
+
+ if (dp->dp_flags & DUMP_END)
+ break;
+
+ pgcnt++;
+ if (lseek(fd, dp->dp_size, SEEK_CUR) == ((off_t)-1)) {
+ incomplete("Could not jump to the page No %lu (%#lx)",
+ pgcnt, pgcnt);
+ return FALSE;
+ }
+ offs += dp->dp_size + sizeof(dump_page_t);
+ } while (1);
+
+ if (pgcnt > dh->dh_num_pages) {
+ corrupted("Page count paradox: pgcnt = %lu, dh_num_pages = "
+ "%" PRIu32, pgcnt, dh->dh_num_pages);
+ return FALSE;
+ }
+
+ if (pgcnt < dh->dh_num_pages) {
+ incomplete("%lu pages lost",
+ (unsigned long) dh->dh_num_pages - pgcnt);
+ return FALSE;
+ }
+
+ if (!silent) {
+ field("Total pages found");
+ printf("%lu (%#lx)
", pgcnt, pgcnt);
+ field("Compressed pages");
+ printf("%lu
", cpgs);
+ field("End-page offset");
+ printf(PRI2offsNL, offs, offs);
+ }
+
+ offs += sizeof(dump_page_t);
+ do {
+ rd = read(fd, buf, sizeof(buf));
+
+ for (i = 0; i < rd; i++)
+ if (buf[i] != 'm') {
+ offs += i;
+ if (endless && !silent) {
+ field("Dump end");
+ printf(PRI2offsNL, offs, offs);
+
+ return TRUE;
+ }
+ corrupted("Found wrong symbol inside end page "
+ "at %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+
+ offs += rd;
+ } while (rd > 0);
+
+ return TRUE;
+}
+
+int lkcd_dump_check_end_page_v3(int fd)
+{
+ dump_page_t *dp;
+ char buf[1024];
+ ssize_t i, len = 0;
+ off_t offs;
+
+ offs = lseek(fd, 0, SEEK_END);
+ while (offs > 0) {
+ offs -= sizeof(buf);
+ if (lseek(fd, offs, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the offset %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
+ incomplete("Could not read last page at %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+ for (i = sizeof(buf); i--; )
+ if (buf[i] != 'm') {
+ i++;
+ if (i < sizeof(dump_page_t)) {
+ offs += sizeof(buf) / 2;
+ len -= sizeof(buf) / 2;
+ break;
+ }
+ i -= sizeof(dump_page_t);
+ goto found;
+ }
+ len += sizeof(buf);
+ }
+found:
+ dp = (dump_page_t *)(buf + i);
+ offs += i;
+ if (from_target_u32(dp->dp_flags) == DUMP_END)
+ if(len) {
+ if (!silent) {
+ printf("
");
+ field("End-page offset");
+ printf(PRI2offsNL, offs, offs);
+ }
+
+ return TRUE;
+ }
+
+ if(!len)
+ incomplete("Could not find final marker and page header for it.");
+ else
+ corrupted("Invalid page header before final marker.");
+ return FALSE;
+}
+
+static int arch_print_asmheader_v3(dump_header_asm_t *dha)
+{
+ dump_header_t *dh;
+ dh = &dump_header_v3;
+
+ printf("
");
+ field("ASM Magic number");
+ printf("%#" PRIx64 "
", dha->dha_magic_number);
+
+ field("Version");
+ printf("%#" PRIx32 "
", dha->dha_version);
+
+ field("Header size");
+ printf("%" PRIu32 "
", dha->dha_header_size);
+
+ if (verbose) {
+ arch_print_pt_regs(&dha->dha_regs);
+ }
+ return TRUE;
+}
+
diff -urpN crash-3.10-11.orig/lkcd_v5_check.c crash-3.10-11.new/lkcd_v5_check.c
--- crash-3.10-11.orig/lkcd_v5_check.c 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/lkcd_v5_check.c 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,520 @@
+/* lkcd_v5_check.c - core analysis suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "check_defs.h"
+#include "lkcd_dump_v5.h"
+
+#if !defined (CRASH_X86)
+
+typedef struct __dump_header_asm {
+ /* the dump magic number -- unique to verify dump is valid */
+ uint64_t dha_magic_number;
+
+ /* the version number of this dump */
+ uint32_t dha_version;
+
+ /* the size of this header (in case we can't read it) */
+ uint32_t dha_header_size;
+} __attribute__((packed)) dump_header_asm_t;
+
+#define swap_asm_header(dh_asm)
+
+#endif
+
+static dump_header_t dump_header_v5 = { 0 };
+static dump_header_asm_t dump_header_asm_v5 = { 0 };
+static dump_page_t dump_page = { 0 };
+static int arch_print_asmheader_v5(dump_header_asm_t *dha);
+
+int lkcd_dump_check_header_v5(int fd)
+{
+ int others;
+ time_t sec;
+ uint16_t host, target;
+ char buf[64];
+ dump_header_t *dh;
+ dh = &dump_header_v5;
+
+ if (lseek(fd, dump_header_offset, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the dump header at " PRI2offs,
+ dump_header_offset, dump_header_offset);
+ return FALSE;
+ }
+
+ if (read(fd, dh, sizeof(dump_header_t)) != sizeof(dump_header_t)) {
+ incomplete("Could not read dump header");
+ return FALSE;
+ }
+
+ /* Swap everything from the target endian to mine.*/
+ dh->dh_magic_number = from_target_u64(dh->dh_magic_number);
+ dh->dh_version = from_target_u32(dh->dh_version);
+ dh->dh_header_size = from_target_u32(dh->dh_header_size);
+ dh->dh_dump_level = from_target_u32(dh->dh_dump_level);
+ dh->dh_page_size = from_target_u32(dh->dh_page_size);
+ dh->dh_memory_size = from_target_u64(dh->dh_memory_size);
+ dh->dh_memory_start = from_target_u64(dh->dh_memory_start);
+ dh->dh_memory_end = from_target_u64(dh->dh_memory_end);
+ dh->dh_num_pages = from_target_u32(dh->dh_num_pages);
+ dh->dh_time.tv_sec = from_target_u64(dh->dh_time.tv_sec);
+ dh->dh_time.tv_usec = from_target_u64(dh->dh_time.tv_usec);
+ if (sizeof(target_ptr) == 64)
+ dh->dh_current_task = from_target_u64(dh->dh_current_task);
+ else
+ dh->dh_current_task = from_target_u32(dh->dh_current_task);
+ dh->dh_dump_compress = from_target_u32(dh->dh_dump_compress);
+ dh->dh_dump_flags = from_target_u32(dh->dh_dump_flags);
+ dh->dh_dump_device = from_target_u32(dh->dh_dump_device);
+
+ if (dh->dh_header_size != sizeof(dump_header_t)) {
+ corrupted("Header size paradox: dh_header_size = %" PRIu32
+ ", sizeof(dump_header_t) = %zu",
+ dh->dh_header_size, sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ if (silent || !print_header)
+ return TRUE;
+
+ if (dump_header_offset != 0 || verbose) {
+ field("Dump header offset");
+ printf(PRI2offsNL, dump_header_offset, dump_header_offset);
+ }
+ if (verbose) {
+ field("Magic number");
+ printf("%#" PRIx64 " ", dh->dh_magic_number);
+ if (dh->dh_magic_number == DUMP_MAGIC_NUMBER)
+ printf("(DUMP_MAGIC_NUMBER)
");
+ else if (dh->dh_magic_number == DUMP_MAGIC_LIVE)
+ printf("(DUMP_MAGIC_LIVE)
");
+ else
+ printf("(?)
");
+
+ field("Version");
+ printf("%#" PRIx32 " (", dh->dh_version);
+ others = 0;
+ switch (dh->dh_version & LKCD_DUMP_VERSION_NUMBER_MASK) {
+ case LKCD_DUMP_V1:
+ printf("%sLKCD_DUMP_V1", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V2:
+ printf("%sLKCD_DUMP_V2", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V3:
+ printf("%sLKCD_DUMP_V3", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V5:
+ printf("%sLKCD_DUMP_V5", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V6:
+ printf("%sLKCD_DUMP_V6", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V7:
+ printf("%sLKCD_DUMP_V7", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V8:
+ printf("%sLKCD_DUMP_V8", others++ ? "|" : "");
+ break;
+ }
+ if (dh->dh_version & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ if (dh->dh_version & LKCD_DUMP_MCLX_V1)
+ printf("%sLKCD_DUMP_MCLX_V1", others++ ? "|" : "");
+ printf(")
");
+
+ field("Header size");
+ printf("%" PRIu32 "
", dh->dh_header_size);
+ }
+
+ field("Dump level");
+ printf("%#" PRIx32 " (", dh->dh_dump_level);
+ others = 0;
+ if (dh->dh_dump_level & DUMP_LEVEL_HEADER)
+ printf("%sDUMP_LEVEL_HEADER", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_LEVEL_KERN)
+ printf("%sDUMP_LEVEL_KERN", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_LEVEL_USED)
+ printf("%sDUMP_LEVEL_USED", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_LEVEL_ALL)
+ printf("%sDUMP_LEVEL_ALL", others++ ? "|" : "");
+ printf(")
");
+
+ field("Dump compression");
+ printf("%#" PRIx32 " (", dh->dh_dump_compress);
+ others = 0;
+ if (dh->dh_dump_compress == DUMP_COMPRESS_NONE)
+ printf("%sDUMP_COMPRESS_NONE", others++ ? "|" : "");
+ if (dh->dh_dump_compress & DUMP_COMPRESS_RLE)
+ printf("%sDUMP_COMPRESS_RLE", others++ ? "|" : "");
+ if (dh->dh_dump_compress & DUMP_COMPRESS_GZIP)
+ printf("%sDUMP_COMPRESS_GZIP", others++ ? "|" : "");
+ printf(")
");
+
+ if (verbose) {
+ field("Dump flags");
+ others = 0;
+ printf("%#" PRIx32 " (", dh->dh_dump_flags);
+ if (dh->dh_dump_flags & DUMP_FLAGS_NONDISRUPT)
+ printf("%sDUMP_FLAGS_NONDISRUPT", others++ ? "|" : "");
+ printf(")
");
+
+ field("Dump device");
+ printf("%" PRIu32 "
", dh->dh_dump_device);
+
+ field("Page size");
+ printf("%" PRIu32 "
", dh->dh_page_size);
+
+ field("Memory size");
+ printf("%#" PRIx64 "
", dh->dh_memory_size);
+
+ field("Memory start");
+ printf("%#" PRIx64 "
", dh->dh_memory_start);
+
+ field("Memory end");
+ printf("%#" PRIx64 "
", dh->dh_memory_end);
+
+ field("Num pages");
+ printf("%" PRIu32 "
", dh->dh_num_pages);
+
+ field("Current task");
+ printf("%#llx
", (unsigned long long) dh->dh_current_task);
+ }
+
+ field("Crash time");
+ sec = dh->dh_time.tv_sec;
+ strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
+ localtime(&sec));
+ printf("%s
", buf);
+
+ field("Kernel name");
+ printf("%s
", dh->dh_utsname_sysname);
+ field("Node name");
+ printf("%s
", dh->dh_utsname_nodename);
+ field("Domain name");
+ printf("%s
", dh->dh_utsname_domainname);
+ field("Kernel release");
+ printf("%s
", dh->dh_utsname_release);
+ field("Kernel version");
+ printf("%s
", dh->dh_utsname_version);
+ field("Machine name");
+ printf("%s
", dh->dh_utsname_machine);
+
+ field("Machine type");
+ host = 1;
+ target = from_target_u16(host);
+ if ((*(char *) &host) && host == target)
+ printf("little endian
");
+ else
+ printf("big endian
");
+
+ field("Panic message");
+ printf("%s
", dh->dh_panic_string);
+
+ return TRUE;
+}
+
+int lkcd_dump_check_asmheader_v5(int fd)
+{
+ dump_header_asm_t *dh_asm;
+ dh_asm = &dump_header_asm_v5;
+
+ if (lseek(fd, dump_header_offset + sizeof(dump_header_t), SEEK_SET)
+ == ((off_t)-1)) {
+ incomplete("Could not jump to the asm header at %#" PRIxoff_t,
+ dump_header_offset + sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ if (read(fd, dh_asm, sizeof(dump_header_asm_t)) !=
+ sizeof(dump_header_asm_t)) {
+ incomplete("Could not read asm header at %#" PRIxoff_t,
+ dump_header_offset + sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ swap_asm_header(dh_asm);
+
+ if (silent || !print_asmheader)
+ return TRUE;
+
+ return arch_print_asmheader_v5(dh_asm);
+}
+
+int lkcd_dump_check_pages_v5(int fd)
+{
+ int others;
+ unsigned long pgcnt = 0, cpgs = 0;
+ ssize_t i, rd;
+ off_t offs;
+ char buf[1024];
+ dump_page_t *dp;
+ dump_header_t *dh;
+ dh = &dump_header_v5;
+ dp = &dump_page;
+
+ offs = dump_header_offset;
+ if (dh->dh_page_size < LKCD_OFFSET_TO_FIRST_PAGE)
+ offs += LKCD_OFFSET_TO_FIRST_PAGE;
+ else
+ offs += LKCD_OFFSET_TO_FIRST_BIG_PAGE;
+ if (lseek(fd, offs, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the page No %lu (%#lx) at "
+ "%#" PRIxoff_t, pgcnt, pgcnt, offs);
+ return FALSE;
+ }
+
+ if (!silent)
+ printf("
");
+ do {
+ if (read(fd, dp, sizeof(dump_page_t)) != sizeof(dump_page_t)) {
+ incomplete("Could not read page header for page No "
+ "%lu (%#lx)", pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ dp->dp_address = from_target_u64(dp->dp_address);
+ dp->dp_size = from_target_u32(dp->dp_size);
+ dp->dp_flags = from_target_u32(dp->dp_flags);
+
+ if (dp->dp_flags & ~(DUMP_DH_COMPRESSED|DUMP_DH_RAW|
+ DUMP_DH_END|LKCD_DUMP_MCLX_V0)) {
+ corrupted("Unknown page flag in the dump: %#" PRIx32
+ ", page No %lu (%#lx)",
+ dp->dp_flags, pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ if (dp->dp_size > dh->dh_page_size) {
+ corrupted("Page size paradox: dp_size = %#" PRIx32
+ ", dh_page_size = %#" PRIx32
+ ", page No %lu (%#lx)", dp->dp_flags,
+ dh->dh_page_size, pgcnt, pgcnt);
+ return FALSE;
+ }
+
+ if ((print_pages || (verbose && !pgcnt)) && !silent) {
+ field("Page No");
+ printf("%lu (%#lx)
", pgcnt, pgcnt);
+
+ field("Page offset");
+ printf(PRI2offsNL, offs, offs);
+
+ field("Page address");
+ printf("%#" PRIx64 "
", dp->dp_address);
+
+ field("Page size");
+ printf("%" PRIu32 "
", dp->dp_size);
+
+ field("Page flags");
+ printf("%#" PRIx32 " (", dp->dp_flags);
+ others = 0;
+ if (dp->dp_flags & DUMP_DH_COMPRESSED) {
+ printf("%sDUMP_DH_COMPRESSED", others++ ? "|" : "");
+ cpgs++;
+ }
+ if (dp->dp_flags & DUMP_DH_RAW)
+ printf("%sDUMP_DH_RAW", others++ ? "|" : "");
+ if (dp->dp_flags & DUMP_DH_END)
+ printf("%sDUMP_DH_END", others++ ? "|" : "");
+ if (dp->dp_flags & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ printf(")
");
+ }
+
+ if (dp->dp_flags & DUMP_DH_END)
+ break;
+
+ pgcnt++;
+ if (lseek(fd, dp->dp_size, SEEK_CUR) == ((off_t)-1)) {
+ incomplete("Could not jump to the page No %lu (%#lx)",
+ pgcnt, pgcnt);
+ return FALSE;
+ }
+ offs += dp->dp_size + sizeof(dump_page_t);
+ } while (1);
+
+ if (pgcnt > dh->dh_num_pages) {
+ corrupted("Page count paradox: pgcnt = %lu, dh_num_pages = "
+ "%" PRIu32, pgcnt, dh->dh_num_pages);
+ return FALSE;
+ }
+
+ if (pgcnt < dh->dh_num_pages) {
+ incomplete("%lu pages lost",
+ (unsigned long) dh->dh_num_pages - pgcnt);
+ return FALSE;
+ }
+
+ if (!silent) {
+ field("Total pages found");
+ printf("%lu (%#lx)
", pgcnt, pgcnt);
+ field("Compressed pages");
+ printf("%lu
", cpgs);
+ field("End-page offset");
+ printf(PRI2offsNL, offs, offs);
+ }
+
+ offs += sizeof(dump_page_t);
+ do {
+ rd = read(fd, buf, sizeof(buf));
+
+ for (i = 0; i < rd; i++)
+ if (buf[i] != 'm') {
+ offs += i;
+ if (endless && !silent) {
+ field("Dump end");
+ printf(PRI2offsNL, offs, offs);
+
+ return TRUE;
+ }
+ corrupted("Found wrong symbol inside end page "
+ "at %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+
+ offs += rd;
+ } while (rd > 0);
+
+ return TRUE;
+}
+
+int lkcd_dump_check_end_page_v5(int fd)
+{
+ dump_page_t *dp;
+ char buf[1024];
+ ssize_t i, len = 0;
+ off_t offs;
+
+ offs = lseek(fd, 0, SEEK_END);
+ while (offs > 0) {
+ offs -= sizeof(buf);
+ if (lseek(fd, offs, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the offset %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
+ incomplete("Could not read last page at %#" PRIxoff_t, offs);
+ return FALSE;
+ }
+ for (i = sizeof(buf); i--; )
+ if (buf[i] != 'm') {
+ i++;
+ if (i < sizeof(dump_page_t)) {
+ offs += sizeof(buf) / 2;
+ len -= sizeof(buf) / 2;
+ break;
+ }
+ i -= sizeof(dump_page_t);
+ goto found;
+ }
+ len += sizeof(buf);
+ }
+found:
+ dp = (dump_page_t *)(buf + i);
+ offs += i;
+ if (from_target_u32(dp->dp_flags) == DUMP_DH_END)
+ if(len) {
+ if (!silent) {
+ printf("
");
+ field("End-page offset");
+ printf(PRI2offsNL, offs, offs);
+ }
+
+ return TRUE;
+ }
+
+ if(!len)
+ incomplete("Could not find final marker and page header for it.");
+ else
+ corrupted("Invalid page header before final marker.");
+ return FALSE;
+}
+
+#if defined (CRASH_X86)
+
+static int arch_print_asmheader_v5(dump_header_asm_t *dha)
+{
+ int cpu;
+ struct target_pt_regs *regs;
+ const char *fmt = "%#" PRIx32 "
";
+ dump_header_t *dh;
+ dh = &dump_header_v5;
+
+ if (strcasecmp(dh->dh_utsname_machine, "i686") &&
+ strcasecmp(dh->dh_utsname_machine, "i586") &&
+ strcasecmp(dh->dh_utsname_machine, "i486") &&
+ strcasecmp(dh->dh_utsname_machine, "i386") &&
+ strcasecmp(dh->dh_utsname_machine, "athlon")) {
+ corrupted("Unsupported architecture: %s", dh->dh_utsname_machine);
+ return FALSE;
+ }
+
+ printf("
");
+ if (verbose) {
+ field("ASM Magic number");
+ printf("%#" PRIx64 "
", dha->dha_magic_number);
+
+ field("Version");
+ printf("%#" PRIx32 "
", dha->dha_version);
+
+ field("Header size");
+ printf("%" PRIu32 "
", dha->dha_header_size);
+ }
+
+ field("Num CPUs");
+ printf("%" PRIu32 "
", dha->dha_smp_num_cpus);
+
+ field("Dumping CPU");
+ printf("%" PRIu32 "
", dha->dha_dumping_cpu);
+
+ if (verbose) {
+ field("ESP register");
+ printf(fmt, dha->dha_esp);
+
+ field("EIP register");
+ printf(fmt, dha->dha_eip);
+
+ for (cpu=0; cpu<dha->dha_smp_num_cpus; cpu++) {
+ regs = &dha->dha_smp_regs[cpu];
+
+ field("CPU");
+ printf("%d
", cpu);
+
+ arch_print_pt_regs(regs);
+ }
+ }
+
+ return TRUE;
+}
+
+#else
+
+static int arch_print_asmheader_v5(dump_header_asm_t *dha)
+{
+ printf("
");
+ field("ASM Magic number");
+ printf("%#" PRIx64 "
", dha->dha_magic_number);
+
+ field("Version");
+ printf("%#" PRIx32 "
", dha->dha_version);
+
+ field("Header size");
+ printf("%" PRIu32 "
", dha->dha_header_size);
+
+ return TRUE;
+}
+
+#endif /* if defined(CRASH_<ARCH>)*/
diff -urpN crash-3.10-11.orig/lkcd_v8_check.c crash-3.10-11.new/lkcd_v8_check.c
--- crash-3.10-11.orig/lkcd_v8_check.c 1970-01-01 03:00:00.000000000 +0300
+++ crash-3.10-11.new/lkcd_v8_check.c 2010-04-14 10:15:12.000000000 +0400
@@ -0,0 +1,1015 @@
+/* lkcd_v8_check.c - core analysis suite
+ *
+ * Copyright (C) 2010 MontaVista Software LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "check_defs.h"
+#include "lkcd_dump_v8.h"
+
+static dump_header_t dump_header_v8 = { 0 };
+static dump_header_asm_t dump_header_asm_v8 = { 0 };
+static dump_page_t dump_page = { 0 };
+static int arch_print_asmheader_v8(dump_header_asm_t *dha);
+
+int lkcd_dump_check_header_v8(int fd)
+{
+ int others;
+ time_t sec;
+ uint16_t host, target;
+ char buf[64];
+ dump_header_t *dh;
+ dh = &dump_header_v8;
+
+ if (lseek(fd, dump_header_offset, SEEK_SET) == ((off_t)-1)) {
+ incomplete("Could not jump to the dump header at " PRI2offs,
+ dump_header_offset, dump_header_offset);
+ return FALSE;
+ }
+
+ if (read(fd, dh, sizeof(dump_header_t)) != sizeof(dump_header_t)) {
+ incomplete("Could not read dump header");
+ return FALSE;
+ }
+
+ /* Swap everything from the target endian to mine.*/
+ dh->dh_magic_number = from_target_u64(dh->dh_magic_number);
+ dh->dh_version = from_target_u32(dh->dh_version);
+ dh->dh_header_size = from_target_u32(dh->dh_header_size);
+ dh->dh_dump_level = from_target_u32(dh->dh_dump_level);
+ dh->dh_page_size = from_target_u32(dh->dh_page_size);
+ dh->dh_memory_size = from_target_u64(dh->dh_memory_size);
+ dh->dh_memory_start = from_target_u64(dh->dh_memory_start);
+ dh->dh_memory_end = from_target_u64(dh->dh_memory_end);
+ dh->dh_num_pages = from_target_u32(dh->dh_num_pages);
+ dh->dh_time.tv_sec = from_target_u64(dh->dh_time.tv_sec);
+ dh->dh_time.tv_usec = from_target_u64(dh->dh_time.tv_usec);
+ dh->dh_current_task = from_target_u64(dh->dh_current_task);
+ dh->dh_dump_compress = from_target_u32(dh->dh_dump_compress);
+ dh->dh_dump_flags = from_target_u32(dh->dh_dump_flags);
+ dh->dh_dump_device = from_target_u32(dh->dh_dump_device);
+
+ if (dh->dh_header_size != sizeof(dump_header_t)) {
+ corrupted("Header size paradox: dh_header_size = %" PRIu32
+ ", sizeof(dump_header_t) = %zu",
+ dh->dh_header_size, sizeof(dump_header_t));
+ return FALSE;
+ }
+
+ if (silent || !print_header)
+ return TRUE;
+
+ if (dump_header_offset != 0 || verbose) {
+ field("Dump header offset");
+ printf(PRI2offsNL, dump_header_offset, dump_header_offset);
+ }
+ if (verbose) {
+ field("Magic number");
+ printf("%#" PRIx64 " ", dh->dh_magic_number);
+ if (dh->dh_magic_number == DUMP_MAGIC_NUMBER)
+ printf("(DUMP_MAGIC_NUMBER)
");
+ else if (dh->dh_magic_number == DUMP_MAGIC_LIVE)
+ printf("(DUMP_MAGIC_LIVE)
");
+ else
+ printf("(?)
");
+
+ field("Version");
+ printf("%#" PRIx32 " (", dh->dh_version);
+ others = 0;
+ switch (dh->dh_version & LKCD_DUMP_VERSION_NUMBER_MASK) {
+ case LKCD_DUMP_V1:
+ printf("%sLKCD_DUMP_V1", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V2:
+ printf("%sLKCD_DUMP_V2", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V3:
+ printf("%sLKCD_DUMP_V3", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V5:
+ printf("%sLKCD_DUMP_V5", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V6:
+ printf("%sLKCD_DUMP_V6", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V7:
+ printf("%sLKCD_DUMP_V7", others++ ? "|" : "");
+ break;
+ case LKCD_DUMP_V8:
+ printf("%sLKCD_DUMP_V8", others++ ? "|" : "");
+ break;
+ }
+ if (dh->dh_version & LKCD_DUMP_MCLX_V0)
+ printf("%sLKCD_DUMP_MCLX_V0", others++ ? "|" : "");
+ if (dh->dh_version & LKCD_DUMP_MCLX_V1)
+ printf("%sLKCD_DUMP_MCLX_V1", others++ ? "|" : "");
+ printf(")
");
+
+ field("Header size");
+ printf("%" PRIu32 "
", dh->dh_header_size);
+ }
+
+ field("Dump level");
+ printf("%#" PRIx32 " (", dh->dh_dump_level);
+ others = 0;
+ if (dh->dh_dump_level & DUMP_LEVEL_HEADER)
+ printf("%sDUMP_LEVEL_HEADER", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_LEVEL_KERN)
+ printf("%sDUMP_LEVEL_KERN", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_LEVEL_USED)
+ printf("%sDUMP_LEVEL_USED", others++ ? "|" : "");
+ if (dh->dh_dump_level & DUMP_LEVEL_ALL)
+ printf("%sDUMP_LEVEL_ALL", others++ ? "|" : "");
+ printf(")
");
+
+ field("Dump compression");
+ printf("%#" PRIx32 " (", dh->dh_dump_compress);
+ others = 0;
+ if (dh->dh_dump_compress == DUMP_COMPRESS_NONE)
+ printf("%sDUMP_COMPRESS_NONE", others++ ? "|" : "");
+ if (dh->dh_dump_compress & DUMP_COMPRESS_RLE)
+ printf("%sDUMP_COMPRESS_RLE", others++ ? "|" : "");
+ if (dh->dh_dump_compress & DUMP_COMPRESS_GZIP)
+ printf("%sDUMP_COMPRESS_GZIP", others++ ? "|" : "");
+ printf(")
");
+
+ if (verbose) {
+ field("Dump flags");
+ others = 0;
+ printf("%#" PRIx32 " (", dh->dh_dump_flags);
+ if (dh->dh_dump_flags & DUMP_FLAGS_NONDISRUPT)
+ printf("%sDUMP_FLAGS_NONDISRUPT", others++ ? "|" : "");
+ printf(")
");
+
+ field("Dump device");
+ printf("%" PRIu32 "
", dh->dh_dump_device);
+
+ field("Page size");
+ printf("%" PRIu32 "
", dh->dh_page_size);
+
+ field("Memory size");
+ printf("%#" PRIx64 "
", dh->dh_memory_size);
+
+ field("Memory start");
+ printf("%#" PRIx64 "
", dh->dh_memory_start);
+
+ field("Memory end");
+ printf("%#" PRIx64 "
", dh->dh_memory_end);
+
+ field("Num pages");
+ pri
 

Thread Tools




All times are GMT. The time now is 07:08 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org