diff --git a/crash.patch b/crash.patch index 9b5491a..a4892ec 100644 --- a/crash.patch +++ b/crash.patch @@ -1,5 +1,5 @@ ---- crash/extensions/Makefile.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/extensions/Makefile 2005-11-08 11:38:21.000000000 -0500 +--- crash/extensions/Makefile.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/extensions/Makefile 2005-11-08 11:39:26.000000000 -0500 @@ -0,0 +1,41 @@ +# +# Makefile for building crash shared object extensions @@ -42,8 +42,8 @@ +dminfo.so: ../defs.h dminfo.c + gcc -nostartfiles -shared -rdynamic -o dminfo.so dminfo.c -fPIC -D$(TARGET) + ---- crash/extensions/echo.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/extensions/echo.c 2006-05-16 15:43:05.000000000 -0400 +--- crash/extensions/echo.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/extensions/echo.c 2005-11-08 10:37:53.000000000 -0500 @@ -0,0 +1,105 @@ +/* echo.c - simple example of a crash extension + * @@ -150,8 +150,8 @@ +}; + + ---- crash/extensions/dminfo.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/extensions/dminfo.c 2006-05-16 15:43:05.000000000 -0400 +--- crash/extensions/dminfo.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/extensions/dminfo.c 2005-11-08 10:37:53.000000000 -0500 @@ -0,0 +1,1531 @@ +/* dminfo.c - crash extension module for device-mapper analysis + * @@ -1684,8 +1684,24 @@ +{ + return 0; +} ---- crash/gdb-6.1/gdb/ppc-linux-tdep.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/gdb-6.1/gdb/ppc-linux-tdep.c 2005-11-04 17:37:54.000000000 -0500 +--- crash/gdb-6.1/gdb/symfile.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/gdb-6.1/gdb/symfile.c 2006-08-23 08:40:53.000000000 -0400 +@@ -3510,6 +3510,13 @@ + bfd_byte * + symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf) + { ++#ifdef CRASH_MERGE ++ /* Executable files have all the relocations already resolved. ++ * Handle files linked with --emit-relocs. ++ * http://sources.redhat.com/ml/gdb/2006-08/msg00137.html */ ++ if ((abfd->flags & EXEC_P) != 0) ++ return NULL; ++#endif + /* We're only interested in debugging sections with relocation + information. */ + if ((sectp->flags & SEC_RELOC) == 0) +--- crash/gdb-6.1/gdb/ppc-linux-tdep.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/gdb-6.1/gdb/ppc-linux-tdep.c 2005-07-14 11:08:17.000000000 -0400 @@ -0,0 +1,1116 @@ +/* Target-dependent code for GDB, the GNU debugger. + @@ -2803,8 +2819,8 @@ + ppc_linux_init_abi); + add_core_fns (&ppc_linux_regset_core_fns); +} ---- crash/main.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/main.c 2006-08-03 16:58:32.000000000 -0400 +--- crash/main.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/main.c 2006-08-31 15:56:58.000000000 -0400 @@ -35,11 +35,15 @@ {"no_data_debug", 0, 0, 0}, {"no_crashrc", 0, 0, 0}, @@ -2826,7 +2842,7 @@ opterr = 0; optind = 0; - while((c = getopt_long(argc, argv, "LgH:h:e:i:sSvc:d:tf", -+ while((c = getopt_long(argc, argv, "LgH:h:e:i:sSvc:d:tfp:", ++ while((c = getopt_long(argc, argv, "LgH:h:e:i:sSvc:d:tfp:m:", long_options, &option_index)) != -1) { switch (c) { @@ -2875,18 +2891,22 @@ break; case 'L': -@@ -193,6 +212,10 @@ +@@ -193,6 +212,14 @@ set_vas_debug(pc->debug); break; + case 'p': + force_page_size(optarg); + break; ++ ++ case 'm': ++ machdep->cmdline_arg = optarg; ++ break; + default: if (STREQ(argv[optind-1], "-h")) program_usage(LONG_FORM); -@@ -264,6 +287,28 @@ +@@ -264,6 +291,28 @@ pc->readmem = read_netdump; pc->writemem = write_netdump; @@ -2915,26 +2935,36 @@ } else if (is_diskdump(argv[optind])) { if (pc->flags & MEMORY_SOURCES) { error(INFO, -@@ -335,8 +380,7 @@ +@@ -335,8 +384,6 @@ machdep_init(PRE_SYMTAB); symtab_init(); machdep_init(PRE_GDB); - kernel_init(PRE_GDB); - verify_version(); -+ read_in_kernel_config(IKCFG_INIT); datatype_init(); /* -@@ -361,6 +405,8 @@ +@@ -361,7 +408,8 @@ { if (!(pc->flags & GDB_INIT)) { gdb_session_init(); -+ kernel_init(PRE_GDB); -+ verify_version(); - kernel_init(POST_GDB); +- kernel_init(POST_GDB); ++ read_in_kernel_config(IKCFG_INIT); ++ kernel_init(); machdep_init(POST_GDB); vm_init(); -@@ -591,6 +637,8 @@ + hq_init(); +@@ -459,6 +507,9 @@ + + pc->curcmd = pc->program_name; + error(INFO, "command not found: %s\n", args[0]); ++ ++ if (pc->curcmd_flags & REPEAT) ++ pc->curcmd_flags &= ~REPEAT; + } + + +@@ -591,6 +642,8 @@ int i; char *p1; char buf[BUFSIZE]; @@ -2943,7 +2973,7 @@ FILE *afp; char *program; -@@ -685,11 +733,11 @@ +@@ -685,11 +738,11 @@ pc->home = "(unknown)"; } else strcpy(pc->home, p1); @@ -2959,7 +2989,7 @@ else { while (fgets(buf, BUFSIZE, afp)) resolve_rc_cmd(buf, ALIAS_RCHOME); -@@ -698,11 +746,12 @@ +@@ -698,11 +751,12 @@ } } @@ -2976,7 +3006,7 @@ else { while (fgets(buf, BUFSIZE, afp)) resolve_rc_cmd(buf, ALIAS_RCLOCAL); -@@ -840,13 +889,22 @@ +@@ -840,13 +894,22 @@ if (pc->flags & REM_S390D) sprintf(&buf[strlen(buf)], "%sREM_S390D", others++ ? "|" : ""); @@ -3001,7 +3031,7 @@ sprintf(&buf[strlen(buf)], "%sDISKDUMP", others++ ? "|" : ""); if (pc->flags & SYSMAP) -@@ -855,21 +913,24 @@ +@@ -855,21 +918,24 @@ if (pc->flags & SYSMAP_ARG) sprintf(&buf[strlen(buf)], "%sSYSMAP_ARG", others++ ? "|" : ""); @@ -3031,7 +3061,7 @@ if (pc->flags) strcat(buf, ")"); -@@ -1017,6 +1078,11 @@ +@@ -1017,6 +1083,13 @@ fprintf(fp, " cur_req: %lx\n", (ulong)pc->cur_req); fprintf(fp, " cmdgencur: %ld\n", pc->cmdgencur); fprintf(fp, " cmdgenspec: %ld\n", pc->cmdgenspec); @@ -3039,11 +3069,13 @@ + others = 0; + if (pc->curcmd_flags & XEN_MACHINE_ADDR) + fprintf(fp, "%sXEN_MACHINE_ADDR", others ? "|" : ""); ++ if (pc->curcmd_flags & REPEAT) ++ fprintf(fp, "%sREPEAT", others ? "|" : ""); + fprintf(fp, ")\n"); fprintf(fp, " sigint_cnt: %d\n", pc->sigint_cnt); fprintf(fp, " sigaction: %lx\n", (ulong)&pc->sigaction); fprintf(fp, " gdb_sigaction: %lx\n", (ulong)&pc->gdb_sigaction); -@@ -1051,6 +1117,10 @@ +@@ -1051,6 +1124,10 @@ fprintf(fp, " readmem: read_daemon()\n"); else if (pc->readmem == read_netdump) fprintf(fp, " readmem: read_netdump()\n"); @@ -3054,7 +3086,7 @@ else if (pc->readmem == read_memory_device) fprintf(fp, " readmem: read_memory_device()\n"); else -@@ -1065,6 +1135,10 @@ +@@ -1065,6 +1142,10 @@ fprintf(fp, " writemem: write_daemon()\n"); else if (pc->writemem == write_netdump) fprintf(fp, " writemem: write_netdump()\n"); @@ -3065,8 +3097,8 @@ else if (pc->writemem == write_memory_device) fprintf(fp, " writemem: write_memory_device()\n"); else ---- crash/tools.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/tools.c 2006-07-06 16:21:55.000000000 -0400 +--- crash/tools.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/tools.c 2006-07-10 11:35:06.000000000 -0400 @@ -2004,6 +2004,10 @@ pc->flags &= ~(DUMPFILE_TYPES); if (is_netdump(args[optind], NETDUMP_LOCAL)) @@ -3183,8 +3215,20 @@ + + return ((c2 == '\0') && (c1 == '/') && (*p1 == '\0')) ? 0 : c1 - c2; +} ---- crash/memory.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/memory.c 2006-08-02 10:32:08.000000000 -0400 +--- crash/global_data.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/global_data.c 2006-08-14 11:40:07.000000000 -0400 +@@ -117,6 +117,9 @@ + {"waitq", cmd_waitq, help_waitq, REFRESH_TASK_TABLE}, + {"whatis", cmd_whatis, help_whatis, 0}, + {"wr", cmd_wr, help_wr, 0}, ++#if defined(S390) || defined(S390X) ++ {"s390dbf", cmd_s390dbf, help_s390dbf, 0}, ++#endif + {(char *)NULL} + }; + +--- crash/memory.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/memory.c 2006-09-06 15:55:00.000000000 -0400 @@ -45,6 +45,8 @@ ulong *addrlist; int *kmem_bufctl; @@ -3194,7 +3238,7 @@ ulong found; ulong retval; char *ignore; -@@ -57,6 +59,10 @@ +@@ -57,12 +59,17 @@ ulong get_slabs; char *slab_buf; char *cache_buf; @@ -3205,7 +3249,15 @@ }; static char *memtype_string(int, int); -@@ -85,6 +91,7 @@ + static char *error_handle_string(ulong); + static void dump_mem_map(struct meminfo *); +-static void fill_mem_map_cache(ulong, char *); ++static void dump_mem_map_SPARSEMEM(struct meminfo *); ++static void fill_mem_map_cache(ulong, ulong, char *); + static void dump_free_pages(struct meminfo *); + static int dump_zone_page_usage(void); + static void dump_multidimensional_free_pages(struct meminfo *); +@@ -85,6 +92,7 @@ static void do_slab_chain(int, struct meminfo *); static void do_slab_chain_percpu_v1(long, struct meminfo *); static void do_slab_chain_percpu_v2(long, struct meminfo *); @@ -3213,7 +3265,7 @@ static void save_slab_data(struct meminfo *); static int slab_data_saved(struct meminfo *); static void dump_saved_slab_data(void); -@@ -97,7 +104,9 @@ +@@ -97,7 +105,9 @@ static void gather_slab_free_list_percpu(struct meminfo *); static void gather_cpudata_list_v1(struct meminfo *); static void gather_cpudata_list_v2(struct meminfo *); @@ -3223,7 +3275,7 @@ static void gather_slab_cached_count(struct meminfo *); static void dump_slab_objects(struct meminfo *); static void dump_slab_objects_percpu(struct meminfo *); -@@ -110,6 +119,7 @@ +@@ -110,6 +120,7 @@ static void search(ulong, ulong, ulong, int, ulong *, int); static int next_upage(struct task_context *, ulong, ulong *); static int next_kpage(ulong, ulong *); @@ -3231,7 +3283,7 @@ static int vm_area_page_dump(ulong, ulong, ulong, ulong, void *, struct reference *); static int dump_swap_info(ulong, ulong *, ulong *); -@@ -124,9 +134,18 @@ +@@ -124,9 +135,24 @@ static int compare_node_data(const void *, const void *); static void do_vm_flags(ulong); static void PG_reserved_flag_init(void); @@ -3240,6 +3292,7 @@ - - +void sparse_mem_init(void); ++void dump_mem_sections(void); +void list_mem_sections(void); +ulong sparse_decode_mem_map(ulong, ulong); +char *read_mem_section(ulong); @@ -3249,10 +3302,15 @@ +ulong section_mem_map_addr(ulong); +ulong valid_section_nr(ulong); +ulong pfn_to_map(ulong); ++static int get_nodes_online(void); ++static int next_online_node(int); ++static ulong next_online_pgdat(int); ++static int vm_stat_init(void); ++static int dump_vm_stat(char *, long *); /* * Memory display modes specific to this file. -@@ -142,6 +161,7 @@ +@@ -142,6 +168,7 @@ #define DECIMAL (0x100) #define UDECIMAL (0x200) #define ASCII_ENDLINE (0x400) @@ -3260,7 +3318,7 @@ static ulong DISPLAY_DEFAULT; -@@ -182,6 +202,13 @@ +@@ -182,6 +209,13 @@ MEMBER_OFFSET_INIT(mm_struct_mmap, "mm_struct", "mmap"); MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd"); MEMBER_OFFSET_INIT(mm_struct_rss, "mm_struct", "rss"); @@ -3274,7 +3332,7 @@ MEMBER_OFFSET_INIT(mm_struct_total_vm, "mm_struct", "total_vm"); MEMBER_OFFSET_INIT(mm_struct_start_code, "mm_struct", "start_code"); MEMBER_OFFSET_INIT(vm_area_struct_vm_mm, "vm_area_struct", "vm_mm"); -@@ -270,6 +297,7 @@ +@@ -270,6 +304,7 @@ STRUCT_SIZE_INIT(kmem_slab_s, "kmem_slab_s"); STRUCT_SIZE_INIT(slab_s, "slab_s"); STRUCT_SIZE_INIT(slab, "slab"); @@ -3282,7 +3340,7 @@ STRUCT_SIZE_INIT(pgd_t, "pgd_t"); if (!VALID_STRUCT(kmem_slab_s) && VALID_STRUCT(slab_s)) { -@@ -310,17 +338,49 @@ +@@ -310,17 +345,49 @@ !VALID_STRUCT(slab_s) && VALID_STRUCT(slab)) { vt->flags |= PERCPU_KMALLOC_V2; @@ -3343,7 +3401,7 @@ MEMBER_OFFSET_INIT(slab_list, "slab", "list"); MEMBER_OFFSET_INIT(slab_s_mem, "slab", "s_mem"); MEMBER_OFFSET_INIT(slab_inuse, "slab", "inuse"); -@@ -330,10 +390,6 @@ +@@ -330,10 +397,6 @@ MEMBER_OFFSET_INIT(array_cache_limit, "array_cache", "limit"); STRUCT_SIZE_INIT(array_cache, "array_cache"); @@ -3354,7 +3412,7 @@ MEMBER_OFFSET_INIT(kmem_list3_slabs_partial, "kmem_list3", "slabs_partial"); MEMBER_OFFSET_INIT(kmem_list3_slabs_full, -@@ -381,6 +437,19 @@ +@@ -381,6 +444,19 @@ "kmem_slab_s", "s_magic"); } @@ -3374,7 +3432,7 @@ if (machdep->init_kernel_pgd) machdep->init_kernel_pgd(); else if (symbol_exists("swapper_pg_dir")) { -@@ -415,10 +484,17 @@ +@@ -415,10 +491,17 @@ error(FATAL, "no swapper_pg_dir or cpu_pgd symbols exist?\n"); get_symbol_data("high_memory", sizeof(ulong), &vt->high_memory); @@ -3393,7 +3451,7 @@ vt->vmalloc_start = machdep->vmalloc_start(); if (IS_VMALLOC_ADDR(vt->mem_map)) vt->flags |= V_MEM_MAP; -@@ -478,7 +554,6 @@ +@@ -478,7 +561,6 @@ STRUCT_SIZE_INIT(free_area_struct, "free_area_struct"); STRUCT_SIZE_INIT(zone, "zone"); STRUCT_SIZE_INIT(zone_struct, "zone_struct"); @@ -3401,7 +3459,31 @@ STRUCT_SIZE_INIT(kmem_bufctl_t, "kmem_bufctl_t"); STRUCT_SIZE_INIT(swap_info_struct, "swap_info_struct"); STRUCT_SIZE_INIT(mm_struct, "mm_struct"); -@@ -524,6 +599,7 @@ +@@ -488,13 +570,20 @@ + if (VALID_STRUCT(pglist_data)) { + vt->flags |= ZONES; + +- if (symbol_exists("pgdat_list")) ++ if (symbol_exists("pgdat_list") && !IS_SPARSEMEM()) + vt->flags |= NODES; + ++ /* ++ * Determine the number of nodes the best way possible, ++ * starting with a default of 1. ++ */ ++ vt->numnodes = 1; ++ + if (symbol_exists("numnodes")) + get_symbol_data("numnodes", sizeof(int), &vt->numnodes); +- else +- vt->numnodes = 1; ++ ++ if ((vt->numnodes = get_nodes_online())) ++ vt->flags |= NODES_ONLINE; + + MEMBER_OFFSET_INIT(pglist_data_node_zones, + "pglist_data", "node_zones"); +@@ -524,6 +613,7 @@ ARRAY_LENGTH_INIT(vt->nr_zones, pglist_data_node_zones, "pglist_data.node_zones", NULL, SIZE_OPTION(zone_struct, zone)); @@ -3409,7 +3491,7 @@ if (VALID_STRUCT(zone_struct)) { MEMBER_OFFSET_INIT(zone_struct_free_pages, -@@ -539,6 +615,8 @@ +@@ -539,6 +629,8 @@ if (INVALID_MEMBER(zone_struct_size)) MEMBER_OFFSET_INIT(zone_struct_memsize, "zone_struct", "memsize"); @@ -3418,7 +3500,7 @@ MEMBER_OFFSET_INIT(zone_struct_zone_start_paddr, "zone_struct", "zone_start_paddr"); MEMBER_OFFSET_INIT(zone_struct_zone_start_mapnr, -@@ -640,13 +718,7 @@ +@@ -640,13 +732,7 @@ kmem_cache_init(); PG_reserved_flag_init(); @@ -3433,7 +3515,7 @@ } /* -@@ -685,7 +757,7 @@ +@@ -685,7 +771,7 @@ memtype = KVADDR; count = -1; @@ -3442,7 +3524,7 @@ switch(c) { case '8': -@@ -748,12 +820,12 @@ +@@ -748,12 +834,12 @@ break; case 'p': @@ -3457,7 +3539,7 @@ memtype = UVADDR; break; -@@ -767,6 +839,17 @@ +@@ -767,6 +853,17 @@ flag |= UDECIMAL; break; @@ -3475,7 +3557,7 @@ default: argerrs++; break; -@@ -830,7 +913,7 @@ +@@ -830,7 +927,7 @@ error(WARNING, "ending address ignored when count is specified\n"); @@ -3484,7 +3566,7 @@ flag |= ASCII_ENDLINE; if (memtype == KVADDR) { -@@ -839,7 +922,6 @@ +@@ -839,7 +936,6 @@ } display_memory(addr, count, flag, memtype); @@ -3492,7 +3574,7 @@ } /* -@@ -903,6 +985,9 @@ +@@ -903,6 +999,9 @@ case PHYSADDR: addrtype = "PHYSADDR"; break; @@ -3502,7 +3584,7 @@ } if (CRASHDEBUG(4)) -@@ -970,7 +1055,8 @@ +@@ -970,7 +1069,8 @@ case DISPLAY_64: if ((flag & (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) == (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) { @@ -3512,7 +3594,7 @@ fprintf(fp, "%-16s ", value_to_symstr(mem.u64, buf, 0)); linelen += strlen(buf)+1; -@@ -993,7 +1079,8 @@ +@@ -993,7 +1093,8 @@ case DISPLAY_32: if ((flag & (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) == (HEXADECIMAL|SYMBOLIC|DISPLAY_DEFAULT)) { @@ -3522,7 +3604,7 @@ fprintf(fp, INT_PRLEN == 16 ? "%-16s " : "%-8s ", value_to_symstr(mem.u32, -@@ -1376,6 +1463,7 @@ +@@ -1376,6 +1477,7 @@ int fd; long cnt; physaddr_t paddr; @@ -3530,7 +3612,7 @@ char *bufptr; if (CRASHDEBUG(4)) -@@ -1424,6 +1512,7 @@ +@@ -1424,6 +1526,7 @@ break; case PHYSADDR: @@ -3538,7 +3620,7 @@ break; } -@@ -1449,6 +1538,17 @@ +@@ -1449,6 +1552,17 @@ case PHYSADDR: paddr = addr; break; @@ -3556,7 +3638,7 @@ } /* -@@ -1460,7 +1560,7 @@ +@@ -1460,7 +1574,7 @@ cnt = size; switch (READMEM(fd, bufptr, cnt, @@ -3565,7 +3647,7 @@ { case SEEK_ERROR: if (PRINT_ERROR_MESSAGE) -@@ -1610,6 +1710,9 @@ +@@ -1610,6 +1724,9 @@ int read_memory_device(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr) { @@ -3575,7 +3657,7 @@ if (!machdep->verify_paddr(paddr)) { if (CRASHDEBUG(1)) error(INFO, "verify_paddr(%lx) failed\n", paddr); -@@ -1754,6 +1857,9 @@ +@@ -1754,6 +1871,9 @@ case PHYSADDR: sprintf(membuf, debug ? "PHYSADDR" : "physical"); break; @@ -3585,7 +3667,7 @@ default: if (debug) sprintf(membuf, "0x%x (?)", memtype); -@@ -2113,6 +2219,8 @@ +@@ -2113,6 +2233,8 @@ break; } @@ -3594,7 +3676,7 @@ switch (memtype) { case UVADDR: fprintf(fp, "%s %s\n", -@@ -2126,9 +2234,12 @@ +@@ -2126,9 +2248,12 @@ return; } if (!uvtop(tc, vaddr, &paddr, 0)) { @@ -3609,7 +3691,7 @@ page_exists = FALSE; } else { fprintf(fp, "%s %s\n\n", -@@ -2161,9 +2272,13 @@ +@@ -2161,9 +2286,13 @@ } if (vtop_flags & USE_USER_PGD) { if (!uvtop(tc, vaddr, &paddr, 0)) { @@ -3625,7 +3707,7 @@ page_exists = FALSE; } else { fprintf(fp, "%s %s\n\n", -@@ -2176,9 +2291,13 @@ +@@ -2176,9 +2305,13 @@ uvtop(tc, vaddr, &paddr, VERBOSE); } else { if (!kvtop(tc, vaddr, &paddr, 0)) { @@ -3641,7 +3723,7 @@ page_exists = FALSE; } else { fprintf(fp, "%s %s\n\n", -@@ -2980,6 +3099,8 @@ +@@ -2980,6 +3113,8 @@ return; tm->rss = ULONG(tt->mm_struct + OFFSET(mm_struct_rss)); @@ -3650,7 +3732,7 @@ tm->total_vm = ULONG(tt->mm_struct + OFFSET(mm_struct_total_vm)); tm->pgd_addr = ULONG(tt->mm_struct + OFFSET(mm_struct_pgd)); -@@ -3036,6 +3157,9 @@ +@@ -3036,6 +3171,9 @@ #define GET_INACTIVE_DIRTY (ADDRESS_SPECIFIED << 13) /* obsolete */ #define SLAB_GET_COUNTS (ADDRESS_SPECIFIED << 14) #define SLAB_WALKTHROUGH (ADDRESS_SPECIFIED << 15) @@ -3660,7 +3742,43 @@ #define GET_ALL \ (GET_SHARED_PAGES|GET_TOTALRAM_PAGES|GET_BUFFERS_PAGES|GET_SLAB_PAGES) -@@ -3159,7 +3283,7 @@ +@@ -3046,7 +3184,7 @@ + int i; + int c; + int sflag, Sflag, pflag, fflag, Fflag, vflag; +- int nflag, cflag, Cflag, iflag, lflag, Lflag, Pflag; ++ int nflag, cflag, Cflag, iflag, lflag, Lflag, Pflag, Vflag; + struct meminfo meminfo; + ulonglong value[MAXARGS]; + char buf[BUFSIZE]; +@@ -3055,13 +3193,17 @@ + + spec_addr = 0; + sflag = Sflag = pflag = fflag = Fflag = Pflag = 0; +- vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = 0; ++ vflag = Cflag = cflag = iflag = nflag = lflag = Lflag = Vflag = 0; + BZERO(&meminfo, sizeof(struct meminfo)); + BZERO(&value[0], sizeof(ulonglong)*MAXARGS); + +- while ((c = getopt(argcnt, args, "I:sSFfpvcCinl:L:P")) != EOF) { ++ while ((c = getopt(argcnt, args, "I:sSFfpvcCinl:L:PV")) != EOF) { + switch(c) + { ++ case 'V': ++ Vflag = 1; ++ break; ++ + case 'n': + nflag = 1; + break; +@@ -3153,13 +3295,13 @@ + if (argerrs) + cmd_usage(pc->curcmd, SYNOPSIS); + +- if ((sflag + Sflag + pflag + fflag + Fflag + ++ if ((sflag + Sflag + pflag + fflag + Fflag + Vflag + + vflag + Cflag + cflag + iflag + lflag + Lflag) > 1) { + error(INFO, "only one flag allowed!\n"); cmd_usage(pc->curcmd, SYNOPSIS); } @@ -3669,7 +3787,28 @@ kmem_cache_init(); while (args[optind]) { -@@ -3373,12 +3497,13 @@ +@@ -3275,7 +3417,7 @@ + /* + * no value arguments allowed! + */ +- if (nflag || iflag || Fflag || Cflag || Lflag) { ++ if (nflag || iflag || Fflag || Cflag || Lflag || Vflag) { + error(INFO, + "no address arguments allowed with this option\n"); + cmd_usage(pc->curcmd, SYNOPSIS); +@@ -3352,7 +3494,10 @@ + dump_page_lists(&meminfo); + } + +- if (!(sflag + Sflag + pflag + fflag + Fflag + vflag + ++ if (Vflag == 1) ++ dump_vm_stat(NULL, NULL); ++ ++ if (!(sflag + Sflag + pflag + fflag + Fflag + vflag + Vflag + + cflag + Cflag + iflag + nflag + lflag + Lflag + meminfo.calls)) + cmd_usage(pc->curcmd, SYNOPSIS); + +@@ -3373,12 +3518,13 @@ buf = (char *)GETBUF(SIZE(page)); if (!readmem(pageptr, KVADDR, buf, SIZE(page), @@ -3685,7 +3824,7 @@ if (count_bits_long(flags) == 1) vt->PG_reserved = flags; else -@@ -3386,12 +3511,50 @@ +@@ -3386,12 +3532,50 @@ if (CRASHDEBUG(2)) fprintf(fp, @@ -3737,13 +3876,15 @@ /* * dump_mem_map() displays basic data about each entry in the mem_map[] * array, or if an address is specified, just the mem_map[] entry for that -@@ -3440,16 +3603,16 @@ +@@ -3438,22 +3622,20 @@ + #define PGMM_CACHED (512) + static void - dump_mem_map(struct meminfo *mi) +-dump_mem_map(struct meminfo *mi) ++dump_mem_map_SPARSEMEM(struct meminfo *mi) { - long i, n; + ulong i; -+ long node; long total_pages; - int others, page_not_mapped, phys_not_mapped; + int others, page_not_mapped, phys_not_mapped, page_mapping; @@ -3757,44 +3898,43 @@ uint count; int print_hdr, pg_spec, phys_spec, done; int v22; -@@ -3462,6 +3625,7 @@ +- struct node_table *nt; + char hdr[BUFSIZE]; + char buf0[BUFSIZE]; + char buf1[BUFSIZE]; +@@ -3462,6 +3644,7 @@ char buf4[BUFSIZE]; char *page_cache; char *pcache; -+ ulong section, section_nr, nr_mem_sections, node_or_section_size; ++ ulong section, section_nr, nr_mem_sections, section_size; v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */ -@@ -3549,22 +3713,67 @@ +@@ -3549,22 +3732,52 @@ done = FALSE; total_pages = 0; - for (n = 0; n < vt->numnodes; n++) { -+ if (IS_SPARSEMEM()) -+ nr_mem_sections = NR_MEM_SECTIONS(); -+ else -+ nr_mem_sections = 1; ++ nr_mem_sections = NR_MEM_SECTIONS(); + + /* + * Iterate over all possible sections + */ -+ node = 0; + for (section_nr = 0; section_nr < nr_mem_sections ; section_nr++) { + + if (CRASHDEBUG(2)) -+ printf("section_nr = %ld\n", section_nr); ++ fprintf(fp, "section_nr = %ld\n", section_nr); + + /* + * If we are looking up a specific address, jump directly + * to the section with that page + */ -+ if (IS_SPARSEMEM() && (mi->flags & ADDRESS_SPECIFIED)) { ++ if (mi->flags & ADDRESS_SPECIFIED) { + ulong pfn = mi->spec_addr >> PAGESHIFT(); + section_nr = pfn_to_section_nr(pfn); + } + -+ if (IS_SPARSEMEM() && -+ !(section = valid_section_nr(section_nr))) { ++ if (!(section = valid_section_nr(section_nr))) { +#ifdef NOTDEF + break; /* On a real sparsemem system we need to check + * every section as gaps may exist. But this @@ -3805,12 +3945,14 @@ + * this loop. + */ +#endif ++ if (mi->flags & ADDRESS_SPECIFIED) ++ break; + continue; + } + if (print_hdr) { - fprintf(fp, "%s%s", n ? "\n" : "", hdr); -+ fprintf(fp, "%s%s", node ? "\n" : "", hdr); ++ fprintf(fp, "%s", hdr); print_hdr = FALSE; } @@ -3822,29 +3964,26 @@ - node_size = vt->max_mapnr; - else - node_size = nt->size; -+next_node: -+ if (IS_SPARSEMEM()) { -+ pp = section_mem_map_addr(section); -+ pp = sparse_decode_mem_map(pp, section_nr); -+ phys = section_nr * PAGES_PER_SECTION() * PAGESIZE(); -+ node_or_section_size = PAGES_PER_SECTION(); -+ } else { -+ nt = &vt->node_table[node]; -+ total_pages += nt->size; -+ pp = nt->mem_map; -+ phys = nt->start_paddr; -+ if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1)) -+ node_or_section_size = vt->max_mapnr; -+ else -+ node_or_section_size = nt->size; -+ } ++ pp = section_mem_map_addr(section); ++ pp = sparse_decode_mem_map(pp, section_nr); ++ phys = section_nr * PAGES_PER_SECTION() * PAGESIZE(); ++ section_size = PAGES_PER_SECTION(); - for (i = 0; i < node_size; -+ for (i = 0; i < node_or_section_size; ++ for (i = 0; i < section_size; i++, pp += SIZE(page), phys += PAGESIZE()) { if ((i % PGMM_CACHED) == 0) { -@@ -3653,11 +3862,12 @@ +@@ -3581,7 +3794,7 @@ + continue; + } + +- fill_mem_map_cache(pp, page_cache); ++ fill_mem_map_cache(pp, ppend, page_cache); + } + + pcache = page_cache + ((i%PGMM_CACHED) * SIZE(page)); +@@ -3653,11 +3866,12 @@ } continue; } @@ -3858,7 +3997,7 @@ mapping = ULONG(pcache + OFFSET(page_mapping)); index = ULONG(pcache + OFFSET(page_index)); -@@ -3700,6 +3910,20 @@ +@@ -3700,6 +3914,20 @@ space(MINSPACE), mkstring(buf4, 8, CENTER|RJUST, " "), " "); @@ -3879,19 +4018,609 @@ else fprintf(fp, "%s%s%s%s%s%s%8ld %2d ", mkstring(buf0, VADDR_PRLEN, -@@ -3827,6 +4051,11 @@ +@@ -3862,88 +4090,533 @@ + FREEBUF(page_cache); + } - if (done) - break; -+ -+ node++; -+ -+ if ((node < vt->numnodes) && !IS_SPARSEMEM()) -+ goto next_node; - } +-/* +- * Stash a chunk of PGMM_CACHED page structures, starting at addr, into the +- * passed-in buffer. The mem_map array is normally guaranteed to be +- * readable except in the case of virtual mem_map usage. When V_MEM_MAP +- * is in place, read all pages consumed by PGMM_CACHED page structures +- * that are currently mapped, leaving the unmapped ones just zeroed out. +- */ + static void +-fill_mem_map_cache(ulong pp, char *page_cache) ++dump_mem_map(struct meminfo *mi) + { +- long size, cnt; +- ulong addr; +- char *bufptr; ++ long i, n; ++ long total_pages; ++ int others, page_not_mapped, phys_not_mapped, page_mapping; ++ ulong pp, ppend; ++ physaddr_t phys, physend; ++ ulong tmp, reserved, shared, slabs; ++ ulong PG_reserved_flag; ++ long buffers; ++ ulong inode, offset, flags, mapping, index; ++ ulong node_size; ++ uint count; ++ int print_hdr, pg_spec, phys_spec, done; ++ int v22; ++ struct node_table *nt; ++ char hdr[BUFSIZE]; ++ char buf0[BUFSIZE]; ++ char buf1[BUFSIZE]; ++ char buf2[BUFSIZE]; ++ char buf3[BUFSIZE]; ++ char buf4[BUFSIZE]; ++ char *page_cache; ++ char *pcache; - switch (mi->flags) -@@ -4520,13 +4749,6 @@ +- /* +- * Try to read it in one fell swoop. +- */ +- if (readmem(pp, KVADDR, page_cache, SIZE(page) * PGMM_CACHED, +- "page struct cache", RETURN_ON_ERROR|QUIET)) ++ if (IS_SPARSEMEM()) { ++ dump_mem_map_SPARSEMEM(mi); + return; ++ } + +- /* +- * Break it into page-size-or-less requests, warning if it's +- * not a virtual mem_map. +- */ +- size = SIZE(page) * PGMM_CACHED; +- addr = pp; +- bufptr = page_cache; +- +- while (size > 0) { +- /* +- * Compute bytes till end of page. +- */ +- cnt = PAGESIZE() - PAGEOFFSET(addr); ++ v22 = VALID_MEMBER(page_inode); /* page.inode vs. page.mapping */ + +- if (cnt > size) +- cnt = size; ++ if (v22) { ++ sprintf(hdr, "%s%s%s%s%s%s%s%sCNT FLAGS\n", ++ mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), ++ space(MINSPACE), ++ mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")), ++ RJUST, "PHYSICAL"), ++ space(MINSPACE), ++ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "INODE"), ++ space(MINSPACE), ++ mkstring(buf4, 8, CENTER|LJUST, "OFFSET"), ++ space(MINSPACE-1)); ++ } else { ++ sprintf(hdr, "%s%s%s%s%s%s%sCNT FLAGS\n", ++ mkstring(buf1, VADDR_PRLEN, CENTER, "PAGE"), ++ space(MINSPACE), ++ mkstring(buf2, MAX(PADDR_PRLEN, strlen("PHYSICAL")), ++ RJUST, "PHYSICAL"), ++ space(MINSPACE), ++ mkstring(buf3, VADDR_PRLEN, CENTER|RJUST, "MAPPING"), ++ space(MINSPACE), ++ mkstring(buf4, 8, CENTER|RJUST, "INDEX")); ++ } + +- if (!readmem(addr, KVADDR, bufptr, size, +- "virtual page struct cache", RETURN_ON_ERROR|QUIET)) { +- BZERO(bufptr, size); +- if (!(vt->flags & V_MEM_MAP)) +- error(WARNING, +- "mem_map[] from %lx to %lx not accessible\n", +- addr, addr+size); ++ pg_spec = phys_spec = print_hdr = FALSE; ++ ++ switch (mi->flags) ++ { ++ case ADDRESS_SPECIFIED: ++ switch (mi->memtype) ++ { ++ case KVADDR: ++ if (is_page_ptr(mi->spec_addr, NULL)) ++ pg_spec = TRUE; ++ else { ++ if (kvtop(NULL, mi->spec_addr, &phys, 0)) { ++ mi->spec_addr = phys; ++ phys_spec = TRUE; ++ } ++ else ++ return; ++ } ++ break; ++ case PHYSADDR: ++ phys_spec = TRUE; ++ break; ++ default: ++ error(FATAL, "dump_mem_map: no memtype specified\n"); ++ break; + } ++ print_hdr = TRUE; ++ break; + +- addr += cnt; +- bufptr += cnt; +- size -= cnt; +- } +-} ++ case GET_ALL: ++ shared = 0; ++ reserved = 0; ++ buffers = 0; ++ slabs = 0; ++ break; + ++ case GET_SHARED_PAGES: ++ shared = 0; ++ break; + +-/* +- * dump_page_hash_table() displays the entries in each page_hash_table. +- */ ++ case GET_TOTALRAM_PAGES: ++ reserved = 0; ++ break; + +-#define PGHASH_CACHED (1024) ++ case GET_BUFFERS_PAGES: ++ buffers = 0; ++ break; + +-static void +-dump_page_hash_table(struct meminfo *hi) +-{ +- int i; +- int len, entry_len; +- ulong page_hash_table, head; +- struct list_data list_data, *ld; +- struct gnu_request req; +- long total_cached; +- long page_cache_size; +- ulong this_addr, searchpage; +- int errflag, found, cnt, populated, verbose; +- uint ival; +- ulong buffer_pages; +- char buf[BUFSIZE]; +- char hash_table[BUFSIZE]; +- char *pcache, *pghash_cache; ++ case GET_SLAB_PAGES: ++ slabs = 0; ++ break; + +- if (!vt->page_hash_table) { +- if (hi->flags & VERBOSE) +- error(FATAL, +- "address_space page cache radix tree not supported\n"); ++ default: ++ print_hdr = TRUE; ++ break; ++ } ++ ++ page_cache = GETBUF(SIZE(page) * PGMM_CACHED); ++ done = FALSE; ++ total_pages = 0; ++ ++ for (n = 0; n < vt->numnodes; n++) { ++ if (print_hdr) { ++ fprintf(fp, "%s%s", n ? "\n" : "", hdr); ++ print_hdr = FALSE; ++ } ++ ++ nt = &vt->node_table[n]; ++ total_pages += nt->size; ++ pp = nt->mem_map; ++ phys = nt->start_paddr; ++ if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1)) ++ node_size = vt->max_mapnr; ++ else ++ node_size = nt->size; ++ ++ for (i = 0; i < node_size; ++ i++, pp += SIZE(page), phys += PAGESIZE()) { ++ ++ if ((i % PGMM_CACHED) == 0) { ++ ppend = pp + ((PGMM_CACHED-1) * SIZE(page)); ++ physend = phys + ((PGMM_CACHED-1) * PAGESIZE()); ++ ++ if ((pg_spec && (mi->spec_addr > ppend)) || ++ (phys_spec && ++ (PHYSPAGEBASE(mi->spec_addr) > physend))) { ++ i += (PGMM_CACHED-1); ++ pp = ppend; ++ phys = physend; ++ continue; ++ } ++ ++ fill_mem_map_cache(pp, ppend, page_cache); ++ } ++ ++ pcache = page_cache + ((i%PGMM_CACHED) * SIZE(page)); ++ ++ if (received_SIGINT()) ++ restart(0); ++ ++ if ((pg_spec && (pp == mi->spec_addr)) || ++ (phys_spec && (phys == PHYSPAGEBASE(mi->spec_addr)))) ++ done = TRUE; ++ ++ if (!done && (pg_spec || phys_spec)) ++ continue; ++ ++ flags = ULONG(pcache + OFFSET(page_flags)); ++ count = UINT(pcache + OFFSET(page_count)); ++ ++ switch (mi->flags) ++ { ++ case GET_ALL: ++ case GET_BUFFERS_PAGES: ++ if (VALID_MEMBER(page_buffers)) { ++ tmp = ULONG(pcache + ++ OFFSET(page_buffers)); ++ if (tmp) ++ buffers++; ++ } else if (THIS_KERNEL_VERSION >= LINUX(2,6,0)) { ++ if ((flags >> v26_PG_private) & 1) ++ buffers++; ++ } else ++ error(FATAL, ++ "cannot determine whether pages have buffers\n"); ++ ++ if (mi->flags != GET_ALL) ++ continue; ++ ++ /* FALLTHROUGH */ ++ ++ case GET_SLAB_PAGES: ++ if (v22) { ++ if ((flags >> v22_PG_Slab) & 1) ++ slabs++; ++ } else if (vt->PG_slab) { ++ if ((flags >> vt->PG_slab) & 1) ++ slabs++; ++ } else { ++ if ((flags >> v24_PG_slab) & 1) ++ slabs++; ++ } ++ if (mi->flags != GET_ALL) ++ continue; ++ ++ /* FALLTHROUGH */ ++ ++ case GET_SHARED_PAGES: ++ case GET_TOTALRAM_PAGES: ++ if (vt->PG_reserved) ++ PG_reserved_flag = vt->PG_reserved; ++ else ++ PG_reserved_flag = v22 ? ++ 1 << v22_PG_reserved : ++ 1 << v24_PG_reserved; ++ ++ if (flags & PG_reserved_flag) { ++ reserved++; ++ } else { ++ if (count > 1) ++ shared++; ++ } ++ continue; ++ } ++ ++ page_mapping = VALID_MEMBER(page_mapping); ++ ++ if (v22) { ++ inode = ULONG(pcache + OFFSET(page_inode)); ++ offset = ULONG(pcache + OFFSET(page_offset)); ++ } else if (page_mapping) { ++ mapping = ULONG(pcache + ++ OFFSET(page_mapping)); ++ index = ULONG(pcache + OFFSET(page_index)); ++ } ++ ++ page_not_mapped = phys_not_mapped = FALSE; ++ ++ if (v22) { ++ fprintf(fp, "%lx%s%s%s%s%s%8lx %2d%s", ++ pp, ++ space(MINSPACE), ++ mkstring(buf1, MAX(PADDR_PRLEN, ++ strlen("PHYSICAL")), ++ RJUST|LONGLONG_HEX, MKSTR(&phys)), ++ space(MINSPACE), ++ mkstring(buf2, VADDR_PRLEN, ++ RJUST|LONG_HEX, MKSTR(inode)), ++ space(MINSPACE), ++ offset, ++ count, ++ space(MINSPACE)); ++ } else { ++ if ((vt->flags & V_MEM_MAP)) { ++ if (!machdep->verify_paddr(phys)) ++ phys_not_mapped = TRUE; ++ if (!kvtop(NULL, pp, NULL, 0)) ++ page_not_mapped = TRUE; ++ } ++ if (page_not_mapped) ++ fprintf(fp, "%s%s%s%s%s%s%s %2s ", ++ mkstring(buf0, VADDR_PRLEN, ++ LJUST|LONG_HEX, MKSTR(pp)), ++ space(MINSPACE), ++ mkstring(buf1, MAX(PADDR_PRLEN, ++ strlen("PHYSICAL")), ++ RJUST|LONGLONG_HEX, MKSTR(&phys)), ++ space(MINSPACE), ++ mkstring(buf3, VADDR_PRLEN, ++ CENTER|RJUST, " "), ++ space(MINSPACE), ++ mkstring(buf4, 8, CENTER|RJUST, " "), ++ " "); ++ else if (!page_mapping) ++ fprintf(fp, "%s%s%s%s%s%s%s %2d ", ++ mkstring(buf0, VADDR_PRLEN, ++ LJUST|LONG_HEX, MKSTR(pp)), ++ space(MINSPACE), ++ mkstring(buf1, MAX(PADDR_PRLEN, ++ strlen("PHYSICAL")), ++ RJUST|LONGLONG_HEX, MKSTR(&phys)), ++ space(MINSPACE), ++ mkstring(buf3, VADDR_PRLEN, ++ CENTER|RJUST, "-------"), ++ space(MINSPACE), ++ mkstring(buf4, 8, CENTER|RJUST, "-----"), ++ count); ++ else ++ fprintf(fp, "%s%s%s%s%s%s%8ld %2d ", ++ mkstring(buf0, VADDR_PRLEN, ++ LJUST|LONG_HEX, MKSTR(pp)), ++ space(MINSPACE), ++ mkstring(buf1, MAX(PADDR_PRLEN, ++ strlen("PHYSICAL")), ++ RJUST|LONGLONG_HEX, MKSTR(&phys)), ++ space(MINSPACE), ++ mkstring(buf2, VADDR_PRLEN, ++ RJUST|LONG_HEX, MKSTR(mapping)), ++ space(MINSPACE), ++ index, ++ count); ++ } ++ ++ others = 0; ++ ++ if (v22) { ++ if ((flags >> v22_PG_DMA) & 1) ++ fprintf(fp, "%sDMA", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_locked) & 1) ++ fprintf(fp, "%slocked", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_error) & 1) ++ fprintf(fp, "%serror", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_referenced) & 1) ++ fprintf(fp, "%sreferenced", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_dirty) & 1) ++ fprintf(fp, "%sdirty", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_uptodate) & 1) ++ fprintf(fp, "%suptodate", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_free_after) & 1) ++ fprintf(fp, "%sfree_after", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_decr_after) & 1) ++ fprintf(fp, "%sdecr_after", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_swap_unlock_after) & 1) ++ fprintf(fp, "%sswap_unlock_after", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_Slab) & 1) ++ fprintf(fp, "%sslab", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_swap_cache) & 1) ++ fprintf(fp, "%sswap_cache", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_skip) & 1) ++ fprintf(fp, "%sskip", ++ others++ ? "," : ""); ++ if ((flags >> v22_PG_reserved) & 1) ++ fprintf(fp, "%sreserved", ++ others++ ? "," : ""); ++ fprintf(fp, "\n"); ++ } else if (THIS_KERNEL_VERSION > LINUX(2,4,9)) { ++ fprintf(fp, "%lx\n", flags); ++ } else { ++ ++ if ((flags >> v24_PG_locked) & 1) ++ fprintf(fp, "%slocked", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_error) & 1) ++ fprintf(fp, "%serror", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_referenced) & 1) ++ fprintf(fp, "%sreferenced", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_uptodate) & 1) ++ fprintf(fp, "%suptodate", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_dirty) & 1) ++ fprintf(fp, "%sdirty", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_decr_after) & 1) ++ fprintf(fp, "%sdecr_after", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_active) & 1) ++ fprintf(fp, "%sactive", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_inactive_dirty) & 1) ++ fprintf(fp, "%sinactive_dirty", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_slab) & 1) ++ fprintf(fp, "%sslab", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_swap_cache) & 1) ++ fprintf(fp, "%sswap_cache", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_skip) & 1) ++ fprintf(fp, "%sskip", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_inactive_clean) & 1) ++ fprintf(fp, "%sinactive_clean", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_highmem) & 1) ++ fprintf(fp, "%shighmem", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_checked) & 1) ++ fprintf(fp, "%schecked", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_bigpage) & 1) ++ fprintf(fp, "%sbigpage", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_arch_1) & 1) ++ fprintf(fp, "%sarch_1", ++ others++ ? "," : ""); ++ if ((flags >> v24_PG_reserved) & 1) ++ fprintf(fp, "%sreserved", ++ others++ ? "," : ""); ++ if (phys_not_mapped) ++ fprintf(fp, "%s[NOT MAPPED]", ++ others++ ? " " : ""); ++ ++ fprintf(fp, "\n"); ++ } ++ ++ if (done) ++ break; ++ } ++ ++ if (done) ++ break; ++ } ++ ++ switch (mi->flags) ++ { ++ case GET_TOTALRAM_PAGES: ++ mi->retval = total_pages - reserved; ++ break; ++ ++ case GET_SHARED_PAGES: ++ mi->retval = shared; ++ break; ++ ++ case GET_BUFFERS_PAGES: ++ mi->retval = buffers; ++ break; ++ ++ case GET_SLAB_PAGES: ++ mi->retval = slabs; ++ break; ++ ++ case GET_ALL: ++ mi->get_totalram = total_pages - reserved; ++ mi->get_shared = shared; ++ mi->get_buffers = buffers; ++ mi->get_slabs = slabs; ++ break; ++ ++ case ADDRESS_SPECIFIED: ++ mi->retval = done; ++ break; ++ } ++ ++ FREEBUF(page_cache); ++} ++ ++/* ++ * Stash a chunk of PGMM_CACHED page structures, starting at addr, into the ++ * passed-in buffer. The mem_map array is normally guaranteed to be ++ * readable except in the case of virtual mem_map usage. When V_MEM_MAP ++ * is in place, read all pages consumed by PGMM_CACHED page structures ++ * that are currently mapped, leaving the unmapped ones just zeroed out. ++ */ ++static void ++fill_mem_map_cache(ulong pp, ulong ppend, char *page_cache) ++{ ++ long size, cnt; ++ ulong addr; ++ char *bufptr; ++ ++ /* ++ * Try to read it in one fell swoop. ++ */ ++ if (readmem(pp, KVADDR, page_cache, SIZE(page) * PGMM_CACHED, ++ "page struct cache", RETURN_ON_ERROR|QUIET)) ++ return; ++ ++ /* ++ * Break it into page-size-or-less requests, warning if it's ++ * not a virtual mem_map. ++ */ ++ size = SIZE(page) * PGMM_CACHED; ++ addr = pp; ++ bufptr = page_cache; ++ ++ while (size > 0) { ++ /* ++ * Compute bytes till end of page. ++ */ ++ cnt = PAGESIZE() - PAGEOFFSET(addr); ++ ++ if (cnt > size) ++ cnt = size; ++ ++ if (!readmem(addr, KVADDR, bufptr, size, ++ "virtual page struct cache", RETURN_ON_ERROR|QUIET)) { ++ BZERO(bufptr, size); ++ if (!(vt->flags & V_MEM_MAP) && ((addr+size) < ppend)) ++ error(WARNING, ++ "mem_map[] from %lx to %lx not accessible\n", ++ addr, addr+size); ++ } ++ ++ addr += cnt; ++ bufptr += cnt; ++ size -= cnt; ++ } ++} ++ ++ ++/* ++ * dump_page_hash_table() displays the entries in each page_hash_table. ++ */ ++ ++#define PGHASH_CACHED (1024) ++ ++static void ++dump_page_hash_table(struct meminfo *hi) ++{ ++ int i; ++ int len, entry_len; ++ ulong page_hash_table, head; ++ struct list_data list_data, *ld; ++ struct gnu_request req; ++ long total_cached; ++ long page_cache_size; ++ ulong this_addr, searchpage; ++ int errflag, found, cnt, populated, verbose; ++ uint ival; ++ ulong buffer_pages; ++ char buf[BUFSIZE]; ++ char hash_table[BUFSIZE]; ++ char *pcache, *pghash_cache; ++ ++ if (!vt->page_hash_table) { ++ if (hi->flags & VERBOSE) ++ error(FATAL, ++ "address_space page cache radix tree not supported\n"); + + if (symbol_exists("nr_pagecache")) { + buffer_pages = nr_blockdev_pages(); +@@ -4520,13 +5193,6 @@ */ static char *zone_hdr = "ZONE NAME SIZE FREE"; @@ -3905,7 +4634,7 @@ static void dump_free_pages_zones_v1(struct meminfo *fi) { -@@ -4610,7 +4832,7 @@ +@@ -4610,7 +5276,7 @@ } if (fi->flags == GET_FREE_HIGHMEM_PAGES) { @@ -3914,7 +4643,7 @@ readmem(node_zones+ OFFSET(zone_struct_free_pages), KVADDR, &value, sizeof(ulong), -@@ -4702,7 +4924,7 @@ +@@ -4702,7 +5368,7 @@ hq_close(); @@ -3923,7 +4652,25 @@ fi->retval = sum; return; } -@@ -4899,7 +5121,7 @@ +@@ -4828,7 +5494,8 @@ + int order, errflag, do_search; + ulong offset, verbose, value, sum, found; + ulong this_addr; +- physaddr_t this_phys, searchphys; ++ physaddr_t phys, this_phys, searchphys; ++ ulong pp; + ulong zone_mem_map; + ulong zone_start_paddr; + ulong zone_start_pfn; +@@ -4886,7 +5553,6 @@ + node_zones = nt->pgdat + OFFSET(pglist_data_node_zones); + + for (i = 0; i < vt->nr_zones; i++) { +- + if (fi->flags == GET_FREE_PAGES) { + readmem(node_zones+ + OFFSET(zone_free_pages), +@@ -4899,7 +5565,7 @@ } if (fi->flags == GET_FREE_HIGHMEM_PAGES) { @@ -3932,7 +4679,45 @@ readmem(node_zones+ OFFSET(zone_free_pages), KVADDR, &value, sizeof(ulong), -@@ -4997,7 +5219,7 @@ +@@ -4958,15 +5624,34 @@ + + fprintf(fp, "%6ld ", value); + +- readmem(node_zones+OFFSET(zone_zone_mem_map), +- KVADDR, &zone_mem_map, sizeof(ulong), +- "node_zones zone_mem_map", FAULT_ON_ERROR); ++ if (VALID_MEMBER(zone_zone_mem_map)) { ++ readmem(node_zones+OFFSET(zone_zone_mem_map), ++ KVADDR, &zone_mem_map, sizeof(ulong), ++ "node_zones zone_mem_map", FAULT_ON_ERROR); ++ } + + readmem(node_zones+ OFFSET(zone_zone_start_pfn), + KVADDR, &zone_start_pfn, sizeof(ulong), + "node_zones zone_start_pfn", FAULT_ON_ERROR); + zone_start_paddr = PTOB(zone_start_pfn); + ++ if (!VALID_MEMBER(zone_zone_mem_map)) { ++ if (IS_SPARSEMEM()) { ++ zone_mem_map = 0; ++ if (size) { ++ phys = PTOB(zone_start_pfn); ++ if (phys_to_page(phys, &pp)) ++ zone_mem_map = pp; ++ } ++ } else if (vt->flags & FLATMEM) { ++ zone_mem_map = 0; ++ if (size) ++ zone_mem_map = nt->mem_map + ++ (zone_start_pfn * SIZE(page)); ++ } else ++ error(FATAL, "\ncannot determine zone mem_map: TBD\n"); ++ } ++ + if (zone_mem_map) + zone_start_mapnr = + (zone_mem_map - nt->mem_map) / +@@ -4997,7 +5682,7 @@ hq_close(); @@ -3941,7 +4726,59 @@ fi->retval = sum; return; } -@@ -5519,17 +5741,18 @@ +@@ -5313,6 +5998,8 @@ + ulong freehighmem_pages; + ulong totallowmem_pages; + ulong freelowmem_pages; ++ long nr_file_pages, nr_slab; ++ ulong swapper_space_nrpages; + ulong pct; + ulong value1, value2; + uint tmp; +@@ -5334,6 +6021,14 @@ + get_buffers = meminfo.get_buffers; + get_slabs = meminfo.get_slabs; + ++ /* ++ * If vm_stat array exists, override page search info. ++ */ ++ if (vm_stat_init()) { ++ if (dump_vm_stat("NR_SLAB", &nr_slab)) ++ get_slabs = nr_slab; ++ } ++ + fprintf(fp, kmeminfo_hdr); + /* + * Get total RAM based upon how the various versions of si_meminfo() +@@ -5409,12 +6104,26 @@ + } else + get_symbol_data("page_cache_size", sizeof(long), + &page_cache_size); ++ page_cache_size -= subtract_buffer_pages; + } else if (symbol_exists("nr_pagecache")) { + get_symbol_data("nr_pagecache", sizeof(int), &tmp); + page_cache_size = (long)tmp; ++ page_cache_size -= subtract_buffer_pages; ++ } else if (dump_vm_stat("NR_FILE_PAGES", &nr_file_pages)) { ++ char *swapper_space = GETBUF(SIZE(address_space)); ++ ++ if (!readmem(symbol_value("swapper_space"), KVADDR, swapper_space, ++ SIZE(address_space), "swapper_space", RETURN_ON_ERROR)) ++ swapper_space_nrpages = 0; ++ else ++ swapper_space_nrpages = ULONG(swapper_space + ++ OFFSET(address_space_nrpages)); ++ ++ page_cache_size = nr_file_pages - swapper_space_nrpages - ++ buffer_pages; ++ FREEBUF(swapper_space); + } + +- page_cache_size -= subtract_buffer_pages; + + pct = (page_cache_size * 100)/totalram_pages; + fprintf(fp, "%10s %7ld %11s %3ld%% of TOTAL MEM\n", +@@ -5519,17 +6228,18 @@ ulong nrpages; char *block_device_buf, *inode_buf, *address_space_buf; @@ -3965,7 +4802,7 @@ hq_open(); bdevcnt = do_list(ld); bdevlist = (ulong *)GETBUF(bdevcnt * sizeof(ulong)); -@@ -5575,15 +5798,17 @@ +@@ -5575,15 +6285,17 @@ char buf1[BUFSIZE]; char buf2[BUFSIZE]; ulong vmlist; @@ -3985,7 +4822,7 @@ fprintf(fp, "%s ", mkstring(buf, MAX(strlen("VM_STRUCT"), VADDR_PRLEN), CENTER|LJUST, "VM_STRUCT")); -@@ -5599,6 +5824,20 @@ +@@ -5599,6 +6311,20 @@ &size, sizeof(ulong), "vmlist size", FAULT_ON_ERROR); @@ -4006,7 +4843,7 @@ if (!(vi->flags & ADDRESS_SPECIFIED) || ((vi->memtype == KVADDR) && ((vi->spec_addr >= addr) && (vi->spec_addr < (addr+size))))) -@@ -5639,7 +5878,7 @@ +@@ -5639,7 +6365,7 @@ } } @@ -4015,7 +4852,7 @@ readmem(next+OFFSET(vm_struct_next), KVADDR, &next, sizeof(void *), "vmlist next", FAULT_ON_ERROR); -@@ -5647,6 +5886,9 @@ +@@ -5647,6 +6373,9 @@ if (vi->flags & GET_HIGHEST) vi->retval = addr+size; @@ -4025,7 +4862,7 @@ } /* -@@ -6136,9 +6378,14 @@ +@@ -6136,9 +6865,14 @@ if (vt->flags & KMEM_CACHE_UNAVAIL) return; @@ -4040,7 +4877,7 @@ if (!strlen(slab_hdr)) sprintf(slab_hdr, "SLAB%sMEMORY%sTOTAL ALLOCATED FREE\n", -@@ -6177,9 +6424,11 @@ +@@ -6177,9 +6911,11 @@ if (!readmem(cache, KVADDR, cache_buf, SIZE(kmem_cache_s), "kmem_cache_s buffer", RETURN_ON_ERROR)) { @@ -4053,7 +4890,7 @@ return; } -@@ -6190,6 +6439,13 @@ +@@ -6190,6 +6926,13 @@ if ((tmp = max_cpudata_limit(cache, &tmp2)) > max_limit) max_limit = tmp; @@ -4067,7 +4904,7 @@ if (tmp2 > max_cpus) max_cpus = tmp2; -@@ -6237,6 +6493,8 @@ +@@ -6237,6 +6980,8 @@ NULL, 0); } @@ -4076,7 +4913,7 @@ vt->flags |= KMEM_CACHE_INIT; } -@@ -6250,25 +6508,32 @@ +@@ -6250,25 +6995,32 @@ ulong cpudata[NR_CPUS]; int limit; ulong max_limit; @@ -4122,7 +4959,7 @@ if (limit > max_limit) max_limit = limit; } -@@ -6279,22 +6544,89 @@ +@@ -6279,22 +7031,89 @@ kmem_cache_s_array: @@ -4219,7 +5056,7 @@ } /* -@@ -6353,6 +6685,7 @@ +@@ -6353,6 +7172,7 @@ #define KMEM_OBJECT_ADDR_INUSE (4) #define KMEM_OBJECT_ADDR_CACHED (5) #define KMEM_ON_SLAB (6) @@ -4227,7 +5064,7 @@ #define DUMP_KMEM_CACHE_INFO_V1() \ { \ -@@ -6408,7 +6741,7 @@ +@@ -6408,7 +7228,7 @@ { \ char b1[BUFSIZE], b2[BUFSIZE]; \ ulong allocated, freeobjs; \ @@ -4236,7 +5073,7 @@ allocated = si->s_inuse - si->cpucached_slab; \ freeobjs = si->c_num - allocated - si->cpucached_slab; \ } else { \ -@@ -6419,8 +6752,8 @@ +@@ -6419,8 +7239,8 @@ mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->slab)), \ mkstring(b2, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->s_mem)), \ si->c_num, allocated, \ @@ -4247,7 +5084,7 @@ } static void -@@ -6857,6 +7190,13 @@ +@@ -6857,6 +7677,13 @@ for (i = 0; i < vt->kmem_max_cpus; i++) si->cpudata[i] = (ulong *) GETBUF(vt->kmem_max_limit * sizeof(ulong)); @@ -4261,7 +5098,7 @@ cnt = 0; -@@ -6939,7 +7279,10 @@ +@@ -6939,7 +7766,10 @@ "kmem_cache_s num", FAULT_ON_ERROR); si->c_num = (ulong)tmp_val; @@ -4273,7 +5110,7 @@ if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) { DUMP_KMEM_CACHE_INFO_V2(); -@@ -6953,12 +7296,16 @@ +@@ -6953,12 +7783,16 @@ if (si->flags & (VERBOSE|ADDRESS_SPECIFIED)) { @@ -4292,7 +5129,7 @@ if (si->found) { fprintf(fp, kmem_cache_hdr); -@@ -7005,7 +7352,14 @@ +@@ -7005,7 +7839,14 @@ " %lx (cpu %d cache)\n", (ulong)si->spec_addr, si->cpu); break; @@ -4308,7 +5145,7 @@ break; } -@@ -7033,6 +7387,7 @@ +@@ -7033,6 +7874,7 @@ FREEBUF(si->kmem_bufctl); for (i = 0; i < vt->kmem_max_cpus; i++) FREEBUF(si->cpudata[i]); @@ -4316,15 +5153,80 @@ } -@@ -7638,68 +7993,293 @@ - } - } +@@ -7569,73 +8411,298 @@ + } while (si->slab != slab_chains[s] && !list_borked); + } --/* -- * Try to preclude any attempt to translate a bogus slab structure. -- */ --static int --verify_slab_v2(struct meminfo *si, ulong last, int s) +- FREEBUF(slab_buf); ++ FREEBUF(slab_buf); ++ if (!list_borked) ++ save_slab_data(si); ++ break; ++ ++ case SLAB_WALKTHROUGH: ++ specified_slab = si->slab; ++ si->flags |= SLAB_WALKTHROUGH; ++ si->flags &= ~SLAB_GET_COUNTS; ++ ++ for (s = 0; s < SLAB_CHAINS; s++) { ++ if (!slab_chains[s]) ++ continue; ++ ++ if (!specified_slab) { ++ if (!readmem(slab_chains[s], ++ KVADDR, &si->slab, sizeof(ulong), ++ "slabs", QUIET|RETURN_ON_ERROR)) { ++ error(INFO, ++ "%s: %s list: bad slab pointer: %lx\n", ++ si->curname, ++ slab_chain_name_v2[s], ++ slab_chains[s]); ++ list_borked = 1; ++ continue; ++ } ++ last = slab_chains[s]; ++ } else ++ last = 0; ++ ++ if (si->slab == slab_chains[s]) ++ continue; ++ ++ if (CRASHDEBUG(1)) { ++ fprintf(fp, "search cache: [%s] ", si->curname); ++ if (si->flags & ADDRESS_SPECIFIED) ++ fprintf(fp, "for %llx", si->spec_addr); ++ fprintf(fp, "\n"); ++ } ++ ++ do { ++ if (received_SIGINT()) ++ restart(0); ++ ++ if (!verify_slab_v2(si, last, s)) { ++ list_borked = 1; ++ continue; ++ } ++ last = si->slab - OFFSET(slab_list); ++ ++ dump_slab_percpu_v2(si); ++ ++ if (si->found) { ++ return; ++ } ++ ++ readmem(si->slab+OFFSET(slab_list), ++ KVADDR, &si->slab, sizeof(ulong), ++ "slab list", FAULT_ON_ERROR); ++ ++ si->slab -= OFFSET(slab_list); ++ ++ } while (si->slab != slab_chains[s] && !list_borked); ++ } ++ ++ break; ++ } ++} ++ + +/* +* Added To Traverse the Nodelists @@ -4332,13 +5234,7 @@ + +static void +do_slab_chain_percpu_v2_nodes(long cmd, struct meminfo *si) - { -- char slab_buf[BUFSIZE]; -- struct kernel_list_head *list_head; -- unsigned int inuse; -- ulong s_mem; -- char *list; -- int errcnt; ++{ + int i, tmp, s; + int list_borked; + char *slab_buf; @@ -4347,25 +5243,17 @@ + ulong slab_chains[SLAB_CHAINS]; + ulong *start_address; + int index; - -- list = slab_chain_name_v2[s]; ++ + list_borked = 0; + si->slabsize = (power(2, si->order) * PAGESIZE()); + si->cpucached_slab = 0; + start_address = (ulong *)GETBUF(sizeof(ulong) * vt->kmem_cache_len_nodes); - -- errcnt = 0; ++ + if (!readmem(si->cache+OFFSET(kmem_cache_s_lists), KVADDR, + &start_address[0], sizeof(ulong) * vt->kmem_cache_len_nodes, + "array nodelist array", RETURN_ON_ERROR)) + error(INFO, "cannot read kmem_cache nodelists array"); - -- if (!readmem(si->slab, KVADDR, slab_buf, -- SIZE(slab), "slab buffer", QUIET|RETURN_ON_ERROR)) { -- error(INFO, "%s: %s list: bad slab pointer: %lx\n", -- si->curname, list, si->slab); -- return FALSE; -- } ++ + switch (cmd) + { + case SLAB_GET_COUNTS: @@ -4387,15 +5275,7 @@ + fprintf(fp, "partial: %lx full: %lx free: %lx ]\n", + slab_chains[0], slab_chains[1], slab_chains[2]); + } - -- list_head = (struct kernel_list_head *)(slab_buf + OFFSET(slab_list)); -- if (!IS_KVADDR((ulong)list_head->next) || -- !accessible((ulong)list_head->next)) { -- error(INFO, "%s: %s list: slab: %lx bad next pointer: %lx\n", -- si->curname, list, si->slab, -- (ulong)list_head->next); -- errcnt++; -- } ++ + for (s = 0; s < SLAB_CHAINS; s++) { + if (!slab_chains[s]) + continue; @@ -4422,26 +5302,14 @@ + continue; + + last = slab_chains[s]; - -- if (last && (last != (ulong)list_head->prev)) { -- error(INFO, "%s: %s list: slab: %lx bad prev pointer: %lx\n", -- si->curname, list, si->slab, -- (ulong)list_head->prev); -- errcnt++; -- } ++ + do { + if (received_SIGINT()) { + FREEBUF(slab_buf); + FREEBUF(start_address); + restart(0); + } - -- inuse = UINT(slab_buf + OFFSET(slab_inuse)); -- if (inuse > si->c_num) { -- error(INFO, "%s: %s list: slab: %lx bad inuse counter: %ld\n", -- si->curname, list, si->slab, inuse); -- errcnt++; -- } ++ + if (!verify_slab_v2(si, last, s)) { + list_borked = 1; + continue; @@ -4457,9 +5325,7 @@ + + if (ACTIVE()) + gather_cpudata_list_v2_nodes(si, index); - -- if (!last) -- goto no_inuse_check_v2; ++ + si->s_mem = ULONG(slab_buf + + OFFSET(slab_s_mem)); + gather_slab_cached_count(si); @@ -4469,15 +5335,7 @@ + si->slab = ULONG(slab_buf + + OFFSET(slab_list)); + si->slab -= OFFSET(slab_list); - -- switch (s) -- { -- case 0: /* partial */ -- if ((inuse == 0) || (inuse == si->c_num)) { -- error(INFO, -- "%s: %s list: slab: %lx bad inuse counter: %ld\n", -- si->curname, list, si->slab, inuse); -- errcnt++; ++ + /* + * Check for slab transition. (Tony Dziedzic) + */ @@ -4494,18 +5352,17 @@ + + } while (si->slab != slab_chains[s] && !list_borked); + } - } -- break; - -- case 1: /* full */ -+ if (!list_borked) -+ save_slab_data(si); -+ break; ++ } + -+ case SLAB_WALKTHROUGH: + if (!list_borked) + save_slab_data(si); + break; + + case SLAB_WALKTHROUGH: +- specified_slab = si->slab; + specified_slab = si->slab; -+ si->flags |= SLAB_WALKTHROUGH; -+ si->flags &= ~SLAB_GET_COUNTS; + si->flags |= SLAB_WALKTHROUGH; + si->flags &= ~SLAB_GET_COUNTS; + slab_buf = GETBUF(SIZE(slab)); + for (index=0; (index < vt->kmem_cache_len_nodes) && start_address[index]; index++) + { @@ -4520,19 +5377,28 @@ + fprintf(fp, "partial: %lx full: %lx free: %lx ]\n", + slab_chains[0], slab_chains[1], slab_chains[2]); + } -+ + +- for (s = 0; s < SLAB_CHAINS; s++) { +- if (!slab_chains[s]) +- continue; + for (s = 0; s < SLAB_CHAINS; s++) { + if (!slab_chains[s]) + continue; -+ -+ if (!specified_slab) { -+ if (!readmem(slab_chains[s], + + if (!specified_slab) { + if (!readmem(slab_chains[s], +- KVADDR, &si->slab, sizeof(ulong), +- "slabs", QUIET|RETURN_ON_ERROR)) { +- error(INFO, +- "%s: %s list: bad slab pointer: %lx\n", + KVADDR, &si->slab, sizeof(ulong), + "slabs", QUIET|RETURN_ON_ERROR)) { + error(INFO, + "%s: %s list: bad slab pointer: %lx\n", -+ si->curname, -+ slab_chain_name_v2[s], + si->curname, + slab_chain_name_v2[s], +- slab_chains[s]); +- list_borked = 1; + slab_chains[s]); + list_borked = 1; + continue; @@ -4542,7 +5408,7 @@ + last = 0; + + if (si->slab == slab_chains[s]) -+ continue; + continue; + + readmem(si->slab, KVADDR, slab_buf, + SIZE(slab), "slab buffer", @@ -4556,8 +5422,24 @@ + if (si->flags & ADDRESS_SPECIFIED) + fprintf(fp, "for %llx", si->spec_addr); + fprintf(fp, "\n"); -+ } -+ + } +- last = slab_chains[s]; +- } else +- last = 0; +- +- if (si->slab == slab_chains[s]) +- continue; +- +- if (CRASHDEBUG(1)) { +- fprintf(fp, "search cache: [%s] ", si->curname); +- if (si->flags & ADDRESS_SPECIFIED) +- fprintf(fp, "for %llx", si->spec_addr); +- fprintf(fp, "\n"); +- } + +- do { +- if (received_SIGINT()) +- restart(0); + do { + if (received_SIGINT()) + { @@ -4565,7 +5447,22 @@ + FREEBUF(slab_buf); + restart(0); + } -+ + +- if (!verify_slab_v2(si, last, s)) { +- list_borked = 1; +- continue; +- } +- last = si->slab - OFFSET(slab_list); +- +- dump_slab_percpu_v2(si); +- +- if (si->found) { +- return; +- } +- +- readmem(si->slab+OFFSET(slab_list), +- KVADDR, &si->slab, sizeof(ulong), +- "slab list", FAULT_ON_ERROR); + if (!verify_slab_v2(si, last, s)) { + list_borked = 1; + continue; @@ -4579,89 +5476,27 @@ + FREEBUF(slab_buf); + return; + } -+ + +- si->slab -= OFFSET(slab_list); + readmem(si->slab+OFFSET(slab_list), + KVADDR, &si->slab, sizeof(ulong), + "slab list", FAULT_ON_ERROR); + + si->slab -= OFFSET(slab_list); -+ + +- } while (si->slab != slab_chains[s] && !list_borked); + } while (si->slab != slab_chains[s] && !list_borked); + } -+ } -+ -+ break; -+ } + } + + break; + } + FREEBUF(slab_buf); + FREEBUF(start_address); -+} -+ -+/* -+ * Try to preclude any attempt to translate a bogus slab structure. -+ */ -+static int -+verify_slab_v2(struct meminfo *si, ulong last, int s) -+{ -+ char slab_buf[BUFSIZE]; -+ struct kernel_list_head *list_head; -+ unsigned int inuse; -+ ulong s_mem; -+ char *list; -+ int errcnt; -+ -+ list = slab_chain_name_v2[s]; -+ -+ errcnt = 0; -+ -+ if (!readmem(si->slab, KVADDR, slab_buf, -+ SIZE(slab), "slab buffer", QUIET|RETURN_ON_ERROR)) { -+ error(INFO, "%s: %s list: bad slab pointer: %lx\n", -+ si->curname, list, si->slab); -+ return FALSE; -+ } -+ -+ list_head = (struct kernel_list_head *)(slab_buf + OFFSET(slab_list)); -+ if (!IS_KVADDR((ulong)list_head->next) || -+ !accessible((ulong)list_head->next)) { -+ error(INFO, "%s: %s list: slab: %lx bad next pointer: %lx\n", -+ si->curname, list, si->slab, -+ (ulong)list_head->next); -+ errcnt++; -+ } -+ -+ if (last && (last != (ulong)list_head->prev)) { -+ error(INFO, "%s: %s list: slab: %lx bad prev pointer: %lx\n", -+ si->curname, list, si->slab, -+ (ulong)list_head->prev); -+ errcnt++; -+ } -+ -+ inuse = UINT(slab_buf + OFFSET(slab_inuse)); -+ if (inuse > si->c_num) { -+ error(INFO, "%s: %s list: slab: %lx bad inuse counter: %ld\n", -+ si->curname, list, si->slab, inuse); -+ errcnt++; -+ } -+ -+ if (!last) -+ goto no_inuse_check_v2; -+ -+ switch (s) -+ { -+ case 0: /* partial */ -+ if ((inuse == 0) || (inuse == si->c_num)) { -+ error(INFO, -+ "%s: %s list: slab: %lx bad inuse counter: %ld\n", -+ si->curname, list, si->slab, inuse); -+ errcnt++; -+ } -+ break; -+ -+ case 1: /* full */ - if (inuse != si->c_num) { - error(INFO, - "%s: %s list: slab: %lx bad inuse counter: %ld\n", -@@ -7750,6 +8330,11 @@ + } + + /* +@@ -7750,6 +8817,11 @@ { int i; @@ -4673,7 +5508,7 @@ if (ACTIVE()) return; -@@ -7840,7 +8425,7 @@ +@@ -7840,7 +8912,7 @@ if (si->flags & ADDRESS_SPECIFIED) { if (INSLAB(si->slab, si) && (si->spec_addr >= si->slab) && @@ -4682,7 +5517,7 @@ si->found = KMEM_SLAB_ADDR; return; } -@@ -8213,7 +8798,7 @@ +@@ -8213,7 +9285,7 @@ */ if (si->c_flags & SLAB_CFLGS_BUFCTL) { @@ -4691,7 +5526,7 @@ obj = si->s_mem + ((next - si->s_index) * si->c_offset); DUMP_SLAB_OBJECT(); -@@ -8263,7 +8848,7 @@ +@@ -8263,7 +9335,7 @@ dump_slab_objects_percpu(struct meminfo *si) { int i, j; @@ -4700,7 +5535,7 @@ ulong cnt, expected; ulong obj; -@@ -8285,6 +8870,7 @@ +@@ -8285,6 +9357,7 @@ for (i = 0, obj = si->s_mem; i < si->c_num; i++, obj += si->size) { on_free_list = FALSE; on_cpudata_list = FALSE; @@ -4708,7 +5543,7 @@ for (j = 0; j < si->c_num; j++) { if (obj == si->addrlist[j]) { -@@ -8294,13 +8880,26 @@ +@@ -8294,13 +9367,26 @@ } on_cpudata_list = check_cpudata_list(si, obj); @@ -4736,7 +5571,7 @@ if (on_free_list) { if (!(si->flags & ADDRESS_SPECIFIED)) -@@ -8324,6 +8923,17 @@ +@@ -8324,6 +9410,17 @@ return; } } @@ -4754,7 +5589,7 @@ } else { if (!(si->flags & ADDRESS_SPECIFIED)) fprintf(fp, " [%lx]\n", obj); -@@ -8349,7 +8959,10 @@ +@@ -8349,7 +9446,10 @@ /* * Determine how many of the "inuse" slab objects are actually cached * in the kmem_cache_s header. Set the per-slab count and update the @@ -4766,7 +5601,7 @@ */ static void -@@ -8357,16 +8970,35 @@ +@@ -8357,16 +9457,35 @@ { int i; ulong obj; @@ -4802,7 +5637,7 @@ } } -@@ -8423,7 +9055,8 @@ +@@ -8423,7 +9542,8 @@ } /* @@ -4812,7 +5647,7 @@ */ static void gather_cpudata_list_v2(struct meminfo *si) -@@ -8431,6 +9064,7 @@ +@@ -8431,6 +9551,7 @@ int i, j; int avail; ulong cpudata[NR_CPUS]; @@ -4820,13 +5655,13 @@ readmem(si->cache+OFFSET(kmem_cache_s_array), KVADDR, &cpudata[0], -@@ -8466,8 +9100,152 @@ +@@ -8466,8 +9587,152 @@ if (CRASHDEBUG(2)) for (j = 0; j < avail; j++) - fprintf(fp, " %lx\n", si->cpudata[i][j]); + fprintf(fp, " %lx (cpu %d)\n", si->cpudata[i][j], i); - } ++ } + + /* + * If the shared list contains anything, gather them as well. @@ -4914,7 +5749,7 @@ + if (CRASHDEBUG(2)) + for (j = 0; j < avail; j++) + fprintf(fp, " %lx (cpu %d)\n", si->cpudata[i][j], i); -+ } + } + + /* + * If the shared list contains anything, gather them as well. @@ -4974,7 +5809,7 @@ } /* -@@ -8491,6 +9269,27 @@ +@@ -8491,6 +9756,27 @@ return FALSE; } @@ -5002,7 +5837,7 @@ /* * Search the various memory subsystems for instances of this address. -@@ -8690,6 +9489,16 @@ +@@ -8690,6 +9976,16 @@ physaddr_t pstart, pend; ulong node_size; @@ -5019,7 +5854,23 @@ for (n = 0; n < vt->numnodes; n++) { nt = &vt->node_table[n]; if ((vt->flags & V_MEM_MAP) && (vt->numnodes == 1)) -@@ -8797,6 +9606,17 @@ +@@ -8775,12 +10071,15 @@ + int i; + struct node_table *nt; + int others; ++ ulong *up; + + others = 0; + fprintf(fp, " flags: %lx %s(", + vt->flags, count_bits_long(vt->flags) > 4 ? "\n " : ""); + if (vt->flags & NODES) + fprintf(fp, "%sNODES", others++ ? "|" : ""); ++ if (vt->flags & NODES_ONLINE) ++ fprintf(fp, "%sNODES_ONLINE", others++ ? "|" : ""); + if (vt->flags & ZONES) + fprintf(fp, "%sZONES", others++ ? "|" : ""); + if (vt->flags & PERCPU_KMALLOC_V1) +@@ -8797,6 +10096,19 @@ fprintf(fp, "%sKMEM_CACHE_UNAVAIL", others++ ? "|" : ""); if (vt->flags & DISCONTIGMEM) fprintf(fp, "%sDISCONTIGMEM", others++ ? "|" : ""); @@ -5033,11 +5884,13 @@ + fprintf(fp, "%sKMEM_CACHE_DELAY", others++ ? "|" : "");\ + if (vt->flags & PERCPU_KMALLOC_V2_NODES) + fprintf(fp, "%sPERCPU_KMALLOC_V2_NODES", others++ ? "|" : "");\ ++ if (vt->flags & VM_STAT) ++ fprintf(fp, "%sVM_STAT", others++ ? "|" : "");\ + fprintf(fp, ")\n"); if (vt->kernel_pgd[0] == vt->kernel_pgd[1]) fprintf(fp, " kernel_pgd[NR_CPUS]: %lx ...\n", -@@ -8825,6 +9645,7 @@ +@@ -8825,6 +10137,7 @@ fprintf(fp, " kmem_max_cpus: %ld\n", vt->kmem_max_cpus); fprintf(fp, " kmem_cache_count: %ld\n", vt->kmem_cache_count); fprintf(fp, " kmem_cache_namelen: %d\n", vt->kmem_cache_namelen); @@ -5045,16 +5898,52 @@ fprintf(fp, " PG_reserved: %lx\n", vt->PG_reserved); fprintf(fp, " PG_slab: %ld\n", vt->PG_slab); fprintf(fp, " paddr_prlen: %d\n", vt->paddr_prlen); -@@ -8869,6 +9690,8 @@ +@@ -8834,12 +10147,12 @@ + for (i = 0; i < vt->numnodes; i++) { + nt = &vt->node_table[i]; + fprintf(fp, " node_table[%d]: \n", i); +- fprintf(fp, " id: %d\n", nt->node_id); +- fprintf(fp, " pgdat: %lx\n", nt->pgdat); +- fprintf(fp, " size: %ld\n", nt->size); +- fprintf(fp, " mem_map: %lx\n", nt->mem_map); +- fprintf(fp, " start_paddr: %llx\n", nt->start_paddr); +- fprintf(fp, " start_mapnr: %ld\n", nt->start_mapnr); ++ fprintf(fp, " id: %d\n", nt->node_id); ++ fprintf(fp, " pgdat: %lx\n", nt->pgdat); ++ fprintf(fp, " size: %ld\n", nt->size); ++ fprintf(fp, " mem_map: %lx\n", nt->mem_map); ++ fprintf(fp, " start_paddr: %llx\n", nt->start_paddr); ++ fprintf(fp, " start_mapnr: %ld\n", nt->start_mapnr); + } + + fprintf(fp, " dump_free_pages: "); +@@ -8869,6 +10182,25 @@ fprintf(fp, " nr_swapfiles: %d\n", vt->nr_swapfiles); fprintf(fp, " last_swap_read: %lx\n", vt->last_swap_read); fprintf(fp, " swap_info_struct: %lx\n", (ulong)vt->swap_info_struct); + fprintf(fp, " mem_sec: %lx\n", (ulong)vt->mem_sec); + fprintf(fp, " ZONE_HIGHMEM: %d\n", vt->ZONE_HIGHMEM); ++ fprintf(fp, "node_online_map_len: %d\n", vt->node_online_map_len); ++ if (vt->node_online_map_len) { ++ fprintf(fp, " node_online_map: "); ++ up = (ulong *)vt->node_online_map; ++ for (i = 0; i < vt->node_online_map_len; i++) { ++ fprintf(fp, "%s%lx", i ? ", " : "[", *up); ++ up++; ++ } ++ fprintf(fp, "]\n"); ++ } else { ++ fprintf(fp, " node_online_map: (unused)\n"); ++ } ++ fprintf(fp, " nr_vm_stat_items: %d\n", vt->nr_vm_stat_items); ++ fprintf(fp, " vm_stat_items: %s", (vt->flags & VM_STAT) ? ++ "\n" : "(not used)\n"); ++ for (i = 0; i < vt->nr_vm_stat_items; i++) ++ fprintf(fp, " [%d] %s\n", i, vt->vm_stat_items[i]); dump_vma_cache(VERBOSE); } -@@ -9321,6 +10144,43 @@ +@@ -9321,6 +10653,43 @@ } /* @@ -5098,7 +5987,7 @@ * Return the next kernel virtual address page that comes after * the passed-in address. */ -@@ -9348,6 +10208,8 @@ +@@ -9348,6 +10717,8 @@ if (IS_VMALLOC_ADDR(vaddr_orig)) { if (IS_VMALLOC_ADDR(vaddr) && (vaddr < vmalloc_limit)) { @@ -5107,7 +5996,7 @@ *nextvaddr = vaddr; return TRUE; } -@@ -9377,6 +10239,7 @@ +@@ -9377,6 +10748,7 @@ /* * We're in the physical range. */ @@ -5115,7 +6004,7 @@ return TRUE; } -@@ -9446,7 +10309,7 @@ +@@ -9446,7 +10818,7 @@ totalswap = totalused = 0; for (i = 0; i < vt->nr_swapfiles; i++, @@ -5124,7 +6013,7 @@ fill_swap_info(swap_info); flags = INT(vt->swap_info_struct + -@@ -9471,8 +10334,12 @@ +@@ -9471,8 +10843,12 @@ prio = INT(vt->swap_info_struct + OFFSET(swap_info_struct_prio)); @@ -5139,7 +6028,7 @@ swap_map = ULONG(vt->swap_info_struct + OFFSET(swap_info_struct_swap_map)); -@@ -9486,7 +10353,7 @@ +@@ -9486,7 +10862,7 @@ } else if (VALID_MEMBER (swap_info_struct_old_block_size)) { get_pathname(file_to_dentry(swap_file), @@ -5148,12 +6037,12 @@ } else { get_pathname(swap_file, buf, BUFSIZE, 1, 0); } -@@ -9741,13 +10608,13 @@ +@@ -9741,14 +11117,16 @@ dump_memory_nodes(int initialize) { int i, j; - int n, id, flen, slen; -+ int n, id, flen, slen, badaddr; ++ int n, id, node, flen, slen, badaddr; ulong node_mem_map; ulong node_start_paddr; ulong node_start_pfn; @@ -5162,9 +6051,12 @@ - ulong free_pages, zone_size, node_size; + ulong free_pages, zone_size, node_size, cum_zone_size; ulong zone_start_paddr, zone_start_mapnr, zone_mem_map; ++ physaddr_t phys; ++ ulong pp; ulong zone_start_pfn; ulong bdata; -@@ -9761,23 +10628,23 @@ + ulong pgdat; +@@ -9761,31 +11139,54 @@ char buf5[BUFSIZE]; struct node_table *nt; @@ -5185,12 +6077,7 @@ - nt->start_mapnr = 0; - return; - } -+ if (IS_SPARSEMEM() && !initialize) { -+ error(INFO,"Per node memory data is not available for this kernel\n"); -+ return; -+ } -+ -+ if (!(vt->flags & NODES) && initialize) { ++ if (!(vt->flags & (NODES|NODES_ONLINE)) && initialize) { + nt = &vt->node_table[0]; + nt->node_id = 0; + if (symbol_exists("contig_page_data")) @@ -5201,12 +6088,43 @@ + nt->mem_map = vt->mem_map; + nt->start_paddr = 0; + nt->start_mapnr = 0; ++ if (CRASHDEBUG(1)) { ++ fprintf(fp, "node_table[%d]: \n", 0); ++ fprintf(fp, " id: %d\n", nt->node_id); ++ fprintf(fp, " pgdat: %lx\n", nt->pgdat); ++ fprintf(fp, " size: %ld\n", nt->size); ++ fprintf(fp, " mem_map: %lx\n", nt->mem_map); ++ fprintf(fp, " start_paddr: %llx\n", nt->start_paddr); ++ fprintf(fp, " start_mapnr: %ld\n", nt->start_mapnr); ++ } + return; } - if (initialize) -@@ -9785,7 +10652,7 @@ - else +- if (initialize) +- get_symbol_data("pgdat_list", sizeof(void *), &pgdat); +- else ++ if (initialize) { ++ /* ++ * This order may have to change based upon architecture... ++ */ ++ if (symbol_exists("pgdat_list") && ++ (VALID_MEMBER(pglist_data_node_next) || ++ VALID_MEMBER(pglist_data_pgdat_next))) { ++ get_symbol_data("pgdat_list", sizeof(void *), &pgdat); ++ vt->flags &= ~NODES_ONLINE; ++ } else if (vt->flags & NODES_ONLINE) { ++ if ((node = next_online_node(0)) < 0) { ++ error(WARNING, ++ "cannot determine first node from node_online_map\n\n"); ++ return; ++ } ++ if (!(pgdat = next_online_pgdat(node))) { ++ error(WARNING, ++ "cannot determine pgdat list for this kernel/architecture\n\n"); ++ return; ++ } ++ } ++ } else pgdat = vt->node_table[0].pgdat; - for (n = 0; pgdat; n++) { @@ -5214,7 +6132,7 @@ if (n >= vt->numnodes) error(FATAL, "numnodes out of sync with pgdat_list?\n"); -@@ -9794,9 +10661,14 @@ +@@ -9794,9 +11195,14 @@ readmem(pgdat+OFFSET(pglist_data_node_id), KVADDR, &id, sizeof(int), "pglist node_id", FAULT_ON_ERROR); @@ -5232,15 +6150,56 @@ if (VALID_MEMBER(pglist_data_node_start_paddr)) readmem(pgdat+OFFSET(pglist_data_node_start_paddr), -@@ -9896,6 +10768,7 @@ +@@ -9808,6 +11214,11 @@ + "pglist node_start_pfn", FAULT_ON_ERROR); + node_start_mapnr = node_start_pfn; + node_start_paddr = PTOB(node_start_pfn); ++ if (badaddr && IS_SPARSEMEM()) { ++ phys = PTOB(node_start_pfn); ++ if (phys_to_page(phys, &pp)) ++ node_mem_map = pp; ++ } + } else error(INFO, + "cannot determine zone starting physical address\n"); + +@@ -9840,6 +11251,16 @@ + nt->mem_map = node_mem_map; + nt->start_paddr = node_start_paddr; + nt->start_mapnr = node_start_mapnr; ++ ++ if (CRASHDEBUG(1)) { ++ fprintf(fp, "node_table[%d]: \n", n); ++ fprintf(fp, " id: %d\n", nt->node_id); ++ fprintf(fp, " pgdat: %lx\n", nt->pgdat); ++ fprintf(fp, " size: %ld\n", nt->size); ++ fprintf(fp, " mem_map: %lx\n", nt->mem_map); ++ fprintf(fp, " start_paddr: %llx\n", nt->start_paddr); ++ fprintf(fp, " start_mapnr: %ld\n", nt->start_mapnr); ++ } + } + + if (!initialize) { +@@ -9896,9 +11317,10 @@ } node_zones = pgdat + OFFSET(pglist_data_node_zones); + cum_zone_size = 0; for (i = 0; i < vt->nr_zones; i++) { if (CRASHDEBUG(7)) - fprintf(fp, "zone at %lx\n", node_zones); -@@ -9926,12 +10799,24 @@ +- fprintf(fp, "zone at %lx\n", node_zones); ++ fprintf(fp, "zone %d at %lx\n", i, node_zones); + + if (VALID_MEMBER(zone_struct_size)) + readmem(node_zones+OFFSET(zone_struct_size), +@@ -9915,6 +11337,7 @@ + "zone spanned_pages", FAULT_ON_ERROR); + } else error(FATAL, + "zone_struct has neither size nor memsize field\n"); ++ + readmem(node_zones+ + OFFSET_OPTION(zone_struct_free_pages, + zone_free_pages), KVADDR, &free_pages, +@@ -9926,12 +11349,24 @@ if (!read_string(value, buf1, BUFSIZE-1)) sprintf(buf1, "(unknown) "); if (VALID_STRUCT(zone_struct)) { @@ -5271,12 +6230,21 @@ readmem(node_zones+ OFFSET(zone_struct_zone_start_mapnr), KVADDR, &zone_start_mapnr, -@@ -9946,7 +10831,14 @@ +@@ -9946,28 +11381,65 @@ "node_zones zone_start_pfn", FAULT_ON_ERROR); zone_start_paddr = PTOB(zone_start_pfn); - readmem(node_zones+ -+ if (!(vt->flags & NODES) && ++ ++ if (IS_SPARSEMEM()) { ++ zone_mem_map = 0; ++ zone_start_mapnr = 0; ++ if (zone_size) { ++ phys = PTOB(zone_start_pfn); ++ zone_start_mapnr = phys/PAGESIZE(); ++ } ++ ++ } else if (!(vt->flags & NODES) && + INVALID_MEMBER(zone_zone_mem_map)) { + readmem(pgdat+OFFSET(pglist_data_node_mem_map), + KVADDR, &zone_mem_map, sizeof(void *), @@ -5287,8 +6255,15 @@ OFFSET(zone_zone_mem_map), KVADDR, &zone_mem_map, sizeof(ulong), -@@ -9959,15 +10851,27 @@ - else + "node_zones zone_mem_map", + FAULT_ON_ERROR); ++ + if (zone_mem_map) + zone_start_mapnr = + (zone_mem_map - node_mem_map) / + SIZE(page); +- else ++ else if (!IS_SPARSEMEM()) zone_start_mapnr = 0; } - readmem(node_zones+ @@ -5296,7 +6271,15 @@ - zone_zone_mem_map), KVADDR, &zone_mem_map, - sizeof(ulong), "node_zones zone_mem_map", - FAULT_ON_ERROR); -+ if (!(vt->flags & NODES) && ++ ++ if (IS_SPARSEMEM()) { ++ zone_mem_map = 0; ++ if (zone_size) { ++ phys = PTOB(zone_start_pfn); ++ if (phys_to_page(phys, &pp)) ++ zone_mem_map = pp; ++ } ++ } else if (!(vt->flags & NODES) && + INVALID_MEMBER(zone_struct_zone_mem_map) && + INVALID_MEMBER(zone_zone_mem_map)) { + readmem(pgdat+OFFSET(pglist_data_node_mem_map), @@ -5320,7 +6303,46 @@ fprintf(fp, "%s %s %s\n", mkstring(buf1, VADDR_PRLEN, RJUST|LONG_HEX,MKSTR(zone_mem_map)), -@@ -10011,19 +10915,21 @@ +@@ -9981,12 +11453,22 @@ + node_zones += SIZE_OPTION(zone_struct, zone); + } + +- if (initialize) +- readmem(pgdat + OFFSET_OPTION(pglist_data_node_next, +- pglist_data_pgdat_next), KVADDR, +- &pgdat, sizeof(void *), "pglist_data node_next", +- FAULT_ON_ERROR); +- else { ++ if (initialize) { ++ if (vt->flags & NODES_ONLINE) { ++ if ((node = next_online_node(node+1)) < 0) ++ pgdat = 0; ++ else if (!(pgdat = next_online_pgdat(node))) { ++ error(WARNING, ++ "cannot determine pgdat list for this kernel/architecture (node %d)\n\n", ++ node); ++ pgdat = 0; ++ } ++ } else ++ readmem(pgdat + OFFSET_OPTION(pglist_data_node_next, ++ pglist_data_pgdat_next), KVADDR, ++ &pgdat, sizeof(void *), "pglist_data node_next", ++ FAULT_ON_ERROR); ++ } else { + if ((n+1) < vt->numnodes) + pgdat = vt->node_table[n+1].pgdat; + else +@@ -9996,6 +11478,9 @@ + + if (n != vt->numnodes) + error(FATAL, "numnodes out of sync with pgdat_list?\n"); ++ ++ if (!initialize && IS_SPARSEMEM()) ++ dump_mem_sections(); + } + + /* +@@ -10011,19 +11496,21 @@ * Override numnodes -- some kernels may leave it at 1 on a system * with multiple memory nodes. */ @@ -5355,7 +6377,7 @@ } if (!(vt->node_table = (struct node_table *) -@@ -10072,6 +10978,9 @@ +@@ -10072,6 +11559,9 @@ { uint psz; @@ -5365,7 +6387,7 @@ if (REMOTE_MEMSRC()) return remote_page_size(); -@@ -10081,6 +10990,14 @@ +@@ -10081,6 +11571,14 @@ psz = diskdump_page_size(); break; @@ -5380,7 +6402,7 @@ case NETDUMP: psz = netdump_page_size(); break; -@@ -10115,6 +11032,48 @@ +@@ -10115,6 +11613,48 @@ } /* @@ -5429,7 +6451,7 @@ * Return the vmalloc address referenced by the first vm_struct * on the vmlist. This can normally be used by the machine-specific * xxx_vmalloc_start() routines. -@@ -10127,6 +11086,9 @@ +@@ -10127,6 +11667,9 @@ get_symbol_data("vmlist", sizeof(void *), &vmlist); @@ -5439,7 +6461,7 @@ if (!readmem(vmlist+OFFSET(vm_struct_addr), KVADDR, &addr, sizeof(void *), "first vmlist addr", RETURN_ON_ERROR)) non_matching_kernel(); -@@ -10186,6 +11148,10 @@ +@@ -10186,6 +11729,10 @@ retval = remote_memory_used(); else if (pc->flags & NETDUMP) retval = netdump_memory_used(); @@ -5450,7 +6472,7 @@ else if (pc->flags & DISKDUMP) retval = diskdump_memory_used(); else if (pc->flags & LKCD) -@@ -10201,6 +11167,10 @@ +@@ -10201,6 +11748,10 @@ retval = remote_free_memory(); else if (pc->flags & NETDUMP) retval = netdump_free_memory(); @@ -5461,7 +6483,7 @@ else if (pc->flags & DISKDUMP) retval = diskdump_free_memory(); else if (pc->flags & LKCD) -@@ -10216,6 +11186,10 @@ +@@ -10216,6 +11767,10 @@ retval = remote_memory_dump(0); else if (pc->flags & NETDUMP) retval = netdump_memory_dump(fp); @@ -5472,7 +6494,7 @@ else if (pc->flags & DISKDUMP) retval = diskdump_memory_dump(fp); else if (pc->flags & LKCD) -@@ -10238,3 +11212,197 @@ +@@ -10238,3 +11793,536 @@ return retval; } @@ -5638,19 +6660,68 @@ +pfn_to_map(ulong pfn) +{ + ulong section, page_offset; ++ ulong section_nr; ++ ulong coded_mem_map, mem_map; + -+ section = pfn_to_section_nr(pfn); ++ section_nr = pfn_to_section_nr(pfn); ++ if (!(section = valid_section_nr(section_nr))) ++ return 0; + + if (section_has_mem_map(section)) { -+ page_offset = pfn - section_nr_to_pfn(section); -+ return (section_mem_map_addr(section) + -+ (page_offset * PAGESIZE())); ++ page_offset = pfn - section_nr_to_pfn(section_nr); ++ coded_mem_map = section_mem_map_addr(section); ++ mem_map = sparse_decode_mem_map(coded_mem_map, section_nr) + ++ (page_offset * SIZE(page)); ++ return mem_map; + } + + return 0; +} + +void ++dump_mem_sections(void) ++{ ++ ulong nr,addr; ++ ulong nr_mem_sections; ++ ulong coded_mem_map, mem_map, pfn; ++ char buf1[BUFSIZE]; ++ char buf2[BUFSIZE]; ++ char buf3[BUFSIZE]; ++ char buf4[BUFSIZE]; ++ ++ nr_mem_sections = NR_MEM_SECTIONS(); ++ ++ fprintf(fp, "\n"); ++ pad_line(fp, BITS32() ? 59 : 67, '-'); ++ fprintf(fp, "\n\nNR %s %s %s PFN\n", ++ mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "SECTION"), ++ mkstring(buf2, VADDR_PRLEN, CENTER|LJUST, "CODED_MEM_MAP"), ++ mkstring(buf3, VADDR_PRLEN, CENTER|LJUST, "MEM_MAP")); ++ ++ for (nr = 0; nr <= nr_mem_sections ; nr++) { ++ if ((addr = valid_section_nr(nr))) { ++ coded_mem_map = section_mem_map_addr(addr); ++ mem_map = sparse_decode_mem_map(coded_mem_map,nr); ++ pfn = section_nr_to_pfn(nr); ++ ++ fprintf(fp, "%2ld %s %s %s %s\n", ++ nr, ++ mkstring(buf1, VADDR_PRLEN, ++ CENTER|LONG_HEX, MKSTR(addr)), ++ mkstring(buf2, VADDR_PRLEN, ++ CENTER|LONG_HEX|RJUST, MKSTR(coded_mem_map)), ++ mkstring(buf3, VADDR_PRLEN, ++ CENTER|LONG_HEX|RJUST, MKSTR(mem_map)), ++ pc->output_radix == 10 ? ++ mkstring(buf4, VADDR_PRLEN, ++ LONG_DEC|LJUST, MKSTR(pfn)) : ++ mkstring(buf4, VADDR_PRLEN, ++ LONG_HEX|LJUST, MKSTR(pfn))); ++ } ++ } ++} ++ ++void +list_mem_sections(void) +{ + ulong nr,addr; @@ -5670,8 +6741,298 @@ + } + } +} ---- crash/filesys.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/filesys.c 2006-07-06 16:40:52.000000000 -0400 ++ ++/* ++ * For kernels containing the node_online_map, return ++ * the number of node bits set. ++ */ ++static int ++get_nodes_online(void) ++{ ++ int i, len, online; ++ struct gnu_request req; ++ ulong *maskptr; ++ ++ if (!symbol_exists("node_online_map")) ++ return 0; ++ ++ len = get_symbol_type("node_online_map", NULL, &req) == TYPE_CODE_UNDEF ? ++ sizeof(ulong) : req.length; ++ ++ if (!(vt->node_online_map = (ulong *)malloc(len))) ++ error(FATAL, "cannot malloc node_online_map\n"); ++ ++ if (!readmem(symbol_value("node_online_map"), KVADDR, ++ (void *)&vt->node_online_map[0], len, "node_online_map", ++ QUIET|RETURN_ON_ERROR)) ++ error(FATAL, "cannot read node_online_map\n"); ++ ++ vt->node_online_map_len = len/sizeof(ulong); ++ ++ online = 0; ++ ++ maskptr = (ulong *)vt->node_online_map; ++ for (i = 0; i < vt->node_online_map_len; i++, maskptr++) ++ online += count_bits_long(*maskptr); ++ ++ if (CRASHDEBUG(1)) { ++ fprintf(fp, "node_online_map: ["); ++ for (i = 0; i < vt->node_online_map_len; i++) ++ fprintf(fp, "%s%lx", i ? ", " : "", vt->node_online_map[i]); ++ fprintf(fp, "] -> nodes online: %d\n", online); ++ } ++ ++ return online; ++} ++ ++/* ++ * Return the next node index, with "first" being the first acceptable node. ++ */ ++static int ++next_online_node(int first) ++{ ++ int i, j, node; ++ ulong mask, *maskptr; ++ ++ if ((first/BITS_PER_LONG) >= vt->node_online_map_len) { ++ error(INFO, "next_online_node: %d is too large!\n", first); ++ return -1; ++ } ++ ++ maskptr = (ulong *)vt->node_online_map; ++ for (i = node = 0; i < vt->node_online_map_len; i++, maskptr++) { ++ mask = *maskptr; ++ for (j = 0; j < BITS_PER_LONG; j++, node++) { ++ if (mask & 1) { ++ if (node >= first) ++ return node; ++ } ++ mask >>= 1; ++ } ++ } ++ ++ return -1; ++} ++ ++/* ++ * Modify appropriately for architecture/kernel nuances. ++ */ ++static ulong ++next_online_pgdat(int node) ++{ ++ char buf[BUFSIZE]; ++ ulong pgdat; ++ ++ /* ++ * Default -- look for type: struct pglist_data node_data[] ++ */ ++ if (get_symbol_type("node_data", NULL, NULL) != TYPE_CODE_ARRAY) ++ goto pgdat2; ++ ++ open_tmpfile(); ++ sprintf(buf, "whatis node_data"); ++ if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) { ++ close_tmpfile(); ++ goto pgdat2; ++ } ++ rewind(pc->tmpfile); ++ while (fgets(buf, BUFSIZE, pc->tmpfile)) { ++ if (STRNEQ(buf, "type = ")) ++ break; ++ } ++ close_tmpfile(); ++ ++ if ((!strstr(buf, "struct pglist_data *") && ++ !strstr(buf, "pg_data_t *")) || ++ (count_chars(buf, '[') != 1) || ++ (count_chars(buf, ']') != 1)) ++ goto pgdat2; ++ ++ if (!readmem(symbol_value("node_data") + (node * sizeof(void *)), ++ KVADDR, &pgdat, sizeof(void *), "node_data", RETURN_ON_ERROR) || ++ !IS_KVADDR(pgdat)) ++ goto pgdat2; ++ ++ return pgdat; ++ ++pgdat2: ++ if (get_symbol_type("pgdat_list", NULL, NULL) != TYPE_CODE_ARRAY) ++ goto pgdat3; ++ ++ open_tmpfile(); ++ sprintf(buf, "whatis pgdat_list"); ++ if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) { ++ close_tmpfile(); ++ goto pgdat3; ++ } ++ rewind(pc->tmpfile); ++ while (fgets(buf, BUFSIZE, pc->tmpfile)) { ++ if (STRNEQ(buf, "type = ")) ++ break; ++ } ++ close_tmpfile(); ++ ++ if ((!strstr(buf, "struct pglist_data *") && ++ !strstr(buf, "pg_data_t *")) || ++ (count_chars(buf, '[') != 1) || ++ (count_chars(buf, ']') != 1)) ++ goto pgdat3; ++ ++ if (!readmem(symbol_value("pgdat_list") + (node * sizeof(void *)), ++ KVADDR, &pgdat, sizeof(void *), "pgdat_list", RETURN_ON_ERROR) || ++ !IS_KVADDR(pgdat)) ++ goto pgdat3; ++ ++ return pgdat; ++ ++pgdat3: ++ if (symbol_exists("contig_page_data") && (node == 0)) ++ return symbol_value("contig_page_data"); ++ ++ return 0; ++} ++ ++/* ++ * Make the vm_stat[] array contents easily accessible. ++ */ ++static int ++vm_stat_init(void) ++{ ++ char buf[BUFSIZE]; ++ char *arglist[MAXARGS]; ++ int i, c, stringlen, total; ++ struct gnu_request *req; ++ char *start; ++ ++ if (vt->flags & VM_STAT) ++ return TRUE; ++ ++ if ((vt->nr_vm_stat_items == -1) || !symbol_exists("vm_stat")) ++ goto bailout; ++ ++ /* ++ * look for type: type = atomic_long_t [] ++ */ ++ if (!symbol_exists("vm_stat") || ++ get_symbol_type("vm_stat", NULL, NULL) != TYPE_CODE_ARRAY) ++ goto bailout; ++ ++ open_tmpfile(); ++ sprintf(buf, "whatis vm_stat"); ++ if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) { ++ close_tmpfile(); ++ goto bailout; ++ } ++ rewind(pc->tmpfile); ++ while (fgets(buf, BUFSIZE, pc->tmpfile)) { ++ if (STRNEQ(buf, "type = ")) ++ break; ++ } ++ close_tmpfile(); ++ ++ if (!strstr(buf, "atomic_long_t") || ++ (count_chars(buf, '[') != 1) || ++ (count_chars(buf, ']') != 1)) ++ goto bailout; ++ ++ open_tmpfile(); ++ req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); ++ req->command = GNU_GET_DATATYPE; ++ req->name = "zone_stat_item"; ++ req->flags = GNU_PRINT_ENUMERATORS; ++ gdb_interface(req); ++ FREEBUF(req); ++ ++ stringlen = 1; ++ ++ rewind(pc->tmpfile); ++ while (fgets(buf, BUFSIZE, pc->tmpfile)) { ++ if (strstr(buf, "{") || strstr(buf, "}")) ++ continue; ++ clean_line(buf); ++ c = parse_line(buf, arglist); ++ if (STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) { ++ vt->nr_vm_stat_items = atoi(arglist[2]); ++ break; ++ } else ++ stringlen += strlen(arglist[0]); ++ } ++ ++ total = stringlen + vt->nr_vm_stat_items + ++ (sizeof(void *) * vt->nr_vm_stat_items); ++ if (!(vt->vm_stat_items = (char **)malloc(total))) { ++ close_tmpfile(); ++ error(FATAL, "cannot malloc vm_area_struct cache\n"); ++ } ++ ++ start = (char *)&vt->vm_stat_items[vt->nr_vm_stat_items]; ++ ++ rewind(pc->tmpfile); ++ while (fgets(buf, BUFSIZE, pc->tmpfile)) { ++ if (strstr(buf, "{") || strstr(buf, "}")) ++ continue; ++ c = parse_line(buf, arglist); ++ i = atoi(arglist[2]); ++ if (i < vt->nr_vm_stat_items) { ++ vt->vm_stat_items[i] = start; ++ strcpy(start, arglist[0]); ++ start += strlen(arglist[0]) + 1; ++ } ++ } ++ close_tmpfile(); ++ ++ vt->flags |= VM_STAT; ++ return TRUE; ++ ++bailout: ++ vt->nr_vm_stat_items = -1; ++ return FALSE; ++} ++ ++/* ++ * Either dump all vm_stat entries, or return the value of ++ * the specified vm_stat item. ++ */ ++static int ++dump_vm_stat(char *item, long *retval) ++{ ++ char *buf; ++ ulong *vp; ++ int i; ++ ++ if (!vm_stat_init()) { ++ if (!item) ++ error(FATAL, ++ "vm_stat not available in this kernel\n"); ++ return FALSE; ++ } ++ ++ buf = GETBUF(sizeof(ulong) * vt->nr_vm_stat_items); ++ ++ readmem(symbol_value("vm_stat"), KVADDR, buf, ++ sizeof(ulong) * vt->nr_vm_stat_items, ++ "vm_stat", FAULT_ON_ERROR); ++ ++ ++ if (!item) { ++ vp = (ulong *)buf; ++ for (i = 0; i < vt->nr_vm_stat_items; i++) ++ fprintf(fp, "%20s: %ld\n", vt->vm_stat_items[i], vp[i]); ++ return TRUE; ++ } ++ ++ vp = (ulong *)buf; ++ for (i = 0; i < vt->nr_vm_stat_items; i++) { ++ if (STREQ(vt->vm_stat_items[i], item)) { ++ *retval = vp[i]; ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} +--- crash/filesys.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/filesys.c 2006-07-06 16:46:08.000000000 -0400 @@ -1,8 +1,8 @@ /* filesys.c - core analysis suite * @@ -5920,8 +7281,8 @@ * get_pathname() fills in a pathname string for an ending dentry * See __d_path() in the kernel for help fixing problems. */ ---- crash/help.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/help.c 2006-08-03 16:59:00.000000000 -0400 +--- crash/help.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/help.c 2006-08-29 17:03:09.000000000 -0400 @@ -1,8 +1,8 @@ /* help.c - core analysis suite * @@ -6136,7 +7497,58 @@ "\nEXAMPLES", " Note that each task_struct is linked to its parent's task_struct via the", " p_pptr member:", -@@ -4419,10 +4460,11 @@ +@@ -3555,7 +3596,7 @@ + char *help_kmem[] = { + "kmem", + "kernel memory", +-"[-f|-F|-p|-c|-C|-i|-s|-S|-v|-n] [-[l|L][a|i]] [slab-name] [[-P] address]", ++"[-f|-F|-p|-c|-C|-i|-s|-S|-v|-V|-n] [-[l|L][a|i]] [slab] [[-P] address]", + " This command displays information about the use of kernel memory.\n", + " -f displays the contents of the system free memory headers.", + " also verifies that the page count equals nr_free_pages.", +@@ -3569,13 +3610,14 @@ + " -S displays all kmalloc() slab data, including all slab objects,", + " and whether each object is in use or is free.", + " -v displays the vmlist entries.", ++" -V displays the kernel vm_stat table.", + " -n display memory node data (if supported).", + " -la walks through the active_list and verifies nr_active_pages.", + " -li walks through the inactive_list and verifies nr_inactive_pages.", + " -La same as -la, but also dumps each page in the active_list.", + " -Li same as -li, but also dumps each page in the inactive_list.", +-" slab-name when used with -s or -S, limits the command to only the slab cache", +-" of name \"slab-name\". If the slab-name argument is \"list\", then", ++" slab when used with -s or -S, limits the command to only the slab cache", ++" of name \"slab\". If the slab argument is \"list\", then", + " all slab cache names and addresses are listed.", + " -P declares that the following address argument is a physical address.", + " address when used without any flag, the address can be a kernel virtual,", +@@ -3781,6 +3823,24 @@ + " c2f8ab60 c8095000 - c8097000 8192", + " c2f519e0 c8097000 - c8099000 8192", + " ", ++" Dump the vm_table contents:\n", ++" %s> kmem -V", ++" NR_ANON_PAGES: 38989", ++" NR_FILE_MAPPED: 3106", ++" NR_FILE_PAGES: 169570", ++" NR_SLAB: 32439", ++" NR_PAGETABLE: 1181", ++" NR_FILE_DIRTY: 4633", ++" NR_WRITEBACK: 0", ++" NR_UNSTABLE_NFS: 0", ++" NR_BOUNCE: 0", ++" NUMA_HIT: 63545992", ++" NUMA_MISS: 0", ++" NUMA_FOREIGN: 0", ++" NUMA_INTERLEAVE_HIT: 24002", ++" NUMA_LOCAL: 63545992", ++" NUMA_OTHER: 0", ++" ", + " Determine (and verify) the page cache size:\n", + " %s> kmem -c", + " page_cache_size: 18431 (verified)", +@@ -4419,10 +4479,11 @@ " Display various network related data:\n", " -a display the ARP cache.", " -s display open network socket/sock addresses, their family and type,", @@ -6150,7 +7562,7 @@ " value into a standard numbers-and-dots notation.", " -R ref socket or sock address, or file descriptor.", " pid a process PID.", -@@ -4450,8 +4492,8 @@ +@@ -4450,8 +4511,8 @@ " Display the sockets for PID 2517, using both -s and -S output formats:\n", " %s> net -s 2517", " PID: 2517 TASK: c1598000 CPU: 1 COMMAND: \"rlogin\"", @@ -6161,7 +7573,7 @@ " ", " %s> net -S 2517", " PID: 2517 TASK: c1598000 CPU: 1 COMMAND: \"rlogin\"", -@@ -4497,52 +4539,52 @@ +@@ -4497,52 +4558,52 @@ " From \"foreach\", find all tasks with references to socket c08ea3cc:\n", " %s> foreach net -s -R c08ea3cc", " PID: 2184 TASK: c7026000 CPU: 1 COMMAND: \"klines.kss\"", @@ -6238,7 +7650,7 @@ " ", NULL }; -@@ -4854,9 +4896,11 @@ +@@ -4854,9 +4915,11 @@ static char *version_info[] = { @@ -6253,8 +7665,8 @@ "Copyright (C) 1999, 2002 Silicon Graphics, Inc.", "Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.", "This program is free software, covered by the GNU General Public License,", ---- crash/task.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/task.c 2006-06-26 09:13:03.000000000 -0400 +--- crash/task.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/task.c 2006-09-06 15:53:39.000000000 -0400 @@ -27,6 +27,7 @@ static void refresh_pidhash_task_table(void); static void refresh_pid_hash_task_table(void); @@ -6263,7 +7675,15 @@ static struct task_context *store_context(struct task_context *, ulong, char *); static void refresh_context(ulong, ulong); static void parent_list(ulong); -@@ -193,6 +194,8 @@ +@@ -49,6 +50,7 @@ + static void task_struct_member(struct task_context *,ulong,struct reference *); + static void signal_reference(struct task_context *, ulong, struct reference *); + static void dump_signal_data(struct task_context *); ++static int sigrt_minmax(int *, int *); + static void signame_list(void); + static ulonglong task_signal(ulong); + static ulonglong task_blocked(ulong); +@@ -193,6 +195,8 @@ MEMBER_OFFSET_INIT(pid_link_pid, "pid_link", "pid"); MEMBER_OFFSET_INIT(pid_hash_chain, "pid", "hash_chain"); @@ -6272,7 +7692,7 @@ MEMBER_OFFSET_INIT(pid_pid_chain, "pid", "pid_chain"); STRUCT_SIZE_INIT(task_struct, "task_struct"); -@@ -219,15 +222,7 @@ +@@ -219,15 +223,7 @@ MEMBER_OFFSET_INIT(sigpending_signal, "sigpending", "signal"); STRUCT_SIZE_INIT(sigqueue, "sigqueue"); @@ -6289,7 +7709,7 @@ STRUCT_SIZE_INIT(sighand_struct, "sighand_struct"); if (VALID_STRUCT(sighand_struct)) -@@ -249,6 +244,19 @@ +@@ -249,6 +245,19 @@ STRUCT_SIZE_INIT(cputime_t, "cputime_t"); @@ -6309,7 +7729,7 @@ if (VALID_MEMBER(runqueue_arrays)) MEMBER_OFFSET_INIT(task_struct_run_list, "task_struct", "run_list"); -@@ -302,7 +310,11 @@ +@@ -302,7 +311,11 @@ tt->refresh_task_table = refresh_pid_hash_task_table; } else { tt->pidhash_addr = symbol_value("pid_hash"); @@ -6322,7 +7742,7 @@ } tt->flags |= PID_HASH; -@@ -987,9 +999,7 @@ +@@ -987,9 +1000,7 @@ return; if (DUMPFILE()) { /* impossible */ @@ -6333,7 +7753,7 @@ if (!symbol_exists("panic_threads")) tt->flags |= POPULATE_PANIC; } -@@ -1152,11 +1162,7 @@ +@@ -1152,11 +1163,7 @@ FREEBUF(pid_hash); @@ -6346,7 +7766,7 @@ if (ACTIVE() && (tt->flags & TASK_INIT_DONE)) refresh_context(curtask, curpid); -@@ -1192,9 +1198,7 @@ +@@ -1192,9 +1199,7 @@ return; if (DUMPFILE()) { /* impossible */ @@ -6357,7 +7777,7 @@ if (!symbol_exists("panic_threads")) tt->flags |= POPULATE_PANIC; } -@@ -1394,12 +1398,229 @@ +@@ -1394,12 +1399,229 @@ FREEBUF(pid_hash); FREEBUF(nodebuf); @@ -6458,8 +7878,8 @@ + else + error(WARNING, "%sduplicate idle tasks?\n", + DUMPFILE() ? "\n" : ""); - } - ++ } ++ + for (i = 0; i < len; i++) { + if (!pid_hash[i]) + continue; @@ -6535,8 +7955,8 @@ + console(" chained task: %lx (node: %lx) next: %lx pprev: %lx\n", + next, kpp, pnext, pprev); + } -+ } -+ + } + + BZERO(tt->task_local, tt->max_tasks * sizeof(void *)); + cnt = retrieve_list((ulong *)tt->task_local, cnt); + @@ -6591,7 +8011,7 @@ if (ACTIVE() && (tt->flags & TASK_INIT_DONE)) refresh_context(curtask, curpid); -@@ -2229,11 +2450,8 @@ +@@ -2229,11 +2451,8 @@ use_kernel_timeval = STRUCT_EXISTS("kernel_timeval"); get_symbol_data("jiffies", sizeof(long), &jiffies); @@ -6605,7 +8025,7 @@ tsp = task_start_times; tc = tcp ? tcp : FIRST_CONTEXT(); -@@ -2330,8 +2548,7 @@ +@@ -2330,8 +2549,7 @@ for (i = 0, tsp = task_start_times; i < tasks; i++, tsp++) { print_task_header(fp, tsp->tc, 0); fprintf(fp, " RUN TIME: %s\n", symbol_exists("jiffies_64") ? @@ -6615,7 +8035,7 @@ convert_time(jiffies - tsp->start_time, buf1)); fprintf(fp, " START TIME: %llu\n", tsp->start_time); if (VALID_MEMBER(task_struct_times)) { -@@ -2397,15 +2614,33 @@ +@@ -2397,15 +2615,33 @@ static ulonglong convert_start_time(ulonglong start_time, ulonglong current) { @@ -6652,7 +8072,7 @@ default: break; } -@@ -2938,12 +3173,17 @@ +@@ -2938,12 +3174,17 @@ if (is_task_active(tc->task)) { if (machdep->flags & HWRESET) fprintf(fp, "(HARDWARE RESET)"); @@ -6672,7 +8092,7 @@ else if (tc->task == tt->panic_task) fprintf(fp, "(PANIC)"); else -@@ -3411,6 +3651,9 @@ +@@ -3411,6 +3652,9 @@ use_task_0: @@ -6682,7 +8102,7 @@ tt->flags |= PANIC_TASK_NOT_FOUND; tc = FIRST_CONTEXT(); return(tc->task); -@@ -3448,49 +3691,68 @@ +@@ -3448,49 +3692,68 @@ int msg_found; BZERO(buf, BUFSIZE); @@ -6786,7 +8206,7 @@ return(buf); } -@@ -3517,7 +3779,7 @@ +@@ -3517,7 +3780,7 @@ BZERO(&foreach_data, sizeof(struct foreach_data)); fd = &foreach_data; @@ -6795,7 +8215,7 @@ switch(c) { case 'R': -@@ -3560,6 +3822,10 @@ +@@ -3560,6 +3823,10 @@ fd->flags |= FOREACH_r_FLAG; break; @@ -6806,7 +8226,7 @@ case 't': fd->flags |= FOREACH_t_FLAG; break; -@@ -3962,7 +4228,12 @@ +@@ -3962,7 +4229,12 @@ bt->flags |= BT_SYMBOLIC_ARGS; if (fd->flags & FOREACH_t_FLAG) bt->flags |= BT_TEXT_SYMBOLS; @@ -6820,7 +8240,7 @@ bt->flags |= BT_OLD_BACK_TRACE; if (fd->flags & FOREACH_e_FLAG) bt->flags |= BT_EFRAME_SEARCH; -@@ -4188,6 +4459,12 @@ +@@ -4188,6 +4460,12 @@ break; } @@ -6833,7 +8253,7 @@ if (strstr(buf, " die at ")) { switch (dietask) { -@@ -4211,6 +4488,10 @@ +@@ -4211,6 +4489,10 @@ if (dietask == (NO_TASK+1)) error(WARNING, "multiple active tasks have called die\n\n"); @@ -6844,7 +8264,7 @@ found_panic_task: populate_panic_threads(); -@@ -4229,6 +4510,9 @@ +@@ -4229,6 +4511,9 @@ } } @@ -6854,7 +8274,7 @@ return NULL; } -@@ -4240,25 +4524,28 @@ +@@ -4240,25 +4525,28 @@ { ulong task; @@ -6894,7 +8314,7 @@ return NO_TASK; } -@@ -4298,14 +4585,17 @@ +@@ -4298,14 +4586,17 @@ tc = FIRST_CONTEXT(); for (i = 0; i < RUNNING_TASKS(); i++, tc++) { @@ -6914,7 +8334,7 @@ tt->panic_threads[0] = get_dumpfile_panic_task(); } -@@ -4331,7 +4621,7 @@ +@@ -4331,7 +4622,7 @@ void dump_task_table(int verbose) { @@ -6923,7 +8343,7 @@ struct task_context *tc; char buf[BUFSIZE]; int others, wrap, flen; -@@ -4363,6 +4653,8 @@ +@@ -4363,6 +4654,8 @@ fprintf(fp, "refresh_pid_hash_task_table()\n"); else if (tt->refresh_task_table == refresh_hlist_task_table) fprintf(fp, "refresh_hlist_task_table()\n"); @@ -6932,7 +8352,7 @@ else fprintf(fp, "%lx\n", (ulong)tt->refresh_task_table); -@@ -4443,7 +4735,9 @@ +@@ -4443,7 +4736,9 @@ wrap = sizeof(void *) == SIZEOF_32BIT ? 8 : 4; flen = sizeof(void *) == SIZEOF_32BIT ? 8 : 16; @@ -6943,7 +8363,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->panic_threads[i]); -@@ -4451,7 +4745,7 @@ +@@ -4451,7 +4746,7 @@ fprintf(fp, "\n"); fprintf(fp, " panic_ksp:"); @@ -6952,7 +8372,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->panic_ksp[i]); -@@ -4459,7 +4753,7 @@ +@@ -4459,7 +4754,7 @@ fprintf(fp, "\n"); fprintf(fp, " hardirq_ctx:"); @@ -6961,7 +8381,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->hardirq_ctx[i]); -@@ -4467,7 +4761,7 @@ +@@ -4467,7 +4762,7 @@ fprintf(fp, "\n"); fprintf(fp, " hardirq_tasks:"); @@ -6970,7 +8390,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->hardirq_tasks[i]); -@@ -4475,7 +4769,7 @@ +@@ -4475,7 +4770,7 @@ fprintf(fp, "\n"); fprintf(fp, " softirq_ctx:"); @@ -6979,7 +8399,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->softirq_ctx[i]); -@@ -4483,7 +4777,7 @@ +@@ -4483,7 +4778,7 @@ fprintf(fp, "\n"); fprintf(fp, " softirq_tasks:"); @@ -6988,7 +8408,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->softirq_tasks[i]); -@@ -4491,7 +4785,7 @@ +@@ -4491,7 +4786,7 @@ fprintf(fp, "\n"); fprintf(fp, " idle_threads:"); @@ -6997,7 +8417,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->idle_threads[i]); -@@ -4499,7 +4793,7 @@ +@@ -4499,7 +4794,7 @@ fprintf(fp, "\n"); fprintf(fp, " active_set:"); @@ -7006,7 +8426,7 @@ if ((i % wrap) == 0) fprintf(fp, "\n "); fprintf(fp, "%.*lx ", flen, tt->active_set[i]); -@@ -4799,23 +5093,47 @@ +@@ -4799,23 +5094,47 @@ tt->flags &= ~ACTIVE_SET; } @@ -7069,7 +8489,7 @@ while (fgets(buf, BUFSIZE, pc->tmpfile)) { \ if (strstr(buf, " die+")) { \ switch (die_task) \ -@@ -4833,12 +5151,23 @@ +@@ -4833,12 +5152,23 @@ { \ case NO_TASK: \ panic_task = task; \ @@ -7093,7 +8513,7 @@ } /* -@@ -4850,11 +5179,12 @@ +@@ -4850,11 +5180,12 @@ int i, j, found; ulong task; char buf[BUFSIZE]; @@ -7108,7 +8528,7 @@ for (i = 0; i < NR_CPUS; i++) { if (!(task = tt->active_set[i])) -@@ -4875,7 +5205,7 @@ +@@ -4875,7 +5206,7 @@ raw_stack_dump(GET_STACKBASE(task), STACKSIZE()); rewind(pc->tmpfile); @@ -7117,7 +8537,7 @@ close_tmpfile(); } -@@ -4903,7 +5233,7 @@ +@@ -4903,7 +5234,7 @@ raw_stack_dump(tt->hardirq_ctx[i], SIZE(thread_union)); rewind(pc->tmpfile); @@ -7126,7 +8546,7 @@ close_tmpfile(); } -@@ -4930,7 +5260,7 @@ +@@ -4930,7 +5261,7 @@ raw_stack_dump(tt->softirq_ctx[i], SIZE(thread_union)); rewind(pc->tmpfile); @@ -7135,7 +8555,7 @@ close_tmpfile(); } -@@ -4938,6 +5268,20 @@ +@@ -4938,6 +5269,20 @@ RESOLVE_PANIC_AND_DIE_CALLERS(); } @@ -7156,7 +8576,156 @@ return NO_TASK; } -@@ -5416,6 +5760,15 @@ +@@ -5174,6 +5519,9 @@ + #define _NSIG_BPW machdep->bits + #define _NSIG_WORDS (_NSIG / _NSIG_BPW) + ++#undef SIGRTMIN ++#define SIGRTMIN 32 ++ + static struct signame { + char *name; + char *altname; +@@ -5209,23 +5557,56 @@ + /* 28 */ {"SIGWINCH", NULL}, + /* 29 */ {"SIGIO", "SIGPOLL"}, + /* 30 */ {"SIGPWR", NULL}, +- /* 31 */ {"SIGSYS", NULL}, ++ /* 31 */ {"SIGSYS", "SIGUNUSED"}, + {NULL, NULL}, /* Real time signals start here. */ + }; + ++static int ++sigrt_minmax(int *min, int *max) ++{ ++ int sigrtmax, j; ++ ++ sigrtmax = THIS_KERNEL_VERSION < LINUX(2,5,0) ? ++ _NSIG - 1 : _NSIG; ++ ++ if (min && max) { ++ j = sigrtmax-SIGRTMIN-1; ++ *max = j / 2; ++ *min = j - *max; ++ } ++ ++ return sigrtmax; ++} ++ + static void + signame_list(void) + { +- int i; ++ int i, sigrtmax, j, min, max; + +- for (i = 0; i < _NSIG; i++) { +- if (!signame[i].name) +- continue; ++ sigrtmax = sigrt_minmax(&min, &max); ++ j = 1; ++ ++ for (i = 1; i <= sigrtmax; i++) { ++ if ((i == SIGRTMIN) || (i == sigrtmax)) { ++ fprintf(fp, "[%d] %s", i, ++ (i== SIGRTMIN) ? "SIGRTMIN" : "SIGRTMAX"); ++ } else if (i > SIGRTMIN) { ++ if (j <= min){ ++ fprintf(fp, "[%d] %s%d", i , "SIGRTMIN+", j); ++ j++; ++ } else if (max >= 1) { ++ fprintf(fp, "[%d] %s%d", i , "SIGRTMAX-",max); ++ max--; ++ } ++ } else { ++ if (!signame[i].name) ++ continue; + +- fprintf(fp, "%s[%d] %s", i < 10 ? " " : "", +- i, signame[i].name); +- if (signame[i].altname) +- fprintf(fp, "/%s", signame[i].altname); ++ fprintf(fp, "%s[%d] %s", i < 10 ? " " : "", ++ i, signame[i].name); ++ if (signame[i].altname) ++ fprintf(fp, "/%s", signame[i].altname); ++ } + fprintf(fp, "\n"); + } + } +@@ -5236,8 +5617,7 @@ + static void + translate_sigset(ulonglong sigset) + { +- int i, c, bit, len; +- ulonglong mask, sig; ++ int sigrtmax, min, max, i, j, c, len; + char buf[BUFSIZE]; + + if (!sigset) { +@@ -5246,21 +5626,42 @@ + } + + len = 0; ++ sigrtmax= sigrt_minmax(&min, &max); ++ j = 1; ++ ++ for (i = 1, c = 0; i <= sigrtmax; i++) { ++ if (sigset & (ulonglong)1) { ++ if (i == SIGRTMIN || i == sigrtmax) ++ sprintf(buf, "%s%s", c++ ? " " : "", ++ (i==SIGRTMIN) ? "SIGRTMIN" : "SIGRTMAX"); ++ else if (i > SIGRTMIN) { ++ if (j <= min) ++ sprintf(buf, "%s%s%d", ++ c++ ? " " : "", "SIGRTMIN+", j); ++ else if (max >= 1) ++ sprintf(buf, "%s%s%d", ++ c++ ? " " : "", "SIGRTMAX-", max); ++ } else ++ sprintf(buf, "%s%s", c++ ? " " : "", ++ signame[i].name); + +- for (i = c = 0; i < (_NSIG/2); i++) { +- mask = (ulong)(1) << i; +- if ((sig = (sigset & mask))) { +- bit = ffs((int)sig); +- sprintf(buf, "%s%s", c++ ? " " : "", +- signame[bit].name); + if ((len + strlen(buf)) > 80) { + shift_string_left(buf, 1); + fprintf(fp, "\n"); + len = 0; + } ++ + len += strlen(buf); + fprintf(fp, buf); + } ++ ++ sigset >>= 1; ++ if (i > SIGRTMIN) { ++ if (j <= min) ++ j++; ++ else if (max >= 1) ++ max--; ++ } + } + fprintf(fp, "\n"); + } +@@ -5403,11 +5804,11 @@ + static void + dump_signal_data(struct task_context *tc) + { +- int i, others, use_sighand; ++ int i, sigrtmax, others, use_sighand; + int translate, sig, sigpending; + uint ti_flags; + ulonglong sigset, blocked, mask; +- ulong signal_struct, kaddr, handler, flags, sigqueue, next; ++ ulong signal_struct, kaddr, handler, flags, sigqueue, sigqueue_save, next; + ulong sighand_struct; + long size; + char *signal_buf, *uaddr; +@@ -5416,6 +5817,15 @@ char buf3[BUFSIZE]; char buf4[BUFSIZE]; @@ -7172,8 +8741,38 @@ sigset = task_signal(tc->task); if (!tt->last_task_read) return; ---- crash/kernel.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/kernel.c 2006-08-03 17:25:27.000000000 -0400 +@@ -5474,7 +5884,9 @@ + } else + use_sighand = FALSE; + +- for (i = 1; i < _NSIG; i++) { ++ sigrtmax = sigrt_minmax(NULL, NULL); ++ ++ for (i = 1; i <= sigrtmax; i++) { + fprintf(fp, "%s[%d] ", i < 10 ? " " : "", i); + + if (use_sighand) { +@@ -5580,6 +5992,8 @@ + else + fprintf(fp, "SIGQUEUE: (empty)\n"); + ++ sigqueue_save = sigqueue; ++ + while (sigqueue) { + readmem(sigqueue, KVADDR, signal_buf, + SIZE_OPTION(signal_queue, sigqueue), +@@ -5597,6 +6011,9 @@ + OFFSET(siginfo_si_signo)); + } + ++ if (sigqueue_save == next) ++ break; ++ + fprintf(fp, " %3d %lx\n", + sig, sigqueue + + OFFSET_OPTION(signal_queue_info, sigqueue_info)); +--- crash/kernel.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/kernel.c 2006-09-05 12:01:04.000000000 -0400 @@ -20,7 +20,7 @@ static void do_module_cmd(ulong, char *, ulong, char *, char *); @@ -7183,7 +8782,7 @@ static char *get_loadavg(char *); static void get_lkcd_regs(struct bt_info *, ulong *, ulong *); static void dump_sys_call_table(char *, int); -@@ -42,6 +42,8 @@ +@@ -42,327 +42,365 @@ static void verify_namelist(void); static char *debug_kernel_version(char *); static int restore_stack(struct bt_info *); @@ -7192,9 +8791,11 @@ /* -@@ -50,9 +52,10 @@ + * Gather a few kernel basics. + */ void - kernel_init(int when) +-kernel_init(int when) ++kernel_init() { - int i; - char *p1, *p2, buf[BUFSIZE];; @@ -7205,127 +8806,644 @@ if (pc->flags & KERNEL_DEBUG_QUERY) return; -@@ -69,6 +72,26 @@ - } - kt->end = symbol_value("_end"); + +- switch (when) +- { +- case PRE_GDB: +- kt->stext = symbol_value("_stext"); +- kt->etext = symbol_value("_etext"); +- get_text_init_space(); +- if (symbol_exists("__init_begin")) { +- kt->init_begin = symbol_value("__init_begin"); +- kt->init_end = symbol_value("__init_end"); +- } +- kt->end = symbol_value("_end"); ++ kt->stext = symbol_value("_stext"); ++ kt->etext = symbol_value("_etext"); ++ get_text_init_space(); ++ if (symbol_exists("__init_begin")) { ++ kt->init_begin = symbol_value("__init_begin"); ++ kt->init_end = symbol_value("__init_end"); ++ } ++ kt->end = symbol_value("_end"); -+ /* -+ * If Xen architecture, default to a guest kernel running -+ * with writable page tables; for now it can be overridden -+ * with the --hypervisor and --shared_page_tables command -+ * line options. -+ */ -+ if (symbol_exists("xen_start_info")) { -+ kt->flags |= ARCH_XEN; -+ if (!(kt->xen_flags & (SHADOW_PAGE_TABLES|CANONICAL_PAGE_TABLES))) -+ kt->xen_flags |= WRITABLE_PAGE_TABLES; -+ get_symbol_data("phys_to_machine_mapping", sizeof(ulong), -+ &kt->phys_to_machine_mapping); -+ if (machine_type("X86")) -+ get_symbol_data("max_pfn", sizeof(ulong), &kt->p2m_table_size); -+ if (machine_type("X86_64")) -+ get_symbol_data("end_pfn", sizeof(ulong), &kt->p2m_table_size); -+ if ((kt->m2p_page = (char *)malloc(PAGESIZE())) == NULL) -+ error(FATAL, "cannot malloc m2p page."); -+ } +- if (symbol_exists("smp_num_cpus")) { +- kt->flags |= SMP; +- get_symbol_data("smp_num_cpus", sizeof(int), &kt->cpus); +- if (kt->cpus < 1 || kt->cpus > NR_CPUS) +- error(WARNING, +- "invalid value: smp_num_cpus: %d\n", +- kt->cpus); +- } else if (symbol_exists("__per_cpu_offset")) { +- kt->flags |= SMP; +- kt->cpus = 1; +- } else +- kt->cpus = 1; +- +- if ((sp1 = symbol_search("__per_cpu_start")) && +- (sp2 = symbol_search("__per_cpu_end")) && +- (sp1->type == 'A') && (sp2->type == 'A') && +- (sp2->value > sp1->value)) +- kt->flags |= SMP|PER_CPU_OFF; ++ /* ++ * If Xen architecture, default to writable page tables; for now ++ * it can be overridden with the --shared_page_tables command ++ * line option. ++ */ ++ if (symbol_exists("xen_start_info")) { ++ kt->flags |= ARCH_XEN; ++ if (!(kt->xen_flags & (SHADOW_PAGE_TABLES|CANONICAL_PAGE_TABLES))) ++ kt->xen_flags |= WRITABLE_PAGE_TABLES; ++ get_symbol_data("phys_to_machine_mapping", sizeof(ulong), ++ &kt->phys_to_machine_mapping); ++ if (machine_type("X86")) ++ get_symbol_data("max_pfn", sizeof(ulong), &kt->p2m_table_size); ++ if (machine_type("X86_64")) ++ get_symbol_data("end_pfn", sizeof(ulong), &kt->p2m_table_size); ++ if ((kt->m2p_page = (char *)malloc(PAGESIZE())) == NULL) ++ error(FATAL, "cannot malloc m2p page."); ++ } + - if (symbol_exists("smp_num_cpus")) { - kt->flags |= SMP; - get_symbol_data("smp_num_cpus", sizeof(int), &kt->cpus); -@@ -96,9 +119,17 @@ - clean_exit(0); - } ++ if (symbol_exists("smp_num_cpus")) { ++ kt->flags |= SMP; ++ get_symbol_data("smp_num_cpus", sizeof(int), &kt->cpus); ++ if (kt->cpus < 1 || kt->cpus > NR_CPUS) ++ error(WARNING, ++ "invalid value: smp_num_cpus: %d\n", ++ kt->cpus); ++ } else if (symbol_exists("__per_cpu_offset")) { ++ kt->flags |= SMP; ++ kt->cpus = 1; ++ } else ++ kt->cpus = 1; ++ ++ if ((sp1 = symbol_search("__per_cpu_start")) && ++ (sp2 = symbol_search("__per_cpu_end")) && ++ (sp1->type == 'A') && (sp2->type == 'A') && ++ (sp2->value > sp1->value)) ++ kt->flags |= SMP|PER_CPU_OFF; + +- get_symbol_data("xtime", sizeof(struct timespec), &kt->date); ++ get_symbol_data("xtime", sizeof(struct timespec), &kt->date); + +- if (pc->flags & GET_TIMESTAMP) { +- fprintf(fp, "%s\n\n", +- strip_linefeeds(ctime(&kt->date.tv_sec))); +- clean_exit(0); +- } ++ if (pc->flags & GET_TIMESTAMP) { ++ fprintf(fp, "%s\n\n", ++ strip_linefeeds(ctime(&kt->date.tv_sec))); ++ clean_exit(0); ++ } - readmem(symbol_value("system_utsname"), KVADDR, &kt->utsname, - sizeof(struct new_utsname), "system_utsname", - FAULT_ON_ERROR); -+ if (symbol_exists("system_utsname")) -+ readmem(symbol_value("system_utsname"), KVADDR, &kt->utsname, -+ sizeof(struct new_utsname), "system_utsname", -+ RETURN_ON_ERROR); -+ else if (symbol_exists("init_uts_ns")) -+ readmem(symbol_value("init_uts_ns") + sizeof(int), -+ KVADDR, &kt->utsname, sizeof(struct new_utsname), -+ "init_uts_ns", RETURN_ON_ERROR); -+ else -+ error(INFO, "cannot access utsname information\n\n"); -+ - strncpy(buf, kt->utsname.release, MIN(strlen(kt->utsname.release), 65)); - if (ascii_string(kt->utsname.release)) { - p1 = p2 = buf; -@@ -117,6 +148,7 @@ - *p2 = NULLCHAR; - kt->kernel_version[2] = atoi(p1); - } -+ - break; +- strncpy(buf, kt->utsname.release, MIN(strlen(kt->utsname.release), 65)); +- if (ascii_string(kt->utsname.release)) { +- p1 = p2 = buf; +- while (*p2 != '.') +- p2++; +- *p2 = NULLCHAR; +- kt->kernel_version[0] = atoi(p1); +- p1 = ++p2; +- while (*p2 != '.') +- p2++; +- *p2 = NULLCHAR; +- kt->kernel_version[1] = atoi(p1); +- p1 = ++p2; +- while ((*p2 >= '0') && (*p2 <= '9')) +- p2++; +- *p2 = NULLCHAR; +- kt->kernel_version[2] = atoi(p1); +- } +- break; ++ if (symbol_exists("system_utsname")) ++ readmem(symbol_value("system_utsname"), KVADDR, &kt->utsname, ++ sizeof(struct new_utsname), "system_utsname", ++ RETURN_ON_ERROR); ++ else if (symbol_exists("init_uts_ns")) ++ readmem(symbol_value("init_uts_ns") + sizeof(int), ++ KVADDR, &kt->utsname, sizeof(struct new_utsname), ++ "init_uts_ns", RETURN_ON_ERROR); ++ else ++ error(INFO, "cannot access utsname information\n\n"); - case POST_GDB: -@@ -127,8 +159,17 @@ - &kt->__per_cpu_offset[0]); - kt->flags |= PER_CPU_OFF; - } +- case POST_GDB: +- if (symbol_exists("__per_cpu_offset")) { +- i = get_array_length("__per_cpu_offset", NULL, 0); +- get_symbol_data("__per_cpu_offset", +- sizeof(long)*(i <= NR_CPUS ? i : NR_CPUS), +- &kt->__per_cpu_offset[0]); +- kt->flags |= PER_CPU_OFF; +- } - MEMBER_OFFSET_INIT(runqueue_cpu, "runqueue", "cpu"); - if (VALID_MEMBER(runqueue_cpu)) { -+ if (STRUCT_EXISTS("runqueue")) -+ rqstruct = "runqueue"; -+ else if (STRUCT_EXISTS("rq")) -+ rqstruct = "rq"; -+ -+ MEMBER_OFFSET_INIT(runqueue_cpu, rqstruct, "cpu"); -+ /* -+ * 'cpu' does not exist in 'struct rq'. -+ */ -+ if (VALID_MEMBER(runqueue_cpu) && -+ (get_array_length("runqueue.cpu", NULL, 0) > 0)) { - MEMBER_OFFSET_INIT(cpu_s_curr, "cpu_s", "curr"); - MEMBER_OFFSET_INIT(cpu_s_idle, "cpu_s", "idle"); - STRUCT_SIZE_INIT(cpu_s, "cpu_s"); -@@ -151,16 +192,17 @@ - "runq_siblings: %d: __cpu_idx and __rq_idx arrays don't exist?\n", - kt->runq_siblings); - } else { +- MEMBER_OFFSET_INIT(cpu_s_curr, "cpu_s", "curr"); +- MEMBER_OFFSET_INIT(cpu_s_idle, "cpu_s", "idle"); +- STRUCT_SIZE_INIT(cpu_s, "cpu_s"); +- kt->runq_siblings = get_array_length("runqueue.cpu", +- NULL, 0); +- if (symbol_exists("__cpu_idx") && +- symbol_exists("__rq_idx")) { +- if (!readmem(symbol_value("__cpu_idx"), KVADDR, +- &kt->__cpu_idx[0], sizeof(long) * NR_CPUS, +- "__cpu_idx[NR_CPUS]", RETURN_ON_ERROR)) +- error(INFO, +- "cannot read __cpu_idx[NR_CPUS] array\n"); +- if (!readmem(symbol_value("__rq_idx"), KVADDR, +- &kt->__rq_idx[0], sizeof(long) * NR_CPUS, +- "__rq_idx[NR_CPUS]", RETURN_ON_ERROR)) +- error(INFO, +- "cannot read __rq_idx[NR_CPUS] array\n"); +- } else if (kt->runq_siblings > 1) +- error(INFO, +- "runq_siblings: %d: __cpu_idx and __rq_idx arrays don't exist?\n", +- kt->runq_siblings); +- } else { - MEMBER_OFFSET_INIT(runqueue_idle, "runqueue", "idle"); - MEMBER_OFFSET_INIT(runqueue_curr, "runqueue", "curr"); - } - MEMBER_OFFSET_INIT(runqueue_active, "runqueue", "active"); - MEMBER_OFFSET_INIT(runqueue_expired, "runqueue", "expired"); - MEMBER_OFFSET_INIT(runqueue_arrays, "runqueue", "arrays"); -+ MEMBER_OFFSET_INIT(runqueue_idle, rqstruct, "idle"); -+ MEMBER_OFFSET_INIT(runqueue_curr, rqstruct, "curr"); -+ ASSIGN_OFFSET(runqueue_cpu) = INVALID_OFFSET; -+ } -+ MEMBER_OFFSET_INIT(runqueue_active, rqstruct, "active"); -+ MEMBER_OFFSET_INIT(runqueue_expired, rqstruct, "expired"); -+ MEMBER_OFFSET_INIT(runqueue_arrays, rqstruct, "arrays"); - MEMBER_OFFSET_INIT(prio_array_queue, "prio_array", "queue"); - MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", - "nr_active"); +- MEMBER_OFFSET_INIT(prio_array_queue, "prio_array", "queue"); +- MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", +- "nr_active"); - STRUCT_SIZE_INIT(runqueue, "runqueue"); -+ STRUCT_SIZE_INIT(runqueue, rqstruct); - STRUCT_SIZE_INIT(prio_array, "prio_array"); - - /* -@@ -197,10 +239,16 @@ - (kt->flags & PER_CPU_OFF)) - kt->cpus = machdep->get_smp_cpus(); - -+ if (kt->cpus_override && (c = atoi(kt->cpus_override))) { -+ error(WARNING, "forcing cpu count to: %d\n\n", c); -+ kt->cpus = c; -+ } +- STRUCT_SIZE_INIT(prio_array, "prio_array"); +- +- /* +- * In 2.4, smp_send_stop() sets smp_num_cpus back to 1 +- * in some, but not all, architectures. So if a count +- * of 1 is found, be suspicious, and check the +- * init_tasks[NR_CPUS] array (also intro'd in 2.4), +- * for idle thread addresses. For 2.2, prepare for the +- * eventuality by verifying the cpu count with the machine +- * dependent count. +- */ +- if ((kt->flags & SMP) && DUMPFILE() && (kt->cpus == 1)) { +- if (symbol_exists("init_tasks")) { +- ulong init_tasks[NR_CPUS]; +- int nr_cpus; +- +- BZERO(&init_tasks[0], sizeof(ulong) * NR_CPUS); +- +- nr_cpus = get_array_length("init_tasks", +- NULL, 0); +- if ((nr_cpus < 1) || (nr_cpus > NR_CPUS)) +- nr_cpus = NR_CPUS; +- +- get_idle_threads(&init_tasks[0], nr_cpus); +- +- for (i = kt->cpus = 0; i < nr_cpus; i++) +- if (init_tasks[i]) +- kt->cpus++; +- } else +- kt->cpus = machdep->get_smp_cpus(); +- } ++ strncpy(buf, kt->utsname.release, MIN(strlen(kt->utsname.release), 65)); ++ if (ascii_string(kt->utsname.release)) { ++ p1 = p2 = buf; ++ while (*p2 != '.') ++ p2++; ++ *p2 = NULLCHAR; ++ kt->kernel_version[0] = atoi(p1); ++ p1 = ++p2; ++ while (*p2 != '.') ++ p2++; ++ *p2 = NULLCHAR; ++ kt->kernel_version[1] = atoi(p1); ++ p1 = ++p2; ++ while ((*p2 >= '0') && (*p2 <= '9')) ++ p2++; ++ *p2 = NULLCHAR; ++ kt->kernel_version[2] = atoi(p1); ++ } + - if (kt->cpus > NR_CPUS) { - error(WARNING, ++ verify_version(); ++ ++ if (symbol_exists("__per_cpu_offset")) { ++ i = get_array_length("__per_cpu_offset", NULL, 0); ++ get_symbol_data("__per_cpu_offset", ++ sizeof(long)*(i <= NR_CPUS ? i : NR_CPUS), ++ &kt->__per_cpu_offset[0]); ++ kt->flags |= PER_CPU_OFF; ++ } ++ if (STRUCT_EXISTS("runqueue")) ++ rqstruct = "runqueue"; ++ else if (STRUCT_EXISTS("rq")) ++ rqstruct = "rq"; + +- if ((kt->flags & SMP) && ACTIVE() && (kt->cpus == 1) && +- (kt->flags & PER_CPU_OFF)) ++ MEMBER_OFFSET_INIT(runqueue_cpu, rqstruct, "cpu"); ++ /* ++ * 'cpu' does not exist in 'struct rq'. ++ */ ++ if (VALID_MEMBER(runqueue_cpu) && ++ (get_array_length("runqueue.cpu", NULL, 0) > 0)) { ++ MEMBER_OFFSET_INIT(cpu_s_curr, "cpu_s", "curr"); ++ MEMBER_OFFSET_INIT(cpu_s_idle, "cpu_s", "idle"); ++ STRUCT_SIZE_INIT(cpu_s, "cpu_s"); ++ kt->runq_siblings = get_array_length("runqueue.cpu", ++ NULL, 0); ++ if (symbol_exists("__cpu_idx") && ++ symbol_exists("__rq_idx")) { ++ if (!readmem(symbol_value("__cpu_idx"), KVADDR, ++ &kt->__cpu_idx[0], sizeof(long) * NR_CPUS, ++ "__cpu_idx[NR_CPUS]", RETURN_ON_ERROR)) ++ error(INFO, ++ "cannot read __cpu_idx[NR_CPUS] array\n"); ++ if (!readmem(symbol_value("__rq_idx"), KVADDR, ++ &kt->__rq_idx[0], sizeof(long) * NR_CPUS, ++ "__rq_idx[NR_CPUS]", RETURN_ON_ERROR)) ++ error(INFO, ++ "cannot read __rq_idx[NR_CPUS] array\n"); ++ } else if (kt->runq_siblings > 1) ++ error(INFO, ++ "runq_siblings: %d: __cpu_idx and __rq_idx arrays don't exist?\n", ++ kt->runq_siblings); ++ } else { ++ MEMBER_OFFSET_INIT(runqueue_idle, rqstruct, "idle"); ++ MEMBER_OFFSET_INIT(runqueue_curr, rqstruct, "curr"); ++ ASSIGN_OFFSET(runqueue_cpu) = INVALID_OFFSET; ++ } ++ MEMBER_OFFSET_INIT(runqueue_active, rqstruct, "active"); ++ MEMBER_OFFSET_INIT(runqueue_expired, rqstruct, "expired"); ++ MEMBER_OFFSET_INIT(runqueue_arrays, rqstruct, "arrays"); ++ MEMBER_OFFSET_INIT(prio_array_queue, "prio_array", "queue"); ++ MEMBER_OFFSET_INIT(prio_array_nr_active, "prio_array", "nr_active"); ++ STRUCT_SIZE_INIT(runqueue, rqstruct); ++ STRUCT_SIZE_INIT(prio_array, "prio_array"); ++ ++ /* ++ * In 2.4, smp_send_stop() sets smp_num_cpus back to 1 ++ * in some, but not all, architectures. So if a count ++ * of 1 is found, be suspicious, and check the ++ * init_tasks[NR_CPUS] array (also intro'd in 2.4), ++ * for idle thread addresses. For 2.2, prepare for the ++ * eventuality by verifying the cpu count with the machine ++ * dependent count. ++ */ ++ if ((kt->flags & SMP) && DUMPFILE() && (kt->cpus == 1)) { ++ if (symbol_exists("init_tasks")) { ++ ulong init_tasks[NR_CPUS]; ++ int nr_cpus; ++ ++ BZERO(&init_tasks[0], sizeof(ulong) * NR_CPUS); ++ ++ nr_cpus = get_array_length("init_tasks", NULL, 0); ++ if ((nr_cpus < 1) || (nr_cpus > NR_CPUS)) ++ nr_cpus = NR_CPUS; ++ ++ get_idle_threads(&init_tasks[0], nr_cpus); ++ ++ for (i = kt->cpus = 0; i < nr_cpus; i++) ++ if (init_tasks[i]) ++ kt->cpus++; ++ } else + kt->cpus = machdep->get_smp_cpus(); ++ } + +- if (kt->cpus > NR_CPUS) { +- error(WARNING, - "calculated number of cpus (%d) greater than compiled-in NR_CPUS (%d)\n", - kt->cpus, NR_CPUS); +- error(FATAL, "recompile crash with larger NR_CPUS\n"); +- } +- +- STRUCT_SIZE_INIT(spinlock_t, "spinlock_t"); +- verify_spinlock(); +- +- STRUCT_SIZE_INIT(list_head, "list_head"); +- MEMBER_OFFSET_INIT(list_head_next, "list_head", "next"); +- MEMBER_OFFSET_INIT(list_head_prev, "list_head", "prev"); +- if (OFFSET(list_head_next) != 0) +- error(WARNING, +- "list_head.next offset: %ld: list command may fail\n", +- OFFSET(list_head_next)); +- +- MEMBER_OFFSET_INIT(hlist_node_next, "hlist_node", "next"); +- MEMBER_OFFSET_INIT(hlist_node_pprev, "hlist_node", "pprev"); +- STRUCT_SIZE_INIT(hlist_head, "hlist_head"); +- STRUCT_SIZE_INIT(hlist_node, "hlist_node"); +- +- MEMBER_OFFSET_INIT(irq_desc_t_status, "irq_desc_t", "status"); +- MEMBER_OFFSET_INIT(irq_desc_t_handler, "irq_desc_t", "handler"); +- MEMBER_OFFSET_INIT(irq_desc_t_action, "irq_desc_t", "action"); +- MEMBER_OFFSET_INIT(irq_desc_t_depth, "irq_desc_t", "depth"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_typename, +- "hw_interrupt_type", "typename"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_startup, +- "hw_interrupt_type", "startup"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_shutdown, +- "hw_interrupt_type", "shutdown"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_handle, +- "hw_interrupt_type", "handle"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_enable, +- "hw_interrupt_type", "enable"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_disable, +- "hw_interrupt_type", "disable"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_ack, +- "hw_interrupt_type", "ack"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_end, +- "hw_interrupt_type", "end"); +- MEMBER_OFFSET_INIT(hw_interrupt_type_set_affinity, +- "hw_interrupt_type", "set_affinity"); +- MEMBER_OFFSET_INIT(irqaction_handler, "irqaction", "handler"); +- MEMBER_OFFSET_INIT(irqaction_flags, "irqaction", "flags"); +- MEMBER_OFFSET_INIT(irqaction_mask, "irqaction", "mask"); +- MEMBER_OFFSET_INIT(irqaction_name, "irqaction", "name"); +- MEMBER_OFFSET_INIT(irqaction_dev_id, "irqaction", "dev_id"); +- MEMBER_OFFSET_INIT(irqaction_next, "irqaction", "next"); +- +- STRUCT_SIZE_INIT(irq_desc_t, "irq_desc_t"); +- +- STRUCT_SIZE_INIT(irq_cpustat_t, "irq_cpustat_t"); +- MEMBER_OFFSET_INIT(irq_cpustat_t___softirq_active, +- "irq_cpustat_t", "__softirq_active"); +- MEMBER_OFFSET_INIT(irq_cpustat_t___softirq_mask, +- "irq_cpustat_t", "__softirq_mask"); +- +- STRUCT_SIZE_INIT(timer_list, "timer_list"); +- MEMBER_OFFSET_INIT(timer_list_list, "timer_list", "list"); +- MEMBER_OFFSET_INIT(timer_list_next, "timer_list", "next"); +- MEMBER_OFFSET_INIT(timer_list_entry, "timer_list", "entry"); +- MEMBER_OFFSET_INIT(timer_list_expires, "timer_list", "expires"); +- MEMBER_OFFSET_INIT(timer_list_function, +- "timer_list", "function"); +- STRUCT_SIZE_INIT(timer_vec_root, "timer_vec_root"); +- if (VALID_STRUCT(timer_vec_root)) +- MEMBER_OFFSET_INIT(timer_vec_root_vec, +- "timer_vec_root", "vec"); +- STRUCT_SIZE_INIT(timer_vec, "timer_vec"); +- if (VALID_STRUCT(timer_vec)) +- MEMBER_OFFSET_INIT(timer_vec_vec, "timer_vec", "vec"); +- +- STRUCT_SIZE_INIT(tvec_root_s, "tvec_root_s"); +- if (VALID_STRUCT(tvec_root_s)) { +- STRUCT_SIZE_INIT(tvec_t_base_s, "tvec_t_base_s"); +- MEMBER_OFFSET_INIT(tvec_t_base_s_tv1, +- "tvec_t_base_s", "tv1"); +- MEMBER_OFFSET_INIT(tvec_root_s_vec, +- "tvec_root_s", "vec"); +- STRUCT_SIZE_INIT(tvec_s, "tvec_s"); +- MEMBER_OFFSET_INIT(tvec_s_vec, "tvec_s", "vec"); +- } +- +- STRUCT_SIZE_INIT(__wait_queue, "__wait_queue"); +- if (VALID_STRUCT(__wait_queue)) { +- MEMBER_OFFSET_INIT(__wait_queue_task, +- "__wait_queue", "task"); +- MEMBER_OFFSET_INIT(__wait_queue_head_task_list, +- "__wait_queue_head", "task_list"); +- MEMBER_OFFSET_INIT(__wait_queue_task_list, +- "__wait_queue", "task_list"); +- } else { +- STRUCT_SIZE_INIT(wait_queue, "wait_queue"); +- if (VALID_STRUCT(wait_queue)) { +- MEMBER_OFFSET_INIT(wait_queue_task, +- "wait_queue", "task"); +- MEMBER_OFFSET_INIT(wait_queue_next, +- "wait_queue", "next"); +- } ++ if ((kt->flags & SMP) && ACTIVE() && (kt->cpus == 1) && ++ (kt->flags & PER_CPU_OFF)) ++ kt->cpus = machdep->get_smp_cpus(); ++ ++ if (kt->cpus_override && (c = atoi(kt->cpus_override))) { ++ error(WARNING, "forcing cpu count to: %d\n\n", c); ++ kt->cpus = c; ++ } ++ ++ if (kt->cpus > NR_CPUS) { ++ error(WARNING, + "%s number of cpus (%d) greater than compiled-in NR_CPUS (%d)\n", -+ kt->cpus_override && atoi(kt->cpus_override) ? -+ "configured" : "calculated", kt->cpus, NR_CPUS); - error(FATAL, "recompile crash with larger NR_CPUS\n"); ++ kt->cpus_override && atoi(kt->cpus_override) ? ++ "configured" : "calculated", kt->cpus, NR_CPUS); ++ error(FATAL, "recompile crash with larger NR_CPUS\n"); ++ } ++ ++ STRUCT_SIZE_INIT(spinlock_t, "spinlock_t"); ++ verify_spinlock(); ++ ++ STRUCT_SIZE_INIT(list_head, "list_head"); ++ MEMBER_OFFSET_INIT(list_head_next, "list_head", "next"); ++ MEMBER_OFFSET_INIT(list_head_prev, "list_head", "prev"); ++ if (OFFSET(list_head_next) != 0) ++ error(WARNING, ++ "list_head.next offset: %ld: list command may fail\n", ++ OFFSET(list_head_next)); ++ ++ MEMBER_OFFSET_INIT(hlist_node_next, "hlist_node", "next"); ++ MEMBER_OFFSET_INIT(hlist_node_pprev, "hlist_node", "pprev"); ++ STRUCT_SIZE_INIT(hlist_head, "hlist_head"); ++ STRUCT_SIZE_INIT(hlist_node, "hlist_node"); ++ ++ MEMBER_OFFSET_INIT(irq_desc_t_status, "irq_desc_t", "status"); ++ MEMBER_OFFSET_INIT(irq_desc_t_handler, "irq_desc_t", "handler"); ++ MEMBER_OFFSET_INIT(irq_desc_t_action, "irq_desc_t", "action"); ++ MEMBER_OFFSET_INIT(irq_desc_t_depth, "irq_desc_t", "depth"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_typename, ++ "hw_interrupt_type", "typename"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_startup, ++ "hw_interrupt_type", "startup"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_shutdown, ++ "hw_interrupt_type", "shutdown"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_handle, ++ "hw_interrupt_type", "handle"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_enable, ++ "hw_interrupt_type", "enable"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_disable, ++ "hw_interrupt_type", "disable"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_ack, ++ "hw_interrupt_type", "ack"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_end, ++ "hw_interrupt_type", "end"); ++ MEMBER_OFFSET_INIT(hw_interrupt_type_set_affinity, ++ "hw_interrupt_type", "set_affinity"); ++ MEMBER_OFFSET_INIT(irqaction_handler, "irqaction", "handler"); ++ MEMBER_OFFSET_INIT(irqaction_flags, "irqaction", "flags"); ++ MEMBER_OFFSET_INIT(irqaction_mask, "irqaction", "mask"); ++ MEMBER_OFFSET_INIT(irqaction_name, "irqaction", "name"); ++ MEMBER_OFFSET_INIT(irqaction_dev_id, "irqaction", "dev_id"); ++ MEMBER_OFFSET_INIT(irqaction_next, "irqaction", "next"); ++ ++ STRUCT_SIZE_INIT(irq_desc_t, "irq_desc_t"); ++ ++ STRUCT_SIZE_INIT(irq_cpustat_t, "irq_cpustat_t"); ++ MEMBER_OFFSET_INIT(irq_cpustat_t___softirq_active, ++ "irq_cpustat_t", "__softirq_active"); ++ MEMBER_OFFSET_INIT(irq_cpustat_t___softirq_mask, ++ "irq_cpustat_t", "__softirq_mask"); ++ ++ STRUCT_SIZE_INIT(timer_list, "timer_list"); ++ MEMBER_OFFSET_INIT(timer_list_list, "timer_list", "list"); ++ MEMBER_OFFSET_INIT(timer_list_next, "timer_list", "next"); ++ MEMBER_OFFSET_INIT(timer_list_entry, "timer_list", "entry"); ++ MEMBER_OFFSET_INIT(timer_list_expires, "timer_list", "expires"); ++ MEMBER_OFFSET_INIT(timer_list_function, "timer_list", "function"); ++ STRUCT_SIZE_INIT(timer_vec_root, "timer_vec_root"); ++ if (VALID_STRUCT(timer_vec_root)) ++ MEMBER_OFFSET_INIT(timer_vec_root_vec, ++ "timer_vec_root", "vec"); ++ STRUCT_SIZE_INIT(timer_vec, "timer_vec"); ++ if (VALID_STRUCT(timer_vec)) ++ MEMBER_OFFSET_INIT(timer_vec_vec, "timer_vec", "vec"); ++ ++ STRUCT_SIZE_INIT(tvec_root_s, "tvec_root_s"); ++ if (VALID_STRUCT(tvec_root_s)) { ++ STRUCT_SIZE_INIT(tvec_t_base_s, "tvec_t_base_s"); ++ MEMBER_OFFSET_INIT(tvec_t_base_s_tv1, ++ "tvec_t_base_s", "tv1"); ++ MEMBER_OFFSET_INIT(tvec_root_s_vec, ++ "tvec_root_s", "vec"); ++ STRUCT_SIZE_INIT(tvec_s, "tvec_s"); ++ MEMBER_OFFSET_INIT(tvec_s_vec, "tvec_s", "vec"); ++ } ++ ++ STRUCT_SIZE_INIT(__wait_queue, "__wait_queue"); ++ if (VALID_STRUCT(__wait_queue)) { ++ MEMBER_OFFSET_INIT(__wait_queue_task, ++ "__wait_queue", "task"); ++ MEMBER_OFFSET_INIT(__wait_queue_head_task_list, ++ "__wait_queue_head", "task_list"); ++ MEMBER_OFFSET_INIT(__wait_queue_task_list, ++ "__wait_queue", "task_list"); ++ } else { ++ STRUCT_SIZE_INIT(wait_queue, "wait_queue"); ++ if (VALID_STRUCT(wait_queue)) { ++ MEMBER_OFFSET_INIT(wait_queue_task, ++ "wait_queue", "task"); ++ MEMBER_OFFSET_INIT(wait_queue_next, ++ "wait_queue", "next"); } ++ } -@@ -471,6 +519,9 @@ +- STRUCT_SIZE_INIT(pt_regs, "pt_regs"); +- STRUCT_SIZE_INIT(softirq_state, "softirq_state"); +- STRUCT_SIZE_INIT(desc_struct, "desc_struct"); +- +- STRUCT_SIZE_INIT(char_device_struct, "char_device_struct"); +- if (VALID_STRUCT(char_device_struct)) { +- MEMBER_OFFSET_INIT(char_device_struct_next, +- "char_device_struct", "next"); +- MEMBER_OFFSET_INIT(char_device_struct_name, +- "char_device_struct", "name"); +- MEMBER_OFFSET_INIT(char_device_struct_fops, +- "char_device_struct", "fops"); +- MEMBER_OFFSET_INIT(char_device_struct_major, +- "char_device_struct", "major"); +- } +- +- MEMBER_OFFSET_INIT(module_kallsyms_start, "module", +- "kallsyms_start"); +- +- STRUCT_SIZE_INIT(kallsyms_header, "kallsyms_header"); +- +- if (VALID_MEMBER(module_kallsyms_start) && +- VALID_SIZE(kallsyms_header)) { +- MEMBER_OFFSET_INIT(kallsyms_header_sections, +- "kallsyms_header", "sections"); +- MEMBER_OFFSET_INIT(kallsyms_header_section_off, +- "kallsyms_header", "section_off"); +- MEMBER_OFFSET_INIT(kallsyms_header_symbols, +- "kallsyms_header", "symbols"); +- MEMBER_OFFSET_INIT(kallsyms_header_symbol_off, +- "kallsyms_header", "symbol_off"); +- MEMBER_OFFSET_INIT(kallsyms_header_string_off, +- "kallsyms_header", "string_off"); +- MEMBER_OFFSET_INIT(kallsyms_symbol_section_off, +- "kallsyms_symbol", "section_off"); +- MEMBER_OFFSET_INIT(kallsyms_symbol_symbol_addr, +- "kallsyms_symbol", "symbol_addr"); +- MEMBER_OFFSET_INIT(kallsyms_symbol_name_off, +- "kallsyms_symbol", "name_off"); +- MEMBER_OFFSET_INIT(kallsyms_section_start, +- "kallsyms_section", "start"); +- MEMBER_OFFSET_INIT(kallsyms_section_size, +- "kallsyms_section", "size"); +- MEMBER_OFFSET_INIT(kallsyms_section_name_off, +- "kallsyms_section", "name_off"); +- STRUCT_SIZE_INIT(kallsyms_symbol, "kallsyms_symbol"); +- STRUCT_SIZE_INIT(kallsyms_section, "kallsyms_section"); ++ STRUCT_SIZE_INIT(pt_regs, "pt_regs"); ++ STRUCT_SIZE_INIT(softirq_state, "softirq_state"); ++ STRUCT_SIZE_INIT(desc_struct, "desc_struct"); ++ ++ STRUCT_SIZE_INIT(char_device_struct, "char_device_struct"); ++ if (VALID_STRUCT(char_device_struct)) { ++ MEMBER_OFFSET_INIT(char_device_struct_next, ++ "char_device_struct", "next"); ++ MEMBER_OFFSET_INIT(char_device_struct_name, ++ "char_device_struct", "name"); ++ MEMBER_OFFSET_INIT(char_device_struct_fops, ++ "char_device_struct", "fops"); ++ MEMBER_OFFSET_INIT(char_device_struct_major, ++ "char_device_struct", "major"); ++ } ++ ++ MEMBER_OFFSET_INIT(module_kallsyms_start, "module", ++ "kallsyms_start"); ++ ++ STRUCT_SIZE_INIT(kallsyms_header, "kallsyms_header"); ++ ++ if (VALID_MEMBER(module_kallsyms_start) && ++ VALID_SIZE(kallsyms_header)) { ++ MEMBER_OFFSET_INIT(kallsyms_header_sections, ++ "kallsyms_header", "sections"); ++ MEMBER_OFFSET_INIT(kallsyms_header_section_off, ++ "kallsyms_header", "section_off"); ++ MEMBER_OFFSET_INIT(kallsyms_header_symbols, ++ "kallsyms_header", "symbols"); ++ MEMBER_OFFSET_INIT(kallsyms_header_symbol_off, ++ "kallsyms_header", "symbol_off"); ++ MEMBER_OFFSET_INIT(kallsyms_header_string_off, ++ "kallsyms_header", "string_off"); ++ MEMBER_OFFSET_INIT(kallsyms_symbol_section_off, ++ "kallsyms_symbol", "section_off"); ++ MEMBER_OFFSET_INIT(kallsyms_symbol_symbol_addr, ++ "kallsyms_symbol", "symbol_addr"); ++ MEMBER_OFFSET_INIT(kallsyms_symbol_name_off, ++ "kallsyms_symbol", "name_off"); ++ MEMBER_OFFSET_INIT(kallsyms_section_start, ++ "kallsyms_section", "start"); ++ MEMBER_OFFSET_INIT(kallsyms_section_size, ++ "kallsyms_section", "size"); ++ MEMBER_OFFSET_INIT(kallsyms_section_name_off, ++ "kallsyms_section", "name_off"); ++ STRUCT_SIZE_INIT(kallsyms_symbol, "kallsyms_symbol"); ++ STRUCT_SIZE_INIT(kallsyms_section, "kallsyms_section"); + +- if (!(kt->flags & NO_KALLSYMS)) +- kt->flags |= KALLSYMS_V1; +- } ++ if (!(kt->flags & NO_KALLSYMS)) ++ kt->flags |= KALLSYMS_V1; ++ } + +- MEMBER_OFFSET_INIT(module_num_symtab, "module", "num_symtab"); ++ MEMBER_OFFSET_INIT(module_num_symtab, "module", "num_symtab"); + +- if (VALID_MEMBER(module_num_symtab)) { +- MEMBER_OFFSET_INIT(module_symtab, "module", "symtab"); +- MEMBER_OFFSET_INIT(module_strtab, "module", "strtab"); ++ if (VALID_MEMBER(module_num_symtab)) { ++ MEMBER_OFFSET_INIT(module_symtab, "module", "symtab"); ++ MEMBER_OFFSET_INIT(module_strtab, "module", "strtab"); + +- if (!(kt->flags & NO_KALLSYMS)) +- kt->flags |= KALLSYMS_V2; +- } +- break; ++ if (!(kt->flags & NO_KALLSYMS)) ++ kt->flags |= KALLSYMS_V2; + } + } + +@@ -471,6 +509,9 @@ } } @@ -7335,7 +9453,7 @@ return; bad_match: -@@ -1140,7 +1191,10 @@ +@@ -1140,7 +1181,10 @@ bt = &bt_info; BZERO(bt, sizeof(struct bt_info)); @@ -7347,7 +9465,7 @@ switch(c) { case 'f': -@@ -1151,6 +1205,28 @@ +@@ -1151,6 +1195,28 @@ bt->flags |= BT_OLD_BACK_TRACE; break; @@ -7376,7 +9494,7 @@ case 'R': if (refptr) error(INFO, "only one -R option allowed\n"); -@@ -1241,6 +1317,8 @@ +@@ -1241,6 +1307,8 @@ bt->flags |= BT_SYMBOLIC_ARGS; break; @@ -7385,7 +9503,7 @@ case 't': bt->flags |= BT_TEXT_SYMBOLS; break; -@@ -1350,9 +1428,10 @@ +@@ -1350,9 +1418,10 @@ char buf[BUFSIZE]; if (bt->flags & BT_TEXT_SYMBOLS) { @@ -7399,7 +9517,7 @@ } if (bt->hp) -@@ -1435,6 +1514,9 @@ +@@ -1435,6 +1504,9 @@ i < LONGS_PER_STACK; i++, up++) { if (is_kernel_text(*up)) fprintf(fp, "%lx: %s\n", @@ -7409,7 +9527,7 @@ bt->task + (i * sizeof(long)), value_to_symstr(*up, buf, 0)); } -@@ -1461,8 +1543,8 @@ +@@ -1461,8 +1533,8 @@ if (bt->hp) { if (bt->hp->esp && !INSTACK(bt->hp->esp, bt)) error(INFO, @@ -7420,7 +9538,7 @@ eip = bt->hp->eip; esp = bt->hp->esp; -@@ -1471,10 +1553,14 @@ +@@ -1471,10 +1543,14 @@ } else if (NETDUMP_DUMPFILE()) get_netdump_regs(bt, &eip, &esp); @@ -7435,7 +9553,7 @@ else machdep->get_stack_frame(bt, &eip, &esp); -@@ -1486,6 +1572,13 @@ +@@ -1486,6 +1562,13 @@ if (bt->flags & (BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)) { @@ -7449,7 +9567,7 @@ if (machdep->flags & MACHDEP_BT_TEXT) { bt->instptr = eip; bt->stkptr = esp; -@@ -1721,6 +1814,13 @@ +@@ -1721,6 +1804,13 @@ *esp = *(up-1); return; } @@ -7463,7 +9581,18 @@ if (STREQ(sym, "smp_stop_cpu_interrupt")) { *eip = *up; *esp = bt->task + -@@ -1873,6 +1973,8 @@ +@@ -1837,8 +1927,8 @@ + return; + } + +- if (IS_VMALLOC_ADDR(list.next) && +- IS_VMALLOC_ADDR(list.prev)) { ++ if (IS_VMALLOC_ADDR((ulong)list.next) && ++ IS_VMALLOC_ADDR((ulong)list.prev)) { + kt->kernel_module = sp->value; + kt->module_list = (ulong)list.next; + modules_found = TRUE; +@@ -1873,6 +1963,8 @@ kallsymsbuf = kt->flags & KALLSYMS_V1 ? GETBUF(SIZE(kallsyms_header)) : NULL; @@ -7472,7 +9601,7 @@ for (mod = kt->module_list; mod != kt->kernel_module; mod = mod_next) { if (CRASHDEBUG(7)) fprintf(fp, "module: %lx\n", mod); -@@ -1880,7 +1982,8 @@ +@@ -1880,7 +1972,8 @@ if (!readmem(mod, KVADDR, modbuf, SIZE(module), "module struct", RETURN_ON_ERROR|QUIET)) { error(WARNING, @@ -7482,7 +9611,7 @@ kt->mods_installed = 0; kt->flags |= NO_MODULE_ACCESS; FREEBUF(modbuf); -@@ -1914,7 +2017,8 @@ +@@ -1914,7 +2007,8 @@ kallsymsbuf, SIZE(kallsyms_header), "kallsyms_header", RETURN_ON_ERROR|QUIET)) { error(WARNING, @@ -7492,7 +9621,7 @@ } else { nsyms = UINT(kallsymsbuf + OFFSET(kallsyms_header_symbols)); -@@ -1947,6 +2051,8 @@ +@@ -1947,6 +2041,8 @@ store_module_symbols_v2(total, kt->mods_installed); break; } @@ -7501,7 +9630,7 @@ } -@@ -2459,7 +2565,7 @@ +@@ -2459,7 +2555,7 @@ static char * @@ -7510,7 +9639,7 @@ { char buf[BUFSIZE]; char file[BUFSIZE]; -@@ -2592,6 +2698,32 @@ +@@ -2592,6 +2688,32 @@ return retbuf; } @@ -7543,7 +9672,7 @@ /* * Unlink any temporary remote module object files. -@@ -2787,6 +2919,8 @@ +@@ -2787,6 +2909,8 @@ do { if (sflag) dump_sys_call_table(args[optind], cnt++); @@ -7552,7 +9681,7 @@ else cmd_usage(args[optind], COMPLETE_HELP); optind++; -@@ -2876,7 +3010,7 @@ +@@ -2876,7 +3000,7 @@ get_symbol_data("xtime", sizeof(struct timespec), &kt->date); fprintf(fp, " DATE: %s\n", strip_linefeeds(ctime(&kt->date.tv_sec))); @@ -7561,7 +9690,7 @@ fprintf(fp, "LOAD AVERAGE: %s\n", get_loadavg(buf)); fprintf(fp, " TASKS: %ld\n", RUNNING_TASKS()); fprintf(fp, " NODENAME: %s\n", uts->nodename); -@@ -2891,6 +3025,9 @@ +@@ -2891,6 +3015,9 @@ #ifdef WHO_CARES fprintf(fp, " DOMAINNAME: %s\n", uts->domainname); #endif @@ -7571,7 +9700,7 @@ if (DUMPFILE()) { fprintf(fp, " PANIC: "); if (machdep->flags & HWRESET) -@@ -2952,28 +3089,42 @@ +@@ -2952,28 +3079,42 @@ /* * Calculate and return the uptime. */ @@ -7630,7 +9759,48 @@ #define FSHIFT 11 /* nr of bits of precision */ #define FIXED_1 (1<> FSHIFT) -@@ -3181,9 +3332,9 @@ +@@ -3048,9 +3189,9 @@ + struct syment *sp, *spn; + long size; + #ifdef S390X +- unsigned int *sct, *sys_call_table, addr; ++ unsigned int *sct, *sys_call_table, sys_ni_syscall, addr; + #else +- ulong *sys_call_table, *sct, addr; ++ ulong *sys_call_table, *sct, sys_ni_syscall, addr; + #endif + if (GDB_PATCHED()) + error(INFO, "line numbers are not available\n"); +@@ -3068,6 +3209,8 @@ + readmem(symbol_value("sys_call_table"), KVADDR, sys_call_table, + size, "sys_call_table", FAULT_ON_ERROR); + ++ sys_ni_syscall = symbol_value("sys_ni_syscall"); ++ + if (spec) + open_tmpfile(); + +@@ -3080,13 +3223,17 @@ + "%3x " : "%3d ", i); + fprintf(fp, + "invalid sys_call_table entry: %lx (%s)\n", +- *sct, value_to_symstr(*sct, buf1, 0)); ++ (unsigned long)*sct, ++ value_to_symstr(*sct, buf1, 0)); + } + continue; + } + + fprintf(fp, (output_radix == 16) ? "%3x " : "%3d ", i); +- fprintf(fp, "%-26s ", scp); ++ if (sys_ni_syscall && *sct == sys_ni_syscall) ++ fprintf(fp, "%-26s ", "sys_ni_syscall"); ++ else ++ fprintf(fp, "%-26s ", scp); + + /* + * For system call symbols whose first instruction is +@@ -3181,9 +3328,9 @@ * "help -k" output */ void @@ -7642,7 +9812,7 @@ struct new_utsname *uts; int others; -@@ -3225,6 +3376,12 @@ +@@ -3225,6 +3372,12 @@ fprintf(fp, "%sKMOD_V2", others++ ? "|" : ""); if (kt->flags & KALLSYMS_V2) fprintf(fp, "%sKALLSYMS_V2", others++ ? "|" : ""); @@ -7655,7 +9825,7 @@ fprintf(fp, ")\n"); fprintf(fp, " stext: %lx\n", kt->stext); fprintf(fp, " etext: %lx\n", kt->etext); -@@ -3234,8 +3391,10 @@ +@@ -3234,8 +3387,10 @@ fprintf(fp, " init_end: %lx\n", kt->init_end); fprintf(fp, " end: %lx\n", kt->end); fprintf(fp, " cpus: %d\n", kt->cpus); @@ -7666,7 +9836,7 @@ if (kt->display_bh == display_bh_1) fprintf(fp, " display_bh: display_bh_1()\n"); else if (kt->display_bh == display_bh_2) -@@ -3265,19 +3424,50 @@ +@@ -3265,19 +3420,50 @@ kt->gcc_version[1], kt->gcc_version[2]); fprintf(fp, " runq_siblings: %d\n", kt->runq_siblings); fprintf(fp, " __rq_idx[NR_CPUS]: "); @@ -7722,7 +9892,7 @@ } /* -@@ -4475,9 +4665,16 @@ +@@ -4475,9 +4661,16 @@ ld->start = vec[i]; ld->list_head_offset = offset; ld->end = vec_kvaddr; @@ -7740,7 +9910,7 @@ if (!timer_cnt) continue; timer_list = (ulong *)GETBUF(timer_cnt * sizeof(ulong)); -@@ -4708,21 +4905,412 @@ +@@ -4708,21 +4901,412 @@ machdep->last_pgd_read = 0; machdep->last_pmd_read = 0; machdep->last_ptbl_read = 0; @@ -7787,8 +9957,7 @@ + + return online; +} - -- return count_bits_long(cpu_online_map); ++ +/* + * Xen machine-address to pseudo-physical-page translator. + */ @@ -7893,7 +10062,8 @@ + kt->p2m_mapping_cache[c].mfn = mfn; + kt->p2m_mapping_cache[c].mapping = mapping; + kt->p2m_cache_index = (c+1) % P2M_MAPPING_CACHE; -+ + +- return count_bits_long(cpu_online_map); + return pfn; + } + } @@ -8004,7 +10174,7 @@ + stream.next_in = (Bytef *)head; + stream.avail_in = (uInt)bufsz; + -+ stream.next_out = uncomp; ++ stream.next_out = (Bytef *)uncomp; + stream.avail_out = (uInt)size; + + stream.zalloc = NULL; @@ -8157,8 +10327,8 @@ + break; + } } ---- crash/gdb_interface.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/gdb_interface.c 2006-04-11 17:25:48.000000000 -0400 +--- crash/gdb_interface.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/gdb_interface.c 2006-08-18 14:58:45.000000000 -0400 @@ -31,9 +31,6 @@ { argc = 1; @@ -8189,9 +10359,32 @@ gdb_interface(req); if (!(req->flags & GNU_COMMAND_FAILED)) goto retry; ---- crash/configure.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/configure.c 2006-03-23 15:44:46.000000000 -0500 -@@ -1128,7 +1128,7 @@ +@@ -556,6 +558,14 @@ + + error_hook = NULL; + ++ if (st->flags & ADD_SYMBOL_FILE) { ++ error(INFO, ++ "%s\n gdb add-symbol-file command failed\n", ++ st->current->mod_namelist); ++ delete_load_module(st->current->mod_base); ++ st->flags &= ~ADD_SYMBOL_FILE; ++ } ++ + if (pc->cur_gdb_cmd) { + pc->last_gdb_cmd = pc->cur_gdb_cmd; + pc->cur_gdb_cmd = 0; +--- crash/configure.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/configure.c 2006-08-22 14:44:48.000000000 -0400 +@@ -1121,14 +1121,14 @@ + printf("#\n"); + printf("# crash core analysis suite\n"); + printf("#\n"); +- printf("Summary: crash utility for live systems; netdump, diskdump, LKCD or mcore dumpfiles\n"); ++ printf("Summary: crash utility for live systems; netdump, diskdump, kdump, LKCD or mcore dumpfiles\n"); + printf("Name: %s\n", lower_case(target_data.program, buf)); + printf("Version: %s\n", Version); + printf("Release: %s\n", Release); printf("License: GPL\n"); printf("Group: Development/Debuggers\n"); printf("Source: %%{name}-%%{version}-%%{release}.tar.gz\n"); @@ -8200,8 +10393,17 @@ printf("Distribution: Linux 2.2 or greater\n"); printf("Vendor: Red Hat, Inc.\n"); printf("Packager: Dave Anderson \n"); ---- crash/net.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/net.c 2006-05-11 11:17:01.000000000 -0400 +@@ -1141,7 +1141,7 @@ + printf("%%description\n"); + printf("The core analysis suite is a self-contained tool that can be used to\n"); + printf("investigate either live systems, kernel core dumps created from the\n"); +- printf("netdump and diskdump packages from Red Hat Linux, the mcore kernel patch\n"); ++ printf("netdump, diskdump and kdump facilities from Red Hat Linux, the mcore kernel patch\n"); + printf("offered by Mission Critical Linux, or the LKCD kernel patch.\n"); + printf("\n"); + printf("%%prep\n"); +--- crash/net.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/net.c 2006-05-11 11:23:41.000000000 -0400 @@ -50,6 +50,7 @@ #define STRUCT_NET_DEVICE (0x4) #define SOCK_V1 (0x8) @@ -8557,8 +10759,8 @@ break; } break; ---- crash/dev.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/dev.c 2005-11-23 11:09:08.000000000 -0500 +--- crash/dev.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/dev.c 2005-11-23 11:09:44.000000000 -0500 @@ -91,13 +91,13 @@ switch(c) { @@ -8575,8 +10777,8 @@ option_not_supported(c); do_pci(); return; ---- crash/alpha.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/alpha.c 2006-08-02 10:30:58.000000000 -0400 +--- crash/alpha.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/alpha.c 2006-08-02 10:34:16.000000000 -0400 @@ -186,7 +186,8 @@ "irq_desc", NULL, 0); else @@ -8596,8 +10798,8 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base); ---- crash/x86.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/x86.c 2006-08-03 11:15:55.000000000 -0400 +--- crash/x86.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/x86.c 2006-08-02 10:34:16.000000000 -0400 @@ -176,6 +176,7 @@ static void db_symbol_values(db_sym_t, char **, db_expr_t *); static int db_sym_numargs(db_sym_t, int *, char **); @@ -10543,8 +12745,8 @@ + return machdep->get_stack_frame(bt, eip, esp); +} #endif /* X86 */ ---- crash/ppc.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/ppc.c 2006-08-02 10:31:13.000000000 -0400 +--- crash/ppc.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/ppc.c 2006-08-02 10:34:16.000000000 -0400 @@ -135,9 +135,13 @@ "irq_desc", NULL, 0); else @@ -10581,8 +12783,8 @@ fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec); } ---- crash/ia64.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/ia64.c 2006-08-03 14:28:37.000000000 -0400 +--- crash/ia64.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/ia64.c 2006-08-21 15:08:44.000000000 -0400 @@ -1,8 +1,8 @@ /* ia64.c - core analysis suite * @@ -10598,12 +12800,31 @@ static void try_old_unwind(struct bt_info *); static void ia64_dump_irq(int); static ulong ia64_processor_speed(void); -+static int ia64_vtop_4l(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr); -+static int ia64_vtop(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr); ++static int ia64_vtop_4l(ulong, physaddr_t *paddr, ulong *pgd, int, int); ++static int ia64_vtop(ulong, physaddr_t *paddr, ulong *pgd, int, int); static int ia64_uvtop(struct task_context *, ulong, physaddr_t *, int); static int ia64_kvtop(struct task_context *, ulong, physaddr_t *, int); static ulong ia64_get_task_pgd(ulong); -@@ -92,17 +94,23 @@ +@@ -62,6 +64,18 @@ + static ulong rse_read_reg(struct unw_frame_info *, int, int *); + static void rse_function_params(struct unw_frame_info *, char *); + ++static int ia64_vtop_4l_xen_wpt(ulong, physaddr_t *paddr, ulong *pgd, int, int); ++static int ia64_vtop_xen_wpt(ulong, physaddr_t *paddr, ulong *pgd, int, int); ++static int ia64_xen_kdump_p2m_create(struct xen_kdump_data *); ++static char *ia64_xen_kdump_load_page(ulong, char *); ++static ulong ia64_xen_kdump_page_mfn(ulong); ++static int ia64_xendump_p2m_create(struct xendump_data *); ++static void ia64_debug_dump_page(FILE *, char *, char *); ++static char *ia64_xendump_load_page(ulong, struct xendump_data *); ++static int ia64_xendump_page_index(ulong, struct xendump_data *); ++static ulong ia64_xendump_panic_task(struct xendump_data *); ++static void ia64_get_xendump_regs(struct xendump_data *, struct bt_info *, ulong *, ulong *); ++ + + struct machine_specific ia64_machine_specific = { 0 }; + +@@ -92,17 +106,23 @@ case 16384: machdep->stacksize = (power(2, 1) * PAGESIZE()); break; @@ -10627,7 +12848,7 @@ machdep->last_pmd_read = 0; machdep->last_ptbl_read = 0; machdep->verify_paddr = ia64_verify_paddr; -@@ -115,14 +123,17 @@ +@@ -115,14 +135,17 @@ break; case PRE_GDB: @@ -10645,17 +12866,31 @@ if ((sp = symbol_search("empty_zero_page")) && (spn = next_symbol(NULL, sp)) && -@@ -202,7 +213,8 @@ +@@ -173,6 +196,11 @@ + DEFAULT_PHYS_START; + } else + machdep->machspec->vmalloc_start = KERNEL_VMALLOC_BASE; ++ ++ machdep->xen_kdump_p2m_create = ia64_xen_kdump_p2m_create; ++ machdep->xendump_p2m_create = ia64_xendump_p2m_create; ++ machdep->xendump_panic_task = ia64_xendump_panic_task; ++ machdep->get_xendump_regs = ia64_get_xendump_regs; + break; + + case POST_GDB: +@@ -202,7 +230,10 @@ else if (symbol_exists("_irq_desc")) ARRAY_LENGTH_INIT(machdep->nr_irqs, irq_desc, "_irq_desc", NULL, 0); - machdep->hz = 1024; + if (!machdep->hz) + machdep->hz = 1024; ++ machdep->section_size_bits = _SECTION_SIZE_BITS; ++ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS; ia64_create_memmap(); break; -@@ -284,11 +296,34 @@ +@@ -284,11 +315,34 @@ continue; } } @@ -10690,7 +12925,7 @@ if (c) fprintf(fp, "\n"); } -@@ -401,12 +436,12 @@ +@@ -401,12 +455,12 @@ fprintf(fp, "%sUNW_R0", others++ ? "|" : ""); if (machdep->flags & MEM_LIMIT) fprintf(fp, "%sMEM_LIMIT", others++ ? "|" : ""); @@ -10705,12 +12940,14 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); fprintf(fp, " identity_map_base: %lx\n", machdep->identity_map_base); -@@ -445,12 +480,16 @@ +@@ -445,16 +499,25 @@ (machdep->verify_paddr == ia64_verify_paddr) ? "ia64_verify_paddr" : "generic_verify_paddr"); fprintf(fp, " init_kernel_pgd: NULL\n"); -+ fprintf(fp, " xendump_p2m_create: NULL\n"); -+ fprintf(fp, "xen_kdump_p2m_create: NULL\n"); ++ fprintf(fp, "xen_kdump_p2m_create: ia64_xen_kdump_p2m_create()\n"); ++ fprintf(fp, " xendump_p2m_create: ia64_xendump_p2m_create()\n"); ++ fprintf(fp, " xendump_panic_task: ia64_xendump_panic_task()\n"); ++ fprintf(fp, " get_xendump_regs: ia64_get_xendump_regs()\n"); fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); fprintf(fp, " line_number_hooks: ia64_line_number_hooks\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); @@ -10722,11 +12959,17 @@ fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); -@@ -664,75 +703,152 @@ - + fprintf(fp, " cmdline_arg: %s\n", machdep->cmdline_arg); ++ fprintf(fp, " section_size_bits: %ld\n", machdep->section_size_bits); ++ fprintf(fp, " max_physmem_bits: %ld\n", machdep->max_physmem_bits); ++ fprintf(fp, " sections_per_root: %ld\n", machdep->sections_per_root); + fprintf(fp, " machspec: ia64_machine_specific\n"); + fprintf(fp, " cpu_data_address: %lx\n", + machdep->machspec->cpu_data_address); +@@ -665,74 +728,148 @@ return (machdep->mhz = mhz); } -- + - -/* - * Translates a user virtual address to its physical address. cmd_vtop() @@ -10760,13 +13003,14 @@ - - *paddr = 0; - region = VADDR_REGION(uvaddr); -+ if(usr){ ++ if (usr) { + region = VADDR_REGION(vaddr); + offset = (vaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); + offset |= (region << (PAGESHIFT() - 6)); + page_dir = pgd + offset; -+ }else{ -+ pgd = (ulong *)vt->kernel_pgd[0]; ++ } else { ++ if (!(pgd = (ulong *)vt->kernel_pgd[0])) ++ error(FATAL, "cannot determine kernel pgd pointer\n"); + page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); + } @@ -10796,6 +13040,7 @@ + pud_pte = ULONG(machdep->pud + PAGEOFFSET(page_upper)); + if (verbose) +- fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); + fprintf(fp, " PUD: %lx => %lx\n", (ulong)page_upper, pud_pte); + + if (!(pud_pte)) @@ -10815,16 +13060,19 @@ + + offset = (vaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); + page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; -+ + +- offset = (uvaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); +- offset |= (region << (PAGESHIFT() - 6)); +- page_dir = pgd + offset; + FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); + pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); + + if (verbose) + fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); -+ + + if (!(pte & (_PAGE_P))) { -+ if(usr) -+ *paddr = pte; ++ if (usr) ++ *paddr = pte; + if (pte && verbose) { + fprintf(fp, "\n"); + ia64_translate_pte(pte, 0, 0); @@ -10840,9 +13088,6 @@ + } + + return TRUE; -+ -+ -+ +} + +/* Generic abstraction to translate user or kernel virtual @@ -10859,24 +13104,20 @@ + ulong pte; + ulong region, offset; + -+ if(usr){ ++ if (usr) { + region = VADDR_REGION(vaddr); + offset = (vaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); + offset |= (region << (PAGESHIFT() - 6)); + page_dir = pgd + offset; -+ }else{ -+ pgd = (ulong *)vt->kernel_pgd[0]; ++ } else { ++ if (!(pgd = (ulong *)vt->kernel_pgd[0])) ++ error(FATAL, "cannot determine kernel pgd pointer\n"); + page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); + } + + if (verbose) - fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); + - -- offset = (uvaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); -- offset |= (region << (PAGESHIFT() - 6)); -- page_dir = pgd + offset; - FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); @@ -10884,7 +13125,6 @@ + if (verbose) fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); - } -+ if (!(pgd_pte)) - goto no_upage; @@ -10910,13 +13150,13 @@ page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); -@@ -742,15 +858,16 @@ +@@ -742,15 +879,16 @@ fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); if (!(pte & (_PAGE_P))) { - *paddr = pte; -+ if(usr) -+ *paddr = pte; ++ if (usr) ++ *paddr = pte; if (pte && verbose) { fprintf(fp, "\n"); ia64_translate_pte(pte, 0, 0); @@ -10930,15 +13170,15 @@ if (verbose) { fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); -@@ -759,9 +876,52 @@ +@@ -758,10 +896,50 @@ + } return TRUE; - --no_upage: +} +-no_upage: + - return FALSE; -+ +/* + * Translates a user virtual address to its physical address. cmd_vtop() + * sets the verbose flag so that the pte translation gets displayed; all @@ -10953,15 +13193,6 @@ +{ + ulong mm; + ulong *pgd; -+/** -+ ulong *page_dir; -+ ulong *page_middle; -+ ulong *page_table; -+ ulong pgd_pte; -+ ulong pmd_pte; -+ ulong pte; -+ ulong offset; -+**/ + + if (!tc) + error(FATAL, "current context invalid\n"); @@ -10977,34 +13208,41 @@ + readmem(tc->mm_struct + OFFSET(mm_struct_pgd), KVADDR, &pgd, + sizeof(long), "mm_struct pgd", FAULT_ON_ERROR); + -+ if (machdep->flags & VM_4_LEVEL) -+ return ia64_vtop_4l(uvaddr, paddr, pgd, verbose, 1); -+ else -+ return ia64_vtop(uvaddr, paddr, pgd, verbose, 1); ++ if (XEN() && (kt->xen_flags & WRITABLE_PAGE_TABLES)) { ++ if (machdep->flags & VM_4_LEVEL) ++ return ia64_vtop_4l_xen_wpt(uvaddr, paddr, pgd, verbose, 1); ++ else ++ return ia64_vtop_xen_wpt(uvaddr, paddr, pgd, verbose, 1); ++ } else { ++ if (machdep->flags & VM_4_LEVEL) ++ return ia64_vtop_4l(uvaddr, paddr, pgd, verbose, 1); ++ else ++ return ia64_vtop(uvaddr, paddr, pgd, verbose, 1); ++ } + } -@@ -774,6 +934,7 @@ +@@ -774,13 +952,6 @@ ia64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbose) { ulong *pgd; -+/** - ulong *page_dir; - ulong *page_middle; - ulong *page_table; -@@ -781,6 +942,7 @@ - ulong pmd_pte; - ulong pte; - ulong offset; -+**/ +- ulong *page_dir; +- ulong *page_middle; +- ulong *page_table; +- ulong pgd_pte; +- ulong pmd_pte; +- ulong pte; +- ulong offset; if (!IS_KVADDR(kvaddr)) return FALSE; -@@ -815,64 +977,11 @@ - - pgd = (ulong *)vt->kernel_pgd[0]; +@@ -813,66 +984,21 @@ + return TRUE; + } +- pgd = (ulong *)vt->kernel_pgd[0]; +- - if (verbose) { - fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); - } @@ -11052,25 +13290,33 @@ - } - - *paddr = (pte & _PFN_MASK) + PAGEOFFSET(kvaddr); -- ++ if (!(pgd = (ulong *)vt->kernel_pgd[0])) ++ error(FATAL, "cannot determine kernel pgd pointer\n"); + - if (verbose) { - fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); - ia64_translate_pte(pte, 0, 0); -- } -- ++ if (XEN() && (kt->xen_flags & WRITABLE_PAGE_TABLES)) { ++ if (machdep->flags & VM_4_LEVEL) ++ return ia64_vtop_4l_xen_wpt(kvaddr, paddr, pgd, verbose, 0); ++ else ++ return ia64_vtop_xen_wpt(kvaddr, paddr, pgd, verbose, 0); ++ } else { ++ if (machdep->flags & VM_4_LEVEL) ++ return ia64_vtop_4l(kvaddr, paddr, pgd, verbose, 0); ++ else ++ return ia64_vtop(kvaddr, paddr, pgd, verbose, 0); + } + - return TRUE; - -no_kpage: -+ if (machdep->flags & VM_4_LEVEL) -+ return ia64_vtop_4l(kvaddr, paddr, pgd, verbose, 0); -+ else -+ return ia64_vtop(kvaddr, paddr, pgd, verbose, 0); - +- - return FALSE; } /* -@@ -2391,9 +2500,10 @@ +@@ -2391,9 +2517,10 @@ if ((ms->mem_limit && (efi_memmap >= ms->mem_limit)) || !readmem(PTOV(efi_memmap), KVADDR, memmap, @@ -11083,7 +13329,7 @@ free(memmap); return; } -@@ -2605,6 +2715,7 @@ +@@ -2605,6 +2732,7 @@ ia64_post_init(void) { struct machine_specific *ms; @@ -11091,7 +13337,7 @@ ms = &ia64_machine_specific; -@@ -2677,9 +2788,10 @@ +@@ -2677,9 +2805,10 @@ } } @@ -11105,9 +13351,310 @@ if (DUMPFILE() && ia64_in_init_stack(SWITCH_STACK_ADDR(CURRENT_TASK()))) machdep->flags |= INIT; ---- crash/s390.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/s390.c 2006-08-02 10:31:22.000000000 -0400 -@@ -158,7 +158,8 @@ +@@ -3326,4 +3455,292 @@ + (vaddr < (ulong)KERNEL_UNCACHED_BASE)); + } + ++/* Generic abstraction to translate user or kernel virtual ++ * addresses to physical using a 4 level page table. ++ */ ++static int ++ia64_vtop_4l_xen_wpt(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr) ++{ ++ error(FATAL, "ia64_vtop_4l_xen_wpt: TBD\n"); ++ return FALSE; ++#ifdef TBD ++ ulong *page_dir; ++ ulong *page_upper; ++ ulong *page_middle; ++ ulong *page_table; ++ ulong pgd_pte; ++ ulong pud_pte; ++ ulong pmd_pte; ++ ulong pte; ++ ulong region, offset; ++ ++ ++ if (usr) { ++ region = VADDR_REGION(vaddr); ++ offset = (vaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); ++ offset |= (region << (PAGESHIFT() - 6)); ++ page_dir = pgd + offset; ++ } else { ++ if (!(pgd = (ulong *)vt->kernel_pgd[0])) ++ error(FATAL, "cannot determine kernel pgd pointer\n"); ++ page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); ++ } ++ ++ if (verbose) ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); ++ ++ FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); ++ pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); ++ ++ if (verbose) ++ fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); ++ ++ if (!(pgd_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PUD_SHIFT) & (PTRS_PER_PUD - 1); ++ page_upper = (ulong *)(PTOV(pgd_pte & _PFN_MASK)) + offset; ++ ++ FILL_PUD(PAGEBASE(page_upper), KVADDR, PAGESIZE()); ++ pud_pte = ULONG(machdep->pud + PAGEOFFSET(page_upper)); ++ ++ if (verbose) ++ fprintf(fp, " PUD: %lx => %lx\n", (ulong)page_upper, pud_pte); ++ ++ if (!(pud_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1); ++ page_middle = (ulong *)(PTOV(pud_pte & _PFN_MASK)) + offset; ++ ++ FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); ++ pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); ++ ++ if (verbose) ++ fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); ++ ++ if (!(pmd_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); ++ page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; ++ ++ FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); ++ pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); ++ ++ if (verbose) ++ fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); ++ ++ if (!(pte & (_PAGE_P))) { ++ if (usr) ++ *paddr = pte; ++ if (pte && verbose) { ++ fprintf(fp, "\n"); ++ ia64_translate_pte(pte, 0, 0); ++ } ++ return FALSE; ++ } ++ ++ *paddr = (pte & _PFN_MASK) + PAGEOFFSET(vaddr); ++ ++ if (verbose) { ++ fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); ++ ia64_translate_pte(pte, 0, 0); ++ } ++ ++ return TRUE; ++#endif ++} ++ ++/* Generic abstraction to translate user or kernel virtual ++ * addresses to physical using a 3 level page table. ++ */ ++static int ++ia64_vtop_xen_wpt(ulong vaddr, physaddr_t *paddr, ulong *pgd, int verbose, int usr) ++{ ++ error(FATAL, "ia64_vtop_xen_wpt: TBD\n"); ++ return FALSE; ++#ifdef TBD ++ ulong *page_dir; ++ ulong *page_middle; ++ ulong *page_table; ++ ulong pgd_pte; ++ ulong pmd_pte; ++ ulong pte; ++ ulong region, offset; ++ ++ ++ if (usr) { ++ region = VADDR_REGION(vaddr); ++ offset = (vaddr >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1); ++ offset |= (region << (PAGESHIFT() - 6)); ++ page_dir = pgd + offset; ++ } else { ++ if (!(pgd = (ulong *)vt->kernel_pgd[0])) ++ error(FATAL, "cannot determine kernel pgd pointer\n"); ++ page_dir = pgd + ((vaddr >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)); ++ } ++ ++ if (verbose) ++ fprintf(fp, "PAGE DIRECTORY: %lx\n", (ulong)pgd); ++ ++ FILL_PGD(PAGEBASE(pgd), KVADDR, PAGESIZE()); ++ pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(page_dir)); ++ ++ if (verbose) ++ fprintf(fp, " PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte); ++ ++ if (!(pgd_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1); ++ page_middle = (ulong *)(PTOV(pgd_pte & _PFN_MASK)) + offset; ++ ++ FILL_PMD(PAGEBASE(page_middle), KVADDR, PAGESIZE()); ++ pmd_pte = ULONG(machdep->pmd + PAGEOFFSET(page_middle)); ++ ++ if (verbose) ++ fprintf(fp, " PMD: %lx => %lx\n", (ulong)page_middle, pmd_pte); ++ ++ if (!(pmd_pte)) ++ return FALSE; ++ ++ offset = (vaddr >> PAGESHIFT()) & (PTRS_PER_PTE - 1); ++ page_table = (ulong *)(PTOV(pmd_pte & _PFN_MASK)) + offset; ++ ++ FILL_PTBL(PAGEBASE(page_table), KVADDR, PAGESIZE()); ++ pte = ULONG(machdep->ptbl + PAGEOFFSET(page_table)); ++ ++ if (verbose) ++ fprintf(fp, " PTE: %lx => %lx\n", (ulong)page_table, pte); ++ ++ if (!(pte & (_PAGE_P))) { ++ if (usr) ++ *paddr = pte; ++ if (pte && verbose) { ++ fprintf(fp, "\n"); ++ ia64_translate_pte(pte, 0, 0); ++ } ++ return FALSE; ++ } ++ ++ *paddr = (pte & _PFN_MASK) + PAGEOFFSET(vaddr); ++ ++ if (verbose) { ++ fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr)); ++ ia64_translate_pte(pte, 0, 0); ++ } ++ ++ return TRUE; ++#endif ++} ++ ++#include "netdump.h" ++ ++/* ++ * From the xen vmcore, create an index of mfns for each page that makes ++ * up the dom0 kernel's complete phys_to_machine_mapping[max_pfn] array. ++ */ ++ ++static int ++ia64_xen_kdump_p2m_create(struct xen_kdump_data *xkd) ++{ ++ error(FATAL, "ia64_xen_kdump_p2m_create: TBD\n"); ++ ++ /* dummy calls for clean "make [wW]arn" */ ++ ia64_xen_kdump_load_page(0, NULL); ++ ia64_xen_kdump_page_mfn(0); ++ ia64_debug_dump_page(NULL, NULL, NULL); ++ ++ return FALSE; ++} ++ ++static char * ++ia64_xen_kdump_load_page(ulong kvaddr, char *pgbuf) ++{ ++ error(FATAL, "ia64_xen_kdump_load_page: TBD\n"); ++ return NULL; ++} ++ ++static ulong ++ia64_xen_kdump_page_mfn(ulong kvaddr) ++{ ++ error(FATAL, "ia64_xen_kdump_page_mfn: TBD\n"); ++ return 0; ++} ++ ++#include "xendump.h" ++ ++/* ++ * Create an index of mfns for each page that makes up the ++ * kernel's complete phys_to_machine_mapping[max_pfn] array. ++ */ ++static int ++ia64_xendump_p2m_create(struct xendump_data *xd) ++{ ++ error(FATAL, "ia64_xendump_p2m_create: TBD\n"); ++ ++ /* dummy calls for clean "make [wW]arn" */ ++ ia64_debug_dump_page(NULL, NULL, NULL); ++ ia64_xendump_load_page(0, xd); ++ ia64_xendump_page_index(0, xd); ++ ia64_xendump_panic_task(xd); /* externally called */ ++ ia64_get_xendump_regs(xd, NULL, NULL, NULL); /* externally called */ ++ ++ return FALSE; ++} ++ ++static void ++ia64_debug_dump_page(FILE *ofp, char *page, char *name) ++{ ++ int i; ++ ulong *up; ++ ++ fprintf(ofp, "%s\n", name); ++ ++ up = (ulong *)page; ++ for (i = 0; i < 1024; i++) { ++ fprintf(ofp, "%016lx: %016lx %016lx\n", ++ (ulong)((i * 2) * sizeof(ulong)), ++ *up, *(up+1)); ++ up += 2; ++ } ++} ++ ++/* ++ * Find the page associate with the kvaddr, and read its contents ++ * into the passed-in buffer. ++ */ ++static char * ++ia64_xendump_load_page(ulong kvaddr, struct xendump_data *xd) ++{ ++ error(FATAL, "ia64_xendump_load_page: TBD\n"); ++ ++ return NULL; ++} ++ ++/* ++ * Find the dumpfile page index associated with the kvaddr. ++ */ ++static int ++ia64_xendump_page_index(ulong kvaddr, struct xendump_data *xd) ++{ ++ error(FATAL, "ia64_xendump_page_index: TBD\n"); ++ ++ return 0; ++} ++ ++static ulong ++ia64_xendump_panic_task(struct xendump_data *xd) ++{ ++ error(INFO, "ia64_xendump_panic_task: TBD\n"); ++ ++ return NO_TASK; ++} ++ ++static void ++ia64_get_xendump_regs(struct xendump_data *xd, struct bt_info *bt, ulong *rip, ulong *rsp) ++{ ++ error(FATAL, "ia64_get_xendump_regs: TBD\n"); ++} + #endif +--- crash/s390.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/s390.c 2006-08-15 09:34:21.000000000 -0400 +@@ -86,7 +86,6 @@ + static ulong s390_processor_speed(void); + static int s390_eframe_search(struct bt_info *); + static void s390_back_trace_cmd(struct bt_info *); +-static void s390_back_trace(struct gnu_request *, struct bt_info *); + static void s390_dump_irq(int); + static void s390_get_stack_frame(struct bt_info *, ulong *, ulong *); + static int s390_dis_filter(ulong, char *); +@@ -158,7 +157,8 @@ machdep->nr_irqs = 0; /* TBD */ machdep->vmalloc_start = s390_vmalloc_start; machdep->dump_irq = s390_dump_irq; @@ -11117,7 +13664,7 @@ break; case POST_INIT: -@@ -178,8 +179,6 @@ +@@ -178,8 +178,6 @@ fprintf(fp, " flags: %lx (", machdep->flags); if (machdep->flags & KSYMS_START) fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); @@ -11126,7 +13673,72 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); -@@ -716,7 +715,9 @@ +@@ -230,19 +228,6 @@ + } + + /* +- * Check if address is in the vmalloc area +- */ +-int +-s390_IS_VMALLOC_ADDR(ulong addr) +-{ +- static unsigned long high_memory = 0; +- if(!high_memory){ +- high_memory = s390_vmalloc_start(); +- } +- return (addr > high_memory); +-} +- +-/* + * Check if address is in context's address space + */ + static int +@@ -293,7 +278,7 @@ + /* + * Check if page is mapped + */ +-inline int ++static inline int + s390_pte_present(unsigned long x) + { + if(THIS_KERNEL_VERSION >= LINUX(2,6,0)) { +@@ -483,7 +468,7 @@ + return FALSE; + } + fprintf(fp,"PTE PHYSICAL FLAGS\n"); +- fprintf(fp,"%08x %08x",pte, pte & S390_PAGE_BASE_MASK); ++ fprintf(fp,"%08lx %08lx",pte, pte & S390_PAGE_BASE_MASK); + fprintf(fp," ("); + if(pte & S390_PAGE_INVALID) + fprintf(fp,"INVALID "); +@@ -510,7 +495,7 @@ + /* + * returns cpu number of task + */ +-int ++static int + s390_cpu_of_task(unsigned long task) + { + int cpu; +@@ -551,7 +536,7 @@ + return FALSE; + } else { + /* Linux 2.6 */ +- unsigned long runqueue_addr, runqueue_offset, per_cpu_offset; ++ unsigned long runqueue_addr, runqueue_offset; + unsigned long cpu_offset, per_cpu_offset_addr, running_task; + char runqueue[4096]; + int cpu; +@@ -700,7 +685,7 @@ + } else if(skip_first_frame){ + skip_first_frame=0; + } else { +- fprintf(fp," #%i [%08x] ",i,backchain); ++ fprintf(fp," #%i [%08lx] ",i,backchain); + fprintf(fp,"%s at %x\n", closest_symbol(r14), r14); + if (bt->flags & BT_LINE_NUMBERS) + s390_dump_line_number(r14); +@@ -716,13 +701,15 @@ frame_size = stack_base - old_backchain + KERNEL_STACK_SIZE; } else { @@ -11137,8 +13749,146 @@ } for(j=0; j< frame_size; j+=4){ if(j % 16 == 0){ ---- crash/s390x.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/s390x.c 2006-08-02 10:31:24.000000000 -0400 +- fprintf(fp,"\n%08x: ",old_backchain+j); ++ fprintf(fp,"\n%08lx: ",old_backchain+j); + } +- fprintf(fp," %08x",ULONG(&stack[old_backchain - ++ fprintf(fp," %08lx",ULONG(&stack[old_backchain - + stack_base + j])); + } + fprintf(fp,"\n\n"); +@@ -771,10 +758,10 @@ + return; + } + fprintf(fp," LOWCORE INFO:\n"); +- fprintf(fp," -psw : %#010x %#010x\n", tmp[0], ++ fprintf(fp," -psw : %#010lx %#010lx\n", tmp[0], + tmp[1]); + if(show_symbols){ +- fprintf(fp," -function : %s at %x\n", ++ fprintf(fp," -function : %s at %lx\n", + closest_symbol(tmp[1] & S390_ADDR_MASK), + tmp[1] & S390_ADDR_MASK); + if (bt->flags & BT_LINE_NUMBERS) +@@ -783,12 +770,12 @@ + ptr = lc + MEMBER_OFFSET("_lowcore","cpu_timer_save_area"); + tmp[0]=UINT(ptr); + tmp[1]=UINT(ptr + S390_WORD_SIZE); +- fprintf(fp," -cpu timer: %#010x %#010x\n", tmp[0],tmp[1]); ++ fprintf(fp," -cpu timer: %#010lx %#010lx\n", tmp[0],tmp[1]); + + ptr = lc + MEMBER_OFFSET("_lowcore","clock_comp_save_area"); + tmp[0]=UINT(ptr); + tmp[1]=UINT(ptr + S390_WORD_SIZE); +- fprintf(fp," -clock cmp: %#010x %#010x\n", tmp[0], tmp[1]); ++ fprintf(fp," -clock cmp: %#010lx %#010lx\n", tmp[0], tmp[1]); + + fprintf(fp," -general registers:\n"); + ptr = lc + MEMBER_OFFSET("_lowcore","gpregs_save_area"); +@@ -796,25 +783,25 @@ + tmp[1]=ULONG(ptr + S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0],tmp[1],tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0],tmp[1],tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 8 * S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 9 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 10* S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 11* S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0],tmp[1],tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 12* S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 13* S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 14* S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 15* S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + + fprintf(fp," -access registers:\n"); +@@ -823,25 +810,25 @@ + tmp[1]=ULONG(ptr + S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 8 * S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 9 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 10* S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 11* S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 12* S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 13* S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 14* S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 15* S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + + fprintf(fp," -control registers:\n"); +@@ -850,26 +837,26 @@ + tmp[1]=ULONG(ptr + S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + + tmp[0]=ULONG(ptr); + tmp[1]=ULONG(ptr + S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390_WORD_SIZE); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + + ptr = lc + MEMBER_OFFSET("_lowcore","floating_pt_save_area"); +@@ -878,8 +865,8 @@ + tmp[1]=ULONG(ptr + 2 * S390_WORD_SIZE); + tmp[2]=ULONG(ptr + 4 * S390_WORD_SIZE); + tmp[3]=ULONG(ptr + 6 * S390_WORD_SIZE); +- fprintf(fp," %#018llx %#018llx\n", tmp[0], tmp[1]); +- fprintf(fp," %#018llx %#018llx\n", tmp[2], tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0], tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2], tmp[3]); + } + + /* +--- crash/s390x.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/s390x.c 2006-08-15 09:34:21.000000000 -0400 @@ -173,7 +173,8 @@ machdep->nr_irqs = 0; /* TBD */ machdep->vmalloc_start = s390x_vmalloc_start; @@ -11158,7 +13908,82 @@ fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); -@@ -749,7 +748,9 @@ +@@ -207,7 +206,8 @@ + fprintf(fp, " hz: %d\n", machdep->hz); + fprintf(fp, " mhz: %ld\n", machdep->mhz); + fprintf(fp, " memsize: %lld (0x%llx)\n", +- machdep->memsize, machdep->memsize); ++ (unsigned long long)machdep->memsize, ++ (unsigned long long)machdep->memsize); + fprintf(fp, " bits: %d\n", machdep->bits); + fprintf(fp, " nr_irqs: %d\n", machdep->nr_irqs); + fprintf(fp, " eframe_search: s390x_eframe_search()\n"); +@@ -245,19 +245,6 @@ + } + + /* +- * Check if address is in the vmalloc area +- */ +-int +-s390x_IS_VMALLOC_ADDR(ulong addr) +-{ +- static unsigned long high_memory = 0; +- if(!high_memory){ +- high_memory = s390x_vmalloc_start(); +- } +- return (addr > high_memory); +-} +- +-/* + * Check if address is in context's address space + */ + static int +@@ -308,7 +295,7 @@ + /* + * Check if page is mapped + */ +-inline int s390x_pte_present(unsigned long x){ ++static inline int s390x_pte_present(unsigned long x){ + if(THIS_KERNEL_VERSION >= LINUX(2,6,0)){ + return !((x) & S390X_PAGE_INVALID) || + ((x) & S390X_PAGE_INVALID_MASK) == S390X_PAGE_INVALID_NONE; +@@ -514,7 +501,7 @@ + return FALSE; + } + fprintf(fp,"PTE PHYSICAL FLAGS\n"); +- fprintf(fp,"%08x %08x",pte, pte & S390X_PAGE_BASE_MASK); ++ fprintf(fp,"%08lx %08llx",pte, pte & S390X_PAGE_BASE_MASK); + fprintf(fp," ("); + if(pte & S390X_PAGE_INVALID) + fprintf(fp,"INVALID "); +@@ -541,7 +528,7 @@ + /* + * returns cpu number of task + */ +-int ++static int + s390x_cpu_of_task(unsigned long task) + { + unsigned int cpu; +@@ -583,7 +570,7 @@ + return FALSE; + } else { + /* Linux 2.6 */ +- unsigned long runqueue_addr, runqueue_offset, per_cpu_offset; ++ unsigned long runqueue_addr, runqueue_offset; + unsigned long cpu_offset, per_cpu_offset_addr, running_task; + char runqueue[4096]; + int cpu; +@@ -733,7 +720,7 @@ + } else if(skip_first_frame){ + skip_first_frame=0; + } else { +- fprintf(fp," #%i [%08x] ",i,backchain); ++ fprintf(fp," #%i [%08lx] ",i,backchain); + fprintf(fp,"%s at %x\n", closest_symbol(r14), r14); + if (bt->flags & BT_LINE_NUMBERS) + s390x_dump_line_number(r14); +@@ -749,13 +736,15 @@ frame_size = stack_base - old_backchain + KERNEL_STACK_SIZE; } else { @@ -11169,8 +13994,1526 @@ } for(j=0; j< frame_size; j+=4){ if(j % 16 == 0){ ---- crash/ppc64.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/ppc64.c 2006-08-02 10:31:29.000000000 -0400 +- fprintf(fp,"\n%08x: ",old_backchain+j); ++ fprintf(fp,"\n%08lx: ",old_backchain+j); + } +- fprintf(fp," %08x",ULONG(&stack[old_backchain - ++ fprintf(fp," %08lx",ULONG(&stack[old_backchain - + stack_base + j])); + } + fprintf(fp,"\n\n"); +@@ -804,26 +793,26 @@ + return; + } + fprintf(fp," LOWCORE INFO:\n"); +- fprintf(fp," -psw : %#018x %#018x\n", tmp[0], tmp[1]); ++ fprintf(fp," -psw : %#018lx %#018lx\n", tmp[0], tmp[1]); + if(show_symbols){ +- fprintf(fp," -function : %s at %x\n", ++ fprintf(fp," -function : %s at %lx\n", + closest_symbol(tmp[1]), tmp[1]); + if (bt->flags & BT_LINE_NUMBERS) + s390x_dump_line_number(tmp[1]); + } + ptr = lc + MEMBER_OFFSET("_lowcore","prefixreg_save_area"); + tmp[0] = UINT(ptr); +- fprintf(fp," -prefix : %#010x\n", tmp[0]); ++ fprintf(fp," -prefix : %#010lx\n", tmp[0]); + + ptr = lc + MEMBER_OFFSET("_lowcore","cpu_timer_save_area"); + tmp[0]=UINT(ptr); + tmp[1]=UINT(ptr + S390X_WORD_SIZE); +- fprintf(fp," -cpu timer: %#010x %#010x\n", tmp[0],tmp[1]); ++ fprintf(fp," -cpu timer: %#010lx %#010lx\n", tmp[0],tmp[1]); + + ptr = lc + MEMBER_OFFSET("_lowcore","clock_comp_save_area"); + tmp[0]=UINT(ptr); + tmp[1]=UINT(ptr + S390X_WORD_SIZE); +- fprintf(fp," -clock cmp: %#010x %#010x\n", tmp[0], tmp[1]); ++ fprintf(fp," -clock cmp: %#010lx %#010lx\n", tmp[0], tmp[1]); + + fprintf(fp," -general registers:\n"); + ptr = lc + MEMBER_OFFSET("_lowcore","gpregs_save_area"); +@@ -831,26 +820,26 @@ + tmp[1]=ULONG(ptr + S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 8 * S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 9 * S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 10* S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 11* S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 12* S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 13* S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 14* S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 15* S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + + fprintf(fp," -access registers:\n"); + ptr = lc + MEMBER_OFFSET("_lowcore","access_regs_save_area"); +@@ -858,25 +847,25 @@ + tmp[1]=ULONG(ptr + 4); + tmp[2]=ULONG(ptr + 2 * 4); + tmp[3]=ULONG(ptr + 3 * 4); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 4 * 4); + tmp[1]=ULONG(ptr + 5 * 4); + tmp[2]=ULONG(ptr + 6 * 4); + tmp[3]=ULONG(ptr + 7 * 4); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 8 * 4); + tmp[1]=ULONG(ptr + 9 * 4); + tmp[2]=ULONG(ptr + 10* 4); + tmp[3]=ULONG(ptr + 11* 4); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + tmp[0]=ULONG(ptr + 12* 4); + tmp[1]=ULONG(ptr + 13* 4); + tmp[2]=ULONG(ptr + 14* 4); + tmp[3]=ULONG(ptr + 15* 4); +- fprintf(fp," %#010x %#010x %#010x %#010x\n", ++ fprintf(fp," %#010lx %#010lx %#010lx %#010lx\n", + tmp[0], tmp[1], tmp[2], tmp[3]); + + fprintf(fp," -control registers:\n"); +@@ -885,26 +874,26 @@ + tmp[1]=ULONG(ptr + S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr); + tmp[1]=ULONG(ptr + S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + + ptr = lc + MEMBER_OFFSET("_lowcore","floating_pt_save_area"); + fprintf(fp," -floating point registers 0,2,4,6:\n"); +@@ -912,26 +901,26 @@ + tmp[1]=ULONG(ptr + S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 2 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 3 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 4 * S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 5 * S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 6 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 7 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 6 * S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 7 * S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 8 * S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 9 * S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + tmp[0]=ULONG(ptr + 10* S390X_WORD_SIZE); + tmp[1]=ULONG(ptr + 11* S390X_WORD_SIZE); + tmp[2]=ULONG(ptr + 12* S390X_WORD_SIZE); + tmp[3]=ULONG(ptr + 13* S390X_WORD_SIZE); +- fprintf(fp," %#018x %#018x\n", tmp[0],tmp[1]); +- fprintf(fp," %#018x %#018x\n", tmp[2],tmp[3]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[0],tmp[1]); ++ fprintf(fp," %#018lx %#018lx\n", tmp[2],tmp[3]); + } + + /* +--- crash/s390dbf.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/s390dbf.c 2006-08-14 13:58:56.000000000 -0400 +@@ -0,0 +1,1340 @@ ++/* ++ * s390 debug feature command for crash ++ * ++ * Copyright (C) IBM Corp. 2006 ++ * Author(s): Michael Holzheu ++ */ ++ ++#if defined(S390) || defined(S390X) ++ ++#include "defs.h" ++#include ++#include ++ ++/* ++ * Compat layer to integrate lcrash commands into crash ++ * Maps lcrash API to crash functions ++ */ ++ ++#define KL_NBPW sizeof(long) ++#define KL_ERRORFP stderr ++#define MAX_ARGS 128 ++#define MAX_CMDLINE 256 ++ ++#define C_FALSE 0x00000001 /* Command takes no arguments */ ++#define C_TRUE 0x00000002 /* Command requires arguments */ ++#define C_ALL 0x00000004 /* All elements */ ++#define C_PERM 0x00000008 /* Allocate perminant blocks */ ++#define C_TEMP 0x00000000 /* For completeness */ ++#define C_FULL 0x00000010 /* Full output */ ++#define C_LIST 0x00000020 /* List items */ ++#define C_NEXT 0x00000040 /* Follow links */ ++#define C_WRITE 0x00000080 /* Write output to file */ ++#define C_NO_OPCHECK 0x00000100 /* Don't reject bad cmd line options */ ++#define C_ITER 0x00000200 /* set iteration threshold */ ++ ++#define C_LFLG_SHFT 12 ++ ++#define KL_ARCH_S390 0 ++#define KL_ARCH_S390X 1 ++#ifdef __s390x__ ++#define KL_ARCH KL_ARCH_S390X ++#define FMTPTR "l" ++#define KL_PTRSZ 8 ++#else ++#define KL_ARCH KL_ARCH_S390 ++#define FMTPTR "ll" ++#define KL_PTRSZ 4 ++#endif ++ ++typedef unsigned long uaddr_t; ++typedef unsigned long kaddr_t; ++ ++typedef struct _syment { ++ char *s_name; ++ kaddr_t s_addr; ++} syment_t; ++ ++typedef struct option_s { ++ struct option_s *op_next; ++ char op_char; ++ char *op_arg; ++} option_t; ++ ++typedef struct command_s { ++ int flags; ++ char cmdstr[MAX_CMDLINE]; ++ char *command; ++ char *cmdline; ++ option_t *options; ++ int nargs; ++ char *args[MAX_ARGS]; ++ char *pipe_cmd; ++ FILE *ofp; ++ FILE *efp; ++} command_t; ++ ++static inline syment_t* kl_lkup_symaddr(kaddr_t addr) ++{ ++ static syment_t sym; ++ struct syment *crash_sym; ++ ++ crash_sym = value_search(addr, &sym.s_addr); ++ if (!crash_sym) ++ return NULL; ++ sym.s_name = crash_sym->name; ++ return &sym; ++} ++ ++static inline syment_t* kl_lkup_symname(char* name) ++{ ++ static syment_t sym; ++ sym.s_addr = symbol_value(name); ++ sym.s_name = NULL; ++ if(!sym.s_addr) ++ return NULL; ++ else ++ return &sym; ++} ++ ++static inline void GET_BLOCK(kaddr_t addr, int size, void* ptr) ++{ ++ readmem(addr, KVADDR,ptr,size,"GET_BLOCK",FAULT_ON_ERROR); ++} ++ ++static inline kaddr_t KL_VREAD_PTR(kaddr_t addr) ++{ ++ unsigned long ptr; ++ readmem(addr, KVADDR,&ptr,sizeof(ptr),"GET_BLOCK",FAULT_ON_ERROR); ++ return (kaddr_t)ptr; ++} ++ ++static inline uint32_t KL_GET_UINT32(void* ptr) ++{ ++ return *((uint32_t*)ptr); ++} ++ ++static inline uint64_t KL_GET_UINT64(void* ptr) ++{ ++ return *((uint64_t*)ptr); ++} ++ ++static inline kaddr_t KL_GET_PTR(void* ptr) ++{ ++ return *((kaddr_t*)ptr); ++} ++ ++static inline void* K_PTR(void* addr, char* struct_name, char* member_name) ++{ ++ return addr+MEMBER_OFFSET(struct_name,member_name); ++} ++ ++static inline uint32_t KL_UINT(void* ptr, char* struct_name, char* member_name) ++{ ++ return (uint32_t) ULONG(ptr+MEMBER_OFFSET(struct_name,member_name)); ++} ++ ++static inline uint32_t KL_VREAD_UINT32(kaddr_t addr) ++{ ++ uint32_t rc; ++ readmem(addr, KVADDR,&rc,sizeof(rc),"KL_VREAD_UINT32",FAULT_ON_ERROR); ++ return rc; ++} ++ ++static inline uint32_t KL_INT(void* ptr, char* struct_name, char* member_name) ++{ ++ return UINT(ptr+MEMBER_OFFSET(struct_name,member_name)); ++} ++ ++static inline int set_cmd_flags(command_t *cmd, int flags, char *extraops) ++{ ++ return 0; ++} ++ ++static inline void kl_s390tod_to_timeval(uint64_t todval, struct timeval *xtime) ++{ ++ todval -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); ++ ++ todval >>= 12; ++ xtime->tv_sec = todval / 1000000; ++ xtime->tv_usec = todval % 1000000; ++} ++ ++static inline int kl_struct_len(char* struct_name) ++{ ++ return STRUCT_SIZE(struct_name); ++} ++ ++static inline kaddr_t kl_funcaddr(kaddr_t addr) ++{ ++ struct syment *crash_sym; ++ ++ crash_sym = value_search(addr, &addr); ++ if (!crash_sym) ++ return -1; ++ else ++ return crash_sym->value; ++} ++ ++#define CMD_USAGE(cmd, s) \ ++ fprintf(cmd->ofp, "Usage: %s %s\n", cmd->command, s); \ ++ fprintf(cmd->ofp, "Enter \"help %s\" for details.\n",cmd->command); ++ ++/* ++ * s390 debug feature implementation ++ */ ++ ++#ifdef DBF_DYNAMIC_VIEWS /* views defined in shared libs */ ++#include ++#endif ++ ++/* Local flags ++ */ ++ ++#define LOAD_FLAG (1 << C_LFLG_SHFT) ++#define VIEWS_FLAG (2 << C_LFLG_SHFT) ++ ++#ifndef MIN ++#define MIN(a,b) (((a)<(b))?(a):(b)) ++#endif ++ ++/* Stuff which has to match with include/asm-s390/debug.h */ ++ ++#define DBF_VERSION_V1 1 ++#define DBF_VERSION_V2 2 ++#define PAGE_SIZE 4096 ++#define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ ++#define DEBUG_MAX_PROCF_LEN 16 /* max length for a proc file name */ ++#define DEBUG_SPRINTF_MAX_ARGS 10 ++ ++/* define debug-structures for lcrash */ ++#define DEBUG_DATA(entry) (char*)(entry + 1) ++ ++typedef struct debug_view_s debug_view_t; ++ ++/* struct to hold contents of struct __debug_entry from dump ++ */ ++typedef struct debug_entry_s{ ++ union { ++ struct { ++ unsigned long long clock:52; ++ unsigned long long exception:1; ++ unsigned long long level:3; ++ unsigned long long cpuid:8; ++ } fields; ++ ++ unsigned long long stck; ++ } id; ++ kaddr_t caller; /* changed from void* to kaddr_t */ ++} __attribute__((packed)) debug_entry_t; ++/* typedef struct __debug_entry debug_entry_t; */ ++ ++ ++static unsigned int dbf_version; ++ ++/* struct is used to manage contents of structs debug_info from dump ++ * in lcrash ++ */ ++typedef struct debug_info_s { ++ struct debug_info_s *next; ++ struct debug_info_s *prev; ++ kaddr_t next_dbi; /* store next ptr of struct in dump */ ++ kaddr_t prev_dbi; /* store prev ptr of struct in dump */ ++ int level; ++ int nr_areas; ++ int page_order; ++ int buf_size; ++ int entry_size; ++ void **areas; /* contents of debug areas from dump */ ++ int active_area; ++ int *active_entry; /* change to uint32_t ? */ ++ debug_view_t *views[DEBUG_MAX_VIEWS]; ++ char name[DEBUG_MAX_PROCF_LEN]; ++ kaddr_t addr; ++ int pages_per_area_v2; ++ void ***areas_v2; ++} debug_info_t; ++ ++ ++/* functions to generate dbf output ++ */ ++typedef int (debug_header_proc_t) (debug_info_t* id, debug_view_t* view, ++ int area, debug_entry_t* entry, ++ char* out_buf); ++typedef int (debug_format_proc_t) (debug_info_t* id, debug_view_t* view, ++ char* out_buf, const char* in_buf); ++typedef int (debug_prolog_proc_t) (debug_info_t* id, debug_view_t* view, ++ char* out_buf); ++ ++struct debug_view_s { ++ char name[DEBUG_MAX_PROCF_LEN]; ++ debug_prolog_proc_t* prolog_proc; ++ debug_header_proc_t* header_proc; ++ debug_format_proc_t* format_proc; ++ void* private_data; ++}; ++ ++#define LCRASH_DB_VIEWS 1000 ++ ++static debug_info_t *debug_area_first = NULL; ++static debug_info_t *debug_area_last = NULL; ++static debug_view_t *debug_views[LCRASH_DB_VIEWS]; ++static int initialized = 0; ++static iconv_t ebcdic_ascii_conv = 0; ++ ++void s390dbf_usage(command_t * cmd); ++static int add_lcrash_debug_view(debug_view_t *); ++static int dbe_size = 0; ++ ++static void ++EBCASC(char *inout, size_t len) ++{ ++ iconv(ebcdic_ascii_conv, &inout, &len, &inout, &len); ++} ++ ++/* ++ * prints header for debug entry ++ */ ++static int ++dflt_header_fn(debug_info_t * id, debug_view_t *view, ++ int area, debug_entry_t * entry, char *out_buf) ++{ ++ struct timeval time_val; ++ unsigned long long time; ++ char *except_str; ++ kaddr_t caller; ++ int rc = 0; ++ char *caller_name; ++ int offset; ++ char caller_buf[30]; ++ unsigned int level; ++ syment_t *caller_sym; ++ debug_entry_t lentry; /* store byte swapped values of entry */ ++ ++ lentry.id.stck = KL_GET_UINT64(&entry->id); ++ lentry.caller = KL_GET_PTR(&entry->caller); ++ level = lentry.id.fields.level; ++ time = lentry.id.stck; ++ ++ kl_s390tod_to_timeval(time, &time_val); ++ ++ if (lentry.id.fields.exception) ++ except_str = "*"; ++ else ++ except_str = "-"; ++ caller = lentry.caller; ++ if(KL_ARCH == KL_ARCH_S390){ ++ caller &= 0x7fffffff; ++ } ++ caller_sym = kl_lkup_symaddr(caller); ++ if(caller_sym){ ++ caller_name = caller_sym->s_name; ++ offset = caller - kl_funcaddr(caller); ++ } ++ else { ++ sprintf(caller_buf, "%llx", (unsigned long long)caller); ++ caller_name = caller_buf; ++ offset = 0; ++ } ++ ++ if(KL_ARCH == KL_ARCH_S390X){ ++ rc += sprintf(out_buf, ++ "%02i %011lu:%06lu %1u %1s %02i <%20s+%04i> ", ++ area, time_val.tv_sec, time_val.tv_usec, level, ++ except_str, entry->id.fields.cpuid, caller_name, ++ offset); ++ } else { ++ rc += sprintf(out_buf, ++ "%02i %011lu:%06lu %1u %1s %02i <%-20s+%04i> ", ++ area, time_val.tv_sec, time_val.tv_usec, level, ++ except_str, lentry.id.fields.cpuid, caller_name, ++ offset); ++ } ++ return rc; ++} ++ ++/* ++ * prints debug header in raw format ++ */ ++static int ++raw_header_fn(debug_info_t * id, debug_view_t *view, ++ int area, debug_entry_t * entry, char *out_buf) ++{ ++ int rc; ++ ++ rc = sizeof(debug_entry_t); ++ if (out_buf == NULL) ++ goto out; ++ memcpy(out_buf,entry,sizeof(debug_entry_t)); ++ out: ++ return rc; ++} ++ ++/* ++ * prints debug data in raw format ++ */ ++static int ++raw_format_fn(debug_info_t * id, debug_view_t *view, ++ char *out_buf, const char *in_buf) ++{ ++ int rc; ++ ++ rc = id->buf_size; ++ if (out_buf == NULL || in_buf == NULL) ++ goto out; ++ memcpy(out_buf, in_buf, id->buf_size); ++ out: ++ return rc; ++} ++ ++/* ++ * prints debug data in hex/ascii format ++ */ ++static int ++hex_ascii_format_fn(debug_info_t * id, debug_view_t *view, ++ char *out_buf, const char *in_buf) ++{ ++ int i, rc = 0; ++ ++ if (out_buf == NULL || in_buf == NULL) { ++ rc = id->buf_size * 4 + 3; ++ goto out; ++ } ++ for (i = 0; i < id->buf_size; i++) { ++ rc += sprintf(out_buf + rc, "%02x ", ++ ((unsigned char *) in_buf)[i]); ++ } ++ rc += sprintf(out_buf + rc, "| "); ++ for (i = 0; i < id->buf_size; i++) { ++ unsigned char c = in_buf[i]; ++ if (!isprint(c)) ++ rc += sprintf(out_buf + rc, "."); ++ else ++ rc += sprintf(out_buf + rc, "%c", c); ++ } ++ rc += sprintf(out_buf + rc, "\n"); ++ out: ++ return rc; ++} ++ ++/* ++ * prints debug data in sprintf format ++ */ ++static int ++sprintf_format_fn(debug_info_t * id, debug_view_t *view, ++ char *out_buf, const char *in_buf) ++{ ++#define _BUFSIZE 1024 ++ char buf[_BUFSIZE]; ++ int i, k, rc = 0, num_longs = 0, num_used_args = 0, num_strings = 0; ++ /* use kaddr_t to store long values of 32bit and 64bit archs here */ ++ kaddr_t inbuf_cpy[DEBUG_SPRINTF_MAX_ARGS]; ++ /* store ptrs to strings to be deallocated at end of this function */ ++ uaddr_t to_dealloc[DEBUG_SPRINTF_MAX_ARGS]; ++ kaddr_t addr; ++ ++ memset(buf, 0, sizeof(buf)); ++ memset(inbuf_cpy, 0, sizeof(inbuf_cpy)); ++ memset(to_dealloc, 0, sizeof(to_dealloc)); ++ ++ if (out_buf == NULL || in_buf == NULL) { ++ rc = id->buf_size * 4 + 3; ++ goto out; ++ } ++ ++ /* get the format string into buf */ ++ addr = KL_GET_PTR((void*)in_buf); ++ GET_BLOCK(addr, _BUFSIZE, buf); ++ ++ k = 0; ++ for (i = 0; buf[i] && (buf[i] != '\n'); i++) { ++ if (buf[i] != '%') ++ continue; ++ if (k == DEBUG_SPRINTF_MAX_ARGS) { ++ fprintf(KL_ERRORFP, ++ "\nToo much parameters in sprinf view (%i)\n" ++ ,k + 1); ++ fprintf(KL_ERRORFP, "Format String: %s)\n", buf); ++ break; ++ } ++ /* for sprintf we have only unsigned long values ... */ ++ if (buf[i+1] != 's'){ ++ /* we use KL_GET_PTR here to read ulong value */ ++ addr = KL_GET_PTR((void*) in_buf + ((k + 1)* KL_NBPW)); ++ inbuf_cpy[k] = addr; ++ } else { /* ... or ptrs to strings in debug areas */ ++ inbuf_cpy[k] = (uaddr_t) malloc(_BUFSIZE); ++ to_dealloc[num_strings++] = inbuf_cpy[k]; ++ addr = KL_GET_PTR((void*) in_buf + ((k + 1)* KL_NBPW)); ++ GET_BLOCK(addr, _BUFSIZE, ++ (void*)(uaddr_t)(inbuf_cpy[k])); ++ } ++ k++; ++ } ++ ++ /* count of longs fit into one entry */ ++ num_longs = id->buf_size / KL_NBPW; /* sizeof(long); */ ++ if(num_longs < 1) /* bufsize of entry too small */ ++ goto out; ++ if(num_longs == 1) { /* no args, just print the format string */ ++ rc = sprintf(out_buf + rc, "%s", buf); ++ goto out; ++ } ++ ++ /* number of arguments used for sprintf (without the format string) */ ++ num_used_args = MIN(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1)); ++ ++ rc = sprintf(out_buf + rc, buf, (uaddr_t)(inbuf_cpy[0]), ++ (uaddr_t)(inbuf_cpy[1]), (uaddr_t)(inbuf_cpy[2]), ++ (uaddr_t)(inbuf_cpy[3]), (uaddr_t)(inbuf_cpy[4]), ++ (uaddr_t)(inbuf_cpy[5]), (uaddr_t)(inbuf_cpy[6]), ++ (uaddr_t)(inbuf_cpy[7]), (uaddr_t)(inbuf_cpy[8]), ++ (uaddr_t)(inbuf_cpy[9])); ++ out: ++ while (num_strings--){ ++ free((char*)(to_dealloc[num_strings])); ++ } ++ return rc; ++} ++ ++ ++/*********************************** ++ * functions for debug-views ++ ***********************************/ ++ ++/* ++ * prints out actual debug level ++ */ ++static int ++prolog_level_fn(debug_info_t * id, ++ debug_view_t *view, char *out_buf) ++{ ++ int rc = 0; ++ ++ if (out_buf == NULL) { ++ rc = 2; ++ goto out; ++ } ++ rc = sprintf(out_buf, "%i\n", id->level); ++ out: ++ return rc; ++} ++ ++/* ++ * prints out actual pages_per_area ++ */ ++static int ++prolog_pages_fn(debug_info_t * id, ++ debug_view_t *view, char *out_buf) ++{ ++ int rc = 0; ++ ++ if (out_buf == NULL) { ++ rc = 2; ++ goto out; ++ } ++ rc = sprintf(out_buf, "%i\n", id->pages_per_area_v2); ++ out: ++ return rc; ++} ++ ++/* ++ * prints out prolog ++ */ ++static int ++prolog_fn(debug_info_t * id, ++ debug_view_t *view, char *out_buf) ++{ ++ int rc = 0; ++ ++ rc = sprintf(out_buf, "AREA TIME LEVEL EXCEPTION CP CALLING FUNCTION" ++ " + OFFSET DATA\n===================================" ++ "=======================================\n"); ++ return rc; ++} ++ ++/* ++ * prints debug data in hex format ++ */ ++static int ++hex_format_fn(debug_info_t * id, debug_view_t *view, ++ char *out_buf, const char *in_buf) ++{ ++ int i, rc = 0; ++ ++ for (i = 0; i < id->buf_size; i++) { ++ rc += sprintf(out_buf + rc, "%02x ", ++ ((unsigned char *) in_buf)[i]); ++ } ++ rc += sprintf(out_buf + rc, "\n"); ++ return rc; ++} ++ ++/* ++ * prints debug data in ascii format ++ */ ++static int ++ascii_format_fn(debug_info_t * id, debug_view_t *view, ++ char *out_buf, const char *in_buf) ++{ ++ int i, rc = 0; ++ ++ if (out_buf == NULL || in_buf == NULL) { ++ rc = id->buf_size + 1; ++ goto out; ++ } ++ for (i = 0; i < id->buf_size; i++) { ++ unsigned char c = in_buf[i]; ++ if (!isprint(c)) ++ rc += sprintf(out_buf + rc, "."); ++ else ++ rc += sprintf(out_buf + rc, "%c", c); ++ } ++ rc += sprintf(out_buf + rc, "\n"); ++ out: ++ return rc; ++} ++ ++/* ++ * prints debug data in ebcdic format ++ */ ++static int ++ebcdic_format_fn(debug_info_t * id, debug_view_t *view, ++ char *out_buf, const char *in_buf) ++{ ++ int i, rc = 0; ++ ++ if (out_buf == NULL || in_buf == NULL) { ++ rc = id->buf_size + 1; ++ goto out; ++ } ++ for (i = 0; i < id->buf_size; i++) { ++ char c = in_buf[i]; ++ EBCASC(&c, 1); ++ if (!isprint(c)) ++ rc += sprintf(out_buf + rc, "."); ++ else ++ rc += sprintf(out_buf + rc, "%c", c); ++ } ++ rc += sprintf(out_buf + rc, "\n"); ++ out: ++ return rc; ++} ++ ++debug_view_t ascii_view = { ++ "ascii", ++ &prolog_fn, ++ &dflt_header_fn, ++ &ascii_format_fn, ++}; ++ ++debug_view_t ebcdic_view = { ++ "ebcdic", ++ &prolog_fn, ++ &dflt_header_fn, ++ &ebcdic_format_fn, ++}; ++ ++debug_view_t hex_view = { ++ "hex", ++ &prolog_fn, ++ &dflt_header_fn, ++ &hex_format_fn, ++}; ++ ++debug_view_t level_view = { ++ "level", ++ &prolog_level_fn, ++ NULL, ++ NULL, ++}; ++ ++debug_view_t pages_view = { ++ "pages", ++ &prolog_pages_fn, ++ NULL, ++ NULL, ++}; ++ ++debug_view_t raw_view = { ++ "raw", ++ NULL, ++ &raw_header_fn, ++ &raw_format_fn, ++}; ++ ++debug_view_t hex_ascii_view = { ++ "hex_ascii", ++ &prolog_fn, ++ &dflt_header_fn, ++ &hex_ascii_format_fn, ++}; ++ ++debug_view_t sprintf_view = { ++ "sprintf", ++ &prolog_fn, ++ &dflt_header_fn, ++ &sprintf_format_fn, ++}; ++ ++ ++static debug_entry_t * ++debug_find_oldest_entry(debug_entry_t *entries, int num, int entry_size) ++{ ++ debug_entry_t *result, *current; ++ int i; ++ uint64_t clock1, clock2; ++ ++ result = entries; ++ current = entries; ++ for (i=0; i < num; i++) { ++ if (current->id.stck == 0) ++ break; ++ clock1 = current->id.fields.clock; ++ clock2 = result->id.fields.clock; ++ clock1 = KL_GET_UINT64(&clock1); ++ clock2 = KL_GET_UINT64(&clock2); ++ if (clock1 < clock2) ++ result = current; ++ current = (debug_entry_t *) ((char *) current + entry_size); ++ } ++ return result; ++} ++ ++ ++/* ++ * debug_format_output: ++ * - calls prolog, header and format functions of view to format output ++ */ ++static int ++debug_format_output_v1(debug_info_t * debug_area, debug_view_t *view, ++ FILE * ofp) ++{ ++ int i, j, len; ++ int nr_of_entries; ++ debug_entry_t *act_entry, *last_entry; ++ char *act_entry_data; ++ char buf[2048]; ++ ++ /* print prolog */ ++ if (view->prolog_proc) { ++ len = view->prolog_proc(debug_area, view, buf); ++ fwrite(buf,len, 1, ofp); ++ memset(buf, 0, 2048); ++ } ++ /* print debug records */ ++ if (!(view->format_proc) && !(view->header_proc)) ++ goto out; ++ if(debug_area->entry_size <= 0){ ++ fprintf(ofp, "Invalid entry_size: %i\n",debug_area->entry_size); ++ goto out; ++ } ++ nr_of_entries = (PAGE_SIZE << debug_area->page_order) / debug_area->entry_size; ++ for (i = 0; i < debug_area->nr_areas; i++) { ++ act_entry = debug_find_oldest_entry(debug_area->areas[i], ++ nr_of_entries, ++ debug_area->entry_size); ++ last_entry = (debug_entry_t *) ((char *) debug_area->areas[i] + ++ (PAGE_SIZE << debug_area->page_order) - ++ debug_area->entry_size); ++ for (j = 0; j < nr_of_entries; j++) { ++ act_entry_data = (char*)act_entry + dbe_size; ++ if (act_entry->id.stck == 0) ++ break; /* empty entry */ ++ if (view->header_proc) { ++ len = view->header_proc(debug_area, view, i, ++ act_entry, buf); ++ fwrite(buf,len, 1, ofp); ++ memset(buf, 0, 2048); ++ } ++ if (view->format_proc) { ++ len = view->format_proc(debug_area, view, ++ buf, act_entry_data); ++ fwrite(buf,len, 1, ofp); ++ memset(buf, 0, 2048); ++ } ++ act_entry = ++ (debug_entry_t *) (((char *) act_entry) + ++ debug_area->entry_size); ++ if (act_entry > last_entry) ++ act_entry = debug_area->areas[i]; ++ } ++ } ++ out: ++ return 1; ++} ++ ++/* ++ * debug_format_output_v2: ++ * - calls prolog, header and format functions of view to format output ++ */ ++static int ++debug_format_output_v2(debug_info_t * debug_area, ++ debug_view_t *view, FILE * ofp) ++{ ++ int i, j, k, len; ++ debug_entry_t *act_entry; ++ char *act_entry_data; ++ char buf[2048]; ++ ++ /* print prolog */ ++ if (view->prolog_proc) { ++ len = view->prolog_proc(debug_area, view, buf); ++ fwrite(buf,len, 1, ofp); ++ memset(buf, 0, 2048); ++ } ++ /* print debug records */ ++ if (!(view->format_proc) && !(view->header_proc)) ++ goto out; ++ if(debug_area->entry_size <= 0){ ++ fprintf(ofp, "Invalid entry_size: %i\n",debug_area->entry_size); ++ goto out; ++ } ++ for (i = 0; i < debug_area->nr_areas; i++) { ++ int nr_entries_per_page = PAGE_SIZE/debug_area->entry_size; ++ for (j = 0; j < debug_area->pages_per_area_v2; j++) { ++ act_entry = debug_area->areas_v2[i][j]; ++ for (k = 0; k < nr_entries_per_page; k++) { ++ act_entry_data = (char*)act_entry + dbe_size; ++ if (act_entry->id.stck == 0) ++ break; /* empty entry */ ++ if (view->header_proc) { ++ len = view->header_proc(debug_area, ++ view, i, act_entry, buf); ++ fwrite(buf,len, 1, ofp); ++ memset(buf, 0, 2048); ++ } ++ if (view->format_proc) { ++ len = view->format_proc(debug_area, ++ view, buf, act_entry_data); ++ fwrite(buf,len, 1, ofp); ++ memset(buf, 0, 2048); ++ } ++ act_entry = (debug_entry_t *) (((char *) ++ act_entry) + debug_area->entry_size); ++ } ++ } ++ } ++out: ++ return 1; ++} ++ ++static debug_info_t * ++find_debug_area(const char *area_name) ++{ ++ debug_info_t* act_debug_info = debug_area_first; ++ while(act_debug_info != NULL){ ++ if (strcmp(act_debug_info->name, area_name) == 0) ++ return act_debug_info; ++ act_debug_info = act_debug_info->next; ++ } ++ return NULL; ++} ++ ++static void ++dbf_init(void) ++{ ++ if (!initialized) { ++ if(dbf_version >= DBF_VERSION_V2) ++ add_lcrash_debug_view(&pages_view); ++ add_lcrash_debug_view(&ascii_view); ++ add_lcrash_debug_view(&level_view); ++ add_lcrash_debug_view(&ebcdic_view); ++ add_lcrash_debug_view(&hex_view); ++ add_lcrash_debug_view(&hex_ascii_view); ++ add_lcrash_debug_view(&sprintf_view); ++ add_lcrash_debug_view(&raw_view); ++ ebcdic_ascii_conv = iconv_open("ISO-8859-1", "EBCDIC-US"); ++ initialized = 1; ++ } ++} ++ ++static debug_view_t* ++get_debug_view(kaddr_t addr) ++{ ++ void* k_debug_view; ++ int k_debug_view_size; ++ debug_view_t* rc; ++ ++ rc = (debug_view_t*)malloc(sizeof(debug_view_t)); ++ memset(rc, 0, sizeof(debug_view_t)); ++ ++ k_debug_view_size = kl_struct_len("debug_view"); ++ k_debug_view = malloc(k_debug_view_size); ++ GET_BLOCK(addr, k_debug_view_size, k_debug_view); ++ strncpy(rc->name,K_PTR(k_debug_view,"debug_view","name"), ++ DEBUG_MAX_PROCF_LEN); ++ ++ free(k_debug_view); ++ return rc; ++} ++ ++static void ++free_debug_view(debug_view_t* view) ++{ ++ if(view) ++ free(view); ++} ++ ++static void ++debug_get_areas_v1(debug_info_t* db_info, void* k_dbi) ++{ ++ kaddr_t mem_pos; ++ kaddr_t dbe_addr; ++ int area_size, i; ++ ++ /* get areas */ ++ /* place to hold ptrs to debug areas in lcrash */ ++ area_size = PAGE_SIZE << db_info->page_order; ++ db_info->areas = (void**)malloc(db_info->nr_areas * sizeof(void *)); ++ memset(db_info->areas, 0, db_info->nr_areas * sizeof(void *)); ++ mem_pos = (kaddr_t) KL_UINT(k_dbi,"debug_info","areas"); ++ for (i = 0; i < db_info->nr_areas; i++) { ++ dbe_addr = KL_VREAD_PTR(mem_pos); ++ db_info->areas[i] = (debug_entry_t *) malloc(area_size); ++ /* read raw data for debug area */ ++ GET_BLOCK(dbe_addr, area_size, db_info->areas[i]); ++ mem_pos += KL_NBPW; ++ } ++} ++ ++static void ++debug_get_areas_v2(debug_info_t* db_info, void* k_dbi) ++{ ++ kaddr_t area_ptr; ++ kaddr_t page_array_ptr; ++ kaddr_t page_ptr; ++ int i,j; ++ db_info->areas_v2=(void***)malloc(db_info->nr_areas * sizeof(void **)); ++ area_ptr = (kaddr_t) KL_UINT(k_dbi,"debug_info","areas"); ++ for (i = 0; i < db_info->nr_areas; i++) { ++ db_info->areas_v2[i] = (void**)malloc(db_info->pages_per_area_v2 ++ * sizeof(void*)); ++ page_array_ptr = KL_VREAD_PTR(area_ptr); ++ for(j=0; j < db_info->pages_per_area_v2; j++) { ++ page_ptr = KL_VREAD_PTR(page_array_ptr); ++ db_info->areas_v2[i][j] = (void*)malloc(PAGE_SIZE); ++ /* read raw data for debug area */ ++ GET_BLOCK(page_ptr, PAGE_SIZE, db_info->areas_v2[i][j]); ++ page_array_ptr += KL_NBPW; ++ } ++ area_ptr += KL_NBPW; ++ } ++} ++ ++static debug_info_t* ++get_debug_info(kaddr_t addr,int get_areas) ++{ ++ void *k_dbi; ++ kaddr_t mem_pos; ++ kaddr_t view_addr; ++ debug_info_t* db_info; ++ int i; ++ int dbi_size; ++ ++ /* get sizes of kernel structures */ ++ if(!(dbi_size = kl_struct_len("debug_info"))){ ++ fprintf (KL_ERRORFP, ++ "Could not determine sizeof(struct debug_info)\n"); ++ return(NULL); ++ } ++ if(!(dbe_size = kl_struct_len("__debug_entry"))){ ++ fprintf(KL_ERRORFP, ++ "Could not determine sizeof(struct __debug_entry)\n"); ++ return(NULL); ++ } ++ ++ /* get kernel debug_info structure */ ++ k_dbi = malloc(dbi_size); ++ GET_BLOCK(addr, dbi_size, k_dbi); ++ ++ db_info = (debug_info_t*)malloc(sizeof(debug_info_t)); ++ memset(db_info, 0, sizeof(debug_info_t)); ++ ++ /* copy members */ ++ db_info->level = KL_INT(k_dbi,"debug_info","level"); ++ db_info->nr_areas = KL_INT(k_dbi,"debug_info","nr_areas"); ++ db_info->pages_per_area_v2= KL_INT(k_dbi,"debug_info","pages_per_area"); ++ db_info->page_order = KL_INT(k_dbi,"debug_info","page_order"); ++ db_info->buf_size = KL_INT(k_dbi,"debug_info","buf_size"); ++ db_info->entry_size = KL_INT(k_dbi,"debug_info","entry_size"); ++ db_info->next_dbi = KL_UINT(k_dbi,"debug_info","next"); ++ db_info->prev_dbi = KL_UINT(k_dbi,"debug_info","prev"); ++ db_info->addr = addr; ++ strncpy(db_info->name,K_PTR(k_dbi,"debug_info","name"), ++ DEBUG_MAX_PROCF_LEN); ++ ++ ++ if(get_areas){ ++ if(dbf_version == DBF_VERSION_V1) ++ debug_get_areas_v1(db_info,k_dbi); ++ else ++ debug_get_areas_v2(db_info,k_dbi); ++ } else { ++ db_info->areas = NULL; ++ } ++ ++ /* get views */ ++ mem_pos = (uaddr_t) K_PTR(k_dbi,"debug_info","views"); ++ memset(&db_info->views, 0, DEBUG_MAX_VIEWS * sizeof(void*)); ++ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { ++ view_addr = KL_GET_PTR((void*)(uaddr_t)mem_pos); ++ if(view_addr == 0){ ++ break; ++ } else { ++ db_info->views[i] = get_debug_view(view_addr); ++ } ++ mem_pos += KL_NBPW; ++ } ++ free(k_dbi); ++ return db_info; ++} ++ ++static void ++free_debug_info_v1(debug_info_t * db_info) ++{ ++ int i; ++ if(db_info->areas){ ++ for (i = 0; i < db_info->nr_areas; i++) { ++ free(db_info->areas[i]); ++ } ++ } ++ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { ++ free_debug_view(db_info->views[i]); ++ } ++ free(db_info->areas); ++ free(db_info); ++} ++ ++static void ++free_debug_info_v2(debug_info_t * db_info) ++{ ++ int i,j; ++ if(db_info->areas) { ++ for (i = 0; i < db_info->nr_areas; i++) { ++ for(j = 0; j < db_info->pages_per_area_v2; j++) { ++ free(db_info->areas_v2[i][j]); ++ } ++ free(db_info->areas[i]); ++ } ++ free(db_info->areas); ++ db_info->areas = NULL; ++ } ++ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { ++ free_debug_view(db_info->views[i]); ++ } ++ free(db_info); ++} ++ ++static int ++get_debug_areas(void) ++{ ++ kaddr_t act_debug_area; ++ syment_t *debug_sym; ++ debug_info_t *act_debug_area_cpy; ++ ++ if(!(debug_sym = kl_lkup_symname("debug_area_first"))){ ++ printf("Did not find debug_areas"); ++ return -1; ++ } ++ act_debug_area = KL_VREAD_PTR(debug_sym->s_addr); ++ while(act_debug_area != 0){ ++ act_debug_area_cpy = get_debug_info(act_debug_area,0); ++ act_debug_area = act_debug_area_cpy->next_dbi; ++ if(debug_area_first == NULL){ ++ debug_area_first = act_debug_area_cpy; ++ } else { ++ debug_area_last->next = act_debug_area_cpy; ++ } ++ debug_area_last = act_debug_area_cpy; ++ } ++ return 0; ++} ++ ++static void ++free_debug_areas(void) ++{ ++ debug_info_t* next; ++ debug_info_t* act_debug_info = debug_area_first; ++ ++ while(act_debug_info != NULL){ ++ next = act_debug_info->next; ++ if(dbf_version == DBF_VERSION_V1) ++ free_debug_info_v1(act_debug_info); ++ else ++ free_debug_info_v2(act_debug_info); ++ act_debug_info = next; ++ } ++ ++ debug_area_first = NULL; ++ debug_area_last = NULL; ++} ++ ++static debug_view_t * ++find_lcrash_debug_view(const char *name) ++{ ++ int i; ++ for (i = 0; (i < LCRASH_DB_VIEWS) && (debug_views[i] != NULL); i++) { ++ if (strcmp(debug_views[i]->name, name) == 0) ++ return debug_views[i]; ++ } ++ return NULL; ++} ++ ++static void ++print_lcrash_debug_views(FILE * ofp) ++{ ++ int i; ++ fprintf(ofp, "REGISTERED VIEWS\n"); ++ fprintf(ofp, "=====================\n"); ++ for (i = 0; i < LCRASH_DB_VIEWS; i++) { ++ if (debug_views[i] == NULL) { ++ return; ++ } ++ fprintf(ofp, " - %s\n", debug_views[i]->name); ++ } ++} ++ ++static int ++add_lcrash_debug_view(debug_view_t *view) ++{ ++ int i; ++ for (i = 0; i < LCRASH_DB_VIEWS; i++) { ++ if (debug_views[i] == NULL) { ++ debug_views[i] = view; ++ return 0; ++ } ++ if (strcmp(debug_views[i]->name, view->name) == 0) ++ return -1; ++ } ++ return -1; ++} ++ ++static int ++list_one_view(char *area_name, char *view_name, command_t * cmd) ++{ ++ debug_info_t *db_info; ++ debug_view_t *db_view; ++ ++ if ((db_info = find_debug_area(area_name)) == NULL) { ++ fprintf(cmd->efp, "Debug log '%s' not found!\n", area_name); ++ return -1; ++ } ++ ++ db_info = get_debug_info(db_info->addr,1); ++ ++ if ((db_view = find_lcrash_debug_view(view_name)) == NULL) { ++ fprintf(cmd->efp, "View '%s' not registered!\n", view_name); ++ return -1; ++ } ++ if(dbf_version == DBF_VERSION_V1){ ++ debug_format_output_v1(db_info, db_view, cmd->ofp); ++ free_debug_info_v1(db_info); ++ } else { ++ debug_format_output_v2(db_info, db_view, cmd->ofp); ++ free_debug_info_v2(db_info); ++ } ++ return 0; ++} ++ ++static int ++list_areas(FILE * ofp) ++{ ++ debug_info_t* act_debug_info = debug_area_first; ++ fprintf(ofp, "Debug Logs:\n"); ++ fprintf(ofp, "==================\n"); ++ while(act_debug_info != NULL){ ++ fprintf(ofp, " - %s\n", act_debug_info->name); ++ act_debug_info = act_debug_info->next; ++ } ++ return 0; ++} ++ ++static int ++list_one_area(const char *area_name, command_t * cmd) ++{ ++ debug_info_t *db_info; ++ int i; ++ if ((db_info = find_debug_area(area_name)) == NULL) { ++ fprintf(cmd->efp, "Debug log '%s' not found!\n", area_name); ++ return -1; ++ } ++ fprintf(cmd->ofp, "INSTALLED VIEWS FOR '%s':\n", area_name); ++ fprintf(cmd->ofp, "================================================" ++ "==============================\n"); ++ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { ++ if (db_info->views[i] != NULL) { ++ fprintf(cmd->ofp, " - %s ", db_info->views[i]->name); ++ if (find_lcrash_debug_view(db_info->views[i]->name)) ++ fprintf(cmd->ofp, "(available)\n"); ++ else ++ fprintf(cmd->ofp, "(not available)\n"); ++ } ++ } ++ fprintf(cmd->ofp, "=================================================" ++ "=============================\n"); ++ return 0; ++} ++ ++#ifdef DBF_DYNAMIC_VIEWS ++static int ++load_debug_view(const char *path, command_t * cmd) ++{ ++ void *library; ++ const char *error; ++ debug_view_t *(*view_init_func) (void); ++ ++ library = dlopen(path, RTLD_LAZY); ++ if (library == NULL) { ++ fprintf(cmd->efp, "Could not open %s: %s\n", path, dlerror()); ++ return (1); ++ } ++ ++ dlerror(); ++ ++ view_init_func = dlsym(library, "debug_view_init"); ++ error = dlerror(); ++ ++ if (error) { ++ fprintf(stderr, "could not find debug_view_init(): %s\n", ++ error); ++ exit(1); ++ } ++ ++ add_lcrash_debug_view((*view_init_func) ()); ++ ++ fprintf(cmd->ofp, "view %s loaded\n", path); ++ fflush(stdout); ++ return 0; ++} ++#endif ++ ++/* ++ * s390dbf_cmd() -- Run the 's390dbf' command. ++ */ ++static int ++s390dbf_cmd(command_t * cmd) ++{ ++ syment_t *dbf_version_sym; ++ int rc = 0; ++ ++ /* check version */ ++ ++ if(!(dbf_version_sym = kl_lkup_symname("debug_feature_version"))){ ++ fprintf(KL_ERRORFP, ++ "Could not determine debug_feature_version\n"); ++ return -1; ++ } ++ ++ dbf_version = KL_VREAD_UINT32(dbf_version_sym->s_addr); ++ ++ if ((dbf_version != DBF_VERSION_V1) && (dbf_version != DBF_VERSION_V2)){ ++ fprintf(cmd->efp,"lcrash does not support the" ++ " debug feature version of the dump kernel:\n"); ++ fprintf(cmd->efp,"DUMP: %i SUPPORTED: %i and %i\n", ++ dbf_version, DBF_VERSION_V1, DBF_VERSION_V2); ++ return -1; ++ } ++ ++ dbf_init(); ++ ++ if (cmd->flags & C_ALL) { ++ return (0); ++ } ++#ifdef DBF_DYNAMIC_VIEWS ++ if (cmd->flags & LOAD_FLAG) { ++ printf("loading: %s\n", cmd->args[0]); ++ return (load_debug_view(cmd->args[0], cmd)); ++ } ++#endif ++ if (cmd->flags & VIEWS_FLAG) { ++ print_lcrash_debug_views(cmd->ofp); ++ return (0); ++ } ++ if (cmd->nargs > 2) { ++ s390dbf_usage(cmd); ++ return (1); ++ } ++ ++ if(get_debug_areas() == -1) ++ return -1; ++ ++ switch (cmd->nargs) { ++ case 0: ++ rc = list_areas(cmd->ofp); ++ break; ++ case 1: ++ rc = list_one_area(cmd->args[0], cmd); ++ break; ++ case 2: ++ rc = list_one_view(cmd->args[0], cmd->args[1], cmd); ++ break; ++ } ++ ++ free_debug_areas(); ++ ++ return rc; ++} ++ ++#define _S390DBF_USAGE " [-v] [debug log] [debug view]" ++ ++/* ++ * s390dbf_usage() -- Print the usage string for the 's390dbf' command. ++ */ ++void ++s390dbf_usage(command_t * cmd) ++{ ++ CMD_USAGE(cmd, _S390DBF_USAGE); ++} ++ ++/* ++ * s390 debug feature command for crash ++ */ ++ ++char *help_s390dbf[] = { ++ "s390dbf", ++ "s390dbf prints out debug feature logs", ++ "[-v] [debug_log] [debug_log view]", ++ "", ++ "Display Debug logs:", ++ " + If called without parameters, all active debug logs are listed.", ++ " + If called with '-v', all debug views which are available to", ++ " 'crash' are listed", ++ " + If called with the name of a debug log, all debug-views for which", ++ " the debug-log has registered are listed. It is possible thatsome", ++ " of the debug views are not available to 'crash'.", ++ " + If called with the name of a debug-log and an available viewname,", ++ " the specified view is printed.", ++ NULL ++}; ++ ++void cmd_s390dbf() ++{ ++ int i,c; ++ ++ command_t cmd = { ++ .ofp = stdout, ++ .efp = stderr, ++ .cmdstr = "s390dbf", ++ .command = "s390dbf", ++ }; ++ ++ cmd.nargs=argcnt - 1; ++ for (i=1; i < argcnt; i++) ++ cmd.args[i-1] = args[i]; ++ ++ while ((c = getopt(argcnt, args, "v")) != EOF) { ++ switch(c) { ++ case 'v': ++ cmd.flags |= VIEWS_FLAG; ++ break; ++ default: ++ s390dbf_usage(&cmd); ++ return; ++ } ++ } ++ s390dbf_cmd(&cmd); ++} ++ ++#endif ++ +--- crash/ppc64.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/ppc64.c 2006-08-02 10:34:16.000000000 -0400 @@ -47,6 +47,9 @@ static char * ppc64_check_eframe(struct ppc64_pt_regs *); static void ppc64_print_eframe(char *, struct ppc64_pt_regs *, @@ -11746,8 +16089,8 @@ + machdep->machspec->last_level4_read = 0; +} #endif /* PPC64 */ ---- crash/x86_64.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/x86_64.c 2006-08-02 10:31:34.000000000 -0400 +--- crash/x86_64.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/x86_64.c 2006-08-31 16:02:02.000000000 -0400 @@ -18,7 +18,10 @@ #ifdef X86_64 @@ -11767,15 +16110,16 @@ static void x86_64_back_trace_cmd(struct bt_info *); static ulong x86_64_in_exception_stack(struct bt_info *); static ulong x86_64_in_irqstack(struct bt_info *); -@@ -56,6 +60,7 @@ +@@ -56,6 +60,8 @@ static void x86_64_display_memmap(void); static void x86_64_dump_line_number(ulong); static struct line_number_hook x86_64_line_number_hooks[]; ++static void x86_64_calc_phys_base(void); +static int x86_64_is_module_addr(ulong); static int x86_64_is_kvaddr(ulong); static int x86_64_is_uvaddr(ulong, struct task_context *); void x86_64_compiler_warning_stub(void); -@@ -63,7 +68,17 @@ +@@ -63,7 +69,17 @@ static void x86_64_cpu_pda_init(void); static void x86_64_ist_init(void); static void x86_64_post_init(void); @@ -11794,7 +16138,7 @@ struct machine_specific x86_64_machine_specific = { 0 }; -@@ -86,6 +101,8 @@ +@@ -86,6 +102,8 @@ machdep->pageoffset = machdep->pagesize - 1; machdep->pagemask = ~((ulonglong)machdep->pageoffset); machdep->stacksize = machdep->pagesize * 2; @@ -11803,7 +16147,7 @@ if ((machdep->pgd = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc pgd space."); if ((machdep->pmd = (char *)malloc(PAGESIZE())) == NULL) -@@ -93,17 +110,69 @@ +@@ -93,17 +111,69 @@ if ((machdep->ptbl = (char *)malloc(PAGESIZE())) == NULL) error(FATAL, "cannot malloc ptbl space."); if ((machdep->machspec->pml4 = @@ -11874,7 +16218,7 @@ machdep->kvbase = (ulong)PAGE_OFFSET; machdep->identity_map_base = (ulong)PAGE_OFFSET; machdep->is_kvaddr = x86_64_is_kvaddr; -@@ -111,7 +180,6 @@ +@@ -111,7 +181,6 @@ machdep->eframe_search = x86_64_eframe_search; machdep->back_trace = x86_64_low_budget_back_trace_cmd; machdep->processor_speed = x86_64_processor_speed; @@ -11882,7 +16226,7 @@ machdep->kvtop = x86_64_kvtop; machdep->get_task_pgd = x86_64_get_task_pgd; machdep->get_stack_frame = x86_64_get_stack_frame; -@@ -126,6 +194,11 @@ +@@ -126,6 +195,12 @@ machdep->line_number_hooks = x86_64_line_number_hooks; machdep->value_to_symbol = generic_machdep_value_to_symbol; machdep->init_kernel_pgd = x86_64_init_kernel_pgd; @@ -11891,10 +16235,11 @@ + machdep->get_xendump_regs = x86_64_get_xendump_regs; + machdep->xen_kdump_p2m_create = x86_64_xen_kdump_p2m_create; + machdep->xendump_panic_task = x86_64_xendump_panic_task; ++ x86_64_calc_phys_base(); break; case POST_GDB: -@@ -165,9 +238,25 @@ +@@ -165,9 +240,25 @@ machdep->nr_irqs = 224; /* NR_IRQS (at least) */ machdep->vmalloc_start = x86_64_vmalloc_start; machdep->dump_irq = x86_64_dump_irq; @@ -11923,7 +16268,7 @@ break; case POST_INIT: -@@ -191,10 +280,18 @@ +@@ -191,10 +282,20 @@ fprintf(fp, "%sKSYMS_START", others++ ? "|" : ""); if (machdep->flags & PT_REGS_INIT) fprintf(fp, "%sPT_REGS_INIT", others++ ? "|" : ""); @@ -11941,10 +16286,12 @@ + fprintf(fp, "%sNO_TSS", others++ ? "|" : ""); + if (machdep->flags & SCHED_TEXT) + fprintf(fp, "%sSCHED_TEXT", others++ ? "|" : ""); ++ if (machdep->flags & PHYS_BASE) ++ fprintf(fp, "%sPHYS_BASE", others++ ? "|" : ""); fprintf(fp, ")\n"); fprintf(fp, " kvbase: %lx\n", machdep->kvbase); -@@ -220,7 +317,14 @@ +@@ -220,7 +321,14 @@ fprintf(fp, " back_trace: %lx\n", (ulong)machdep->back_trace); fprintf(fp, " processor_speed: x86_64_processor_speed()\n"); @@ -11960,7 +16307,7 @@ fprintf(fp, " kvtop: x86_64_kvtop()\n"); fprintf(fp, " get_task_pgd: x86_64_get_task_pgd()\n"); fprintf(fp, " dump_irq: x86_64_dump_irq()\n"); -@@ -239,6 +343,11 @@ +@@ -239,6 +347,11 @@ fprintf(fp, " is_uvaddr: x86_64_is_uvaddr()\n"); fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); fprintf(fp, " init_kernel_pgd: x86_64_init_kernel_pgd()\n"); @@ -11972,7 +16319,7 @@ fprintf(fp, " line_number_hooks: x86_64_line_number_hooks\n"); fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); -@@ -248,8 +357,26 @@ +@@ -248,8 +361,27 @@ fprintf(fp, " pmd: %lx\n", (ulong)machdep->pmd); fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); @@ -11988,6 +16335,7 @@ + fprintf(fp, " vmalloc_end: %016lx\n", (ulong)ms->vmalloc_end); + fprintf(fp, " modules_vaddr: %016lx\n", (ulong)ms->modules_vaddr); + fprintf(fp, " modules_end: %016lx\n", (ulong)ms->modules_end); ++ fprintf(fp, " phys_base: %lx\n", (ulong)ms->phys_base); fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4); + fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read); + if (ms->upml) { @@ -12000,7 +16348,7 @@ fprintf(fp, " irqstack: %lx\n", (ulong)ms->irqstack); fprintf(fp, " pto: %s", machdep->flags & PT_REGS_INIT ? "\n" : "(uninitialized)\n"); -@@ -276,8 +403,10 @@ +@@ -276,8 +408,10 @@ fprintf(fp, " rsp: %ld\n", ms->pto.rsp); fprintf(fp, " ss: %ld\n", ms->pto.ss); } @@ -12013,7 +16361,7 @@ fprintf(fp, " ebase[%s][7]:", arg ? "NR_CPUS" : "cpus"); cpus = arg ? NR_CPUS : kt->cpus; -@@ -306,9 +435,9 @@ +@@ -306,9 +440,9 @@ static void x86_64_cpu_pda_init(void) { @@ -12025,7 +16373,7 @@ struct syment *sp, *nsp; ulong offset, istacksize; -@@ -320,18 +449,36 @@ +@@ -320,18 +454,36 @@ MEMBER_OFFSET_INIT(x8664_pda_irqstackptr, "x8664_pda", "irqstackptr"); MEMBER_OFFSET_INIT(x8664_pda_level4_pgt, "x8664_pda", "level4_pgt"); MEMBER_OFFSET_INIT(x8664_pda_cpunumber, "x8664_pda", "cpunumber"); @@ -12068,7 +16416,7 @@ break; cpus++; -@@ -448,6 +595,13 @@ +@@ -448,6 +600,13 @@ if (ms->stkinfo.ebase[c][0] == 0) break; } @@ -12082,7 +16430,7 @@ } if (ms->stkinfo.ebase[0][0] && ms->stkinfo.ebase[0][1]) -@@ -535,6 +689,10 @@ +@@ -535,6 +694,10 @@ if (clues >= 2) kt->cpu_flags[c] |= NMI; } @@ -12093,7 +16441,16 @@ } /* -@@ -584,12 +742,19 @@ +@@ -576,7 +739,7 @@ + ulong x86_64_VTOP(ulong vaddr) + { + if (vaddr >= __START_KERNEL_map) +- return ((vaddr) - (ulong)__START_KERNEL_map); ++ return ((vaddr) - (ulong)__START_KERNEL_map + machdep->machspec->phys_base); + else + return ((vaddr) - PAGE_OFFSET); + } +@@ -584,12 +747,19 @@ /* * Include both vmalloc'd and module address space as VMALLOC space. */ @@ -12114,7 +16471,7 @@ /* * Refining this may cause more problems than just doing it this way. */ -@@ -616,6 +781,257 @@ +@@ -616,6 +786,257 @@ */ static int @@ -12372,7 +16729,7 @@ x86_64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose) { ulong mm; -@@ -748,6 +1164,9 @@ +@@ -748,6 +1169,9 @@ return TRUE; } @@ -12382,7 +16739,7 @@ /* * pgd = pgd_offset_k(addr); */ -@@ -764,7 +1183,7 @@ +@@ -764,7 +1188,7 @@ pgd = ((ulong *)pgd_paddr) + pgd_index(kvaddr); pgd_pte = ULONG(machdep->pgd + PAGEOFFSET(pgd)); if (verbose) @@ -12391,7 +16748,7 @@ if (!(pgd_pte & _PAGE_PRESENT)) goto no_kpage; -@@ -824,47 +1243,177 @@ +@@ -824,47 +1248,177 @@ return FALSE; } @@ -12602,7 +16959,7 @@ /* -@@ -878,7 +1427,6 @@ +@@ -878,7 +1432,6 @@ if (!name || !strlen(name) || !(machdep->flags & KSYMS_START)) return FALSE; @@ -12610,7 +16967,7 @@ return TRUE; } -@@ -1091,6 +1639,9 @@ +@@ -1091,6 +1644,9 @@ ulong *up; ulong words, addr; @@ -12620,7 +16977,7 @@ words = (rsp - bt->frameptr) / sizeof(ulong) + 1; addr = bt->frameptr; -@@ -1308,7 +1859,7 @@ +@@ -1308,7 +1864,7 @@ (rsp < (ms->stkinfo.ebase[c][i] + ms->stkinfo.esize))) { estack = ms->stkinfo.ebase[c][i]; @@ -12629,7 +16986,7 @@ error(INFO, "task cpu: %d exception stack cpu: %d\n", bt->tc->processor, c); -@@ -1341,7 +1892,7 @@ +@@ -1341,7 +1897,7 @@ if ((rsp >= ms->stkinfo.ibase[c]) && (rsp < (ms->stkinfo.ibase[c] + ms->stkinfo.isize))) { irqstack = ms->stkinfo.ibase[c]; @@ -12638,7 +16995,7 @@ error(INFO, "task cpu: %d IRQ stack cpu: %d\n", bt->tc->processor, c); -@@ -1399,12 +1950,13 @@ +@@ -1399,12 +1955,13 @@ ofp = fp; if (bt->flags & BT_TEXT_SYMBOLS) { @@ -12658,7 +17015,7 @@ } else if (bt->flags & BT_START) { x86_64_print_stack_entry(bt, ofp, level, 0, bt->instptr); -@@ -1647,8 +2199,12 @@ +@@ -1647,8 +2204,12 @@ bt->stackbuf + (irq_eframe - bt->stackbase), bt, ofp); if (cs & 3) done = TRUE; /* IRQ from user-mode */ @@ -12672,7 +17029,7 @@ level++; } -@@ -1691,6 +2247,10 @@ +@@ -1691,6 +2252,10 @@ bt->call_target); continue; } @@ -12683,7 +17040,7 @@ } else if (!STREQ(sp->name, bt->call_target)) { /* * We got function called by the text routine, -@@ -1709,6 +2269,8 @@ +@@ -1709,6 +2274,8 @@ { case BACKTRACE_ENTRY_AND_EFRAME_DISPLAYED: last_process_stack_eframe = rsp + 8; @@ -12692,7 +17049,7 @@ rsp += SIZE(pt_regs); i += SIZE(pt_regs)/sizeof(ulong); case BACKTRACE_ENTRY_DISPLAYED: -@@ -1842,6 +2404,8 @@ +@@ -1842,6 +2409,8 @@ long rax, rbx, rcx, rdx, rsi, rdi; long r8, r9, r10, r11, r12, r13, r14, r15; struct machine_specific *ms; @@ -12701,7 +17058,7 @@ char *pt_regs_buf; long verified; int err; -@@ -1950,8 +2514,17 @@ +@@ -1950,8 +2519,17 @@ cs & 3 ? "USER" : "KERNEL", kvaddr ? kvaddr : (local - bt->stackbuf) + bt->stackbase); @@ -12720,7 +17077,7 @@ fprintf(ofp, " RIP: %016lx RSP: %016lx RFLAGS: %08lx\n", rip, rsp, rflags); fprintf(ofp, " RAX: %016lx RBX: %016lx RCX: %016lx\n", -@@ -2006,6 +2579,39 @@ +@@ -2006,6 +2584,39 @@ return 0; } @@ -12760,7 +17117,7 @@ /* * Check that the verifiable registers contain reasonable data. */ -@@ -2021,6 +2627,11 @@ +@@ -2021,6 +2632,11 @@ if ((cs == 0x10) && (ss == 0x18)) { if (is_kernel_text(rip) && IS_KVADDR(rsp)) return TRUE; @@ -12772,7 +17129,7 @@ } if ((cs == 0x10) && kvaddr) { -@@ -2040,6 +2651,26 @@ +@@ -2040,6 +2656,26 @@ return TRUE; } @@ -12799,7 +17156,7 @@ return FALSE; } -@@ -2065,7 +2696,7 @@ +@@ -2065,7 +2701,7 @@ x86_64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *rip, ulong *rsp) { int panic_task; @@ -12808,7 +17165,7 @@ char *sym; struct syment *sp; ulong *up; -@@ -2080,6 +2711,7 @@ +@@ -2080,6 +2716,7 @@ ms = machdep->machspec; ur_rip = ur_rsp = 0; stage = 0; @@ -12816,7 +17173,7 @@ panic_task = tt->panic_task == bt->task ? TRUE : FALSE; -@@ -2119,13 +2751,14 @@ +@@ -2119,13 +2756,14 @@ STREQ(sym, "netpoll_start_netdump") || STREQ(sym, "start_disk_dump") || STREQ(sym, "disk_dump") || @@ -12832,7 +17189,7 @@ (STREQ(sym, "nmi_watchdog_tick") || STREQ(sym, "default_do_nmi"))) { sp = x86_64_function_called_by((*up)-5); -@@ -2161,7 +2794,7 @@ +@@ -2161,7 +2799,7 @@ next_sysrq: *rip = *up; *rsp = bt->stackbase + ((char *)(up) - bt->stackbuf); @@ -12841,7 +17198,7 @@ for (i++, up++; i < LONGS_PER_STACK; i++, up++) { sym = closest_symbol(*up); if (STREQ(sym, "sysrq_handle_crash")) -@@ -2176,6 +2809,12 @@ +@@ -2176,6 +2814,12 @@ *rsp = bt->stackbase + ((char *)(up) - bt->stackbuf); return; } @@ -12854,7 +17211,7 @@ } if (panic) -@@ -2191,25 +2830,30 @@ +@@ -2191,25 +2835,30 @@ bt->stackbase = ms->stkinfo.ibase[bt->tc->processor]; bt->stacktop = ms->stkinfo.ibase[bt->tc->processor] + ms->stkinfo.isize; @@ -12892,7 +17249,7 @@ } /* -@@ -2258,7 +2902,7 @@ +@@ -2258,7 +2907,7 @@ { ulong offset, rip; @@ -12901,7 +17258,7 @@ return symbol_value("thread_return"); if (tt->flags & THREAD_INFO) { -@@ -2457,25 +3101,40 @@ +@@ -2457,25 +3106,40 @@ int x86_64_get_smp_cpus(void) { @@ -12952,7 +17309,7 @@ cpus++; } -@@ -2551,9 +3210,9 @@ +@@ -2551,9 +3215,9 @@ static void x86_64_display_cpu_data(void) { @@ -12964,7 +17321,7 @@ if (symbol_exists("cpu_data")) { cpu_data = symbol_value("cpu_data"); -@@ -2564,7 +3223,13 @@ +@@ -2564,7 +3228,13 @@ boot_cpu = TRUE; cpus = 1; } @@ -12979,7 +17336,7 @@ for (cpu = 0; cpu < cpus; cpu++) { if (boot_cpu) -@@ -2574,10 +3239,17 @@ +@@ -2574,10 +3244,17 @@ dump_struct("cpuinfo_x86", cpu_data, 0); fprintf(fp, "\n"); @@ -12999,7 +17356,7 @@ } } -@@ -2691,4 +3363,698 @@ +@@ -2691,4 +3368,824 @@ x86_64_dump_line_number(0); } @@ -13008,6 +17365,10 @@ + * + * --machdep vm=orig + * --machdep vm=2.6.11 ++ * ++ * Force the phys_base address via: ++ * ++ * --machdep phys_base=
+ */ + +void @@ -13017,7 +17378,9 @@ + char *p; + char buf[BUFSIZE]; + char *arglist[MAXARGS]; ++ int megabytes; + int lines = 0; ++ ulong value; + + if (!strstr(machdep->cmdline_arg, "=")) { + error(WARNING, "ignoring --machdep option: %s\n\n", @@ -13051,7 +17414,33 @@ + continue; + } + } -+ } ++ } else if (STRNEQ(arglist[i], "phys_base=")) { ++ megabytes = FALSE; ++ if ((LASTCHAR(arglist[i]) == 'm') || ++ (LASTCHAR(arglist[i]) == 'M')) { ++ LASTCHAR(arglist[i]) = NULLCHAR; ++ megabytes = TRUE; ++ } ++ p = arglist[i] + strlen("phys_base="); ++ if (strlen(p)) { ++ if (megabytes) { ++ value = dtol(p, RETURN_ON_ERROR|QUIET, ++ &errflag); ++ } else ++ value = htol(p, RETURN_ON_ERROR|QUIET, ++ &errflag); ++ if (!errflag) { ++ if (megabytes) ++ value = MEGABYTES(value); ++ machdep->machspec->phys_base = value; ++ error(NOTE, ++ "setting phys_base to: 0x%lx\n\n", ++ machdep->machspec->phys_base); ++ machdep->flags |= PHYS_BASE; ++ continue; ++ } ++ } ++ } + + error(WARNING, "ignoring --machdep option: %s\n", arglist[i]); + lines++; @@ -13097,6 +17486,100 @@ +#include "netdump.h" + +/* ++ * Determine the physical address base for relocatable kernels. ++ */ ++static void ++x86_64_calc_phys_base(void) ++{ ++ int i; ++ FILE *iomem; ++ char buf[BUFSIZE]; ++ char *p1; ++ ulong text_start, kernel_code_start; ++ int errflag; ++ struct vmcore_data *vd; ++ Elf64_Phdr *phdr; ++ ++ if (machdep->flags & PHYS_BASE) /* --machdep override */ ++ return; ++ ++ machdep->machspec->phys_base = 0; /* default/traditional */ ++ ++ if (!symbol_exists("phys_base")) ++ return; ++ ++ if (!symbol_exists("_text")) ++ return; ++ else ++ text_start = symbol_value("_text"); ++ ++ if (ACTIVE()) { ++ if ((iomem = fopen("/proc/iomem", "r")) == NULL) ++ return; ++ ++ errflag = 1; ++ while (fgets(buf, BUFSIZE, iomem)) { ++ if (strstr(buf, ": Kernel code")) { ++ clean_line(buf); ++ errflag = 0; ++ break; ++ } ++ } ++ fclose(iomem); ++ ++ if (errflag) ++ return; ++ ++ if (!(p1 = strstr(buf, "-"))) ++ return; ++ else ++ *p1 = NULLCHAR; ++ ++ errflag = 0; ++ kernel_code_start = htol(buf, RETURN_ON_ERROR|QUIET, &errflag); ++ if (errflag) ++ return; ++ ++ machdep->machspec->phys_base = kernel_code_start - ++ (text_start - __START_KERNEL_map); ++ ++ if (CRASHDEBUG(1)) { ++ fprintf(fp, "_text: %lx ", text_start); ++ fprintf(fp, "Kernel code: %lx -> ", kernel_code_start); ++ fprintf(fp, "phys_base: %lx\n\n", ++ machdep->machspec->phys_base); ++ } ++ ++ return; ++ } ++ ++ /* ++ * Get relocation value from whatever dumpfile format is being used. ++ */ ++ if ((vd = get_kdump_vmcore_data())) { ++ for (i = 0; i < vd->num_pt_load_segments; i++) { ++ phdr = vd->load64 + i; ++ if ((phdr->p_vaddr >= __START_KERNEL_map) && ++ !(IS_VMALLOC_ADDR(phdr->p_vaddr))) { ++ ++ machdep->machspec->phys_base = phdr->p_paddr - ++ (phdr->p_vaddr & ~(__START_KERNEL_map)); ++ ++ if (CRASHDEBUG(1)) { ++ fprintf(fp, "p_vaddr: %lx p_paddr: %lx -> ", ++ phdr->p_vaddr, phdr->p_paddr); ++ fprintf(fp, "phys_base: %lx\n\n", ++ machdep->machspec->phys_base); ++ } ++ break; ++ } ++ } ++ ++ return; ++ } ++} ++ ++/* + * From the xen vmcore, create an index of mfns for each page that makes + * up the dom0 kernel's complete phys_to_machine_mapping[max_pfn] array. + */ @@ -13698,8 +18181,8 @@ + } +} #endif /* X86_64 */ ---- crash/extensions.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/extensions.c 2005-11-10 09:47:46.000000000 -0500 +--- crash/extensions.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/extensions.c 2005-11-10 10:12:44.000000000 -0500 @@ -18,9 +18,6 @@ #include "defs.h" #include @@ -13728,8 +18211,8 @@ unload_extension(char *lib) { struct extension_table *ext; ---- crash/va_server.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/va_server.c 2006-03-22 08:55:34.000000000 -0500 +--- crash/va_server.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/va_server.c 2006-03-22 09:11:38.000000000 -0500 @@ -57,13 +57,15 @@ extern int monitor_memory(long *, long *, long *, long *); @@ -13747,8 +18230,8 @@ if(read_map(crash_file)) { if(va_server_init_v1(crash_file, start, end, stride)) return -1; ---- crash/symbols.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/symbols.c 2006-08-03 14:43:54.000000000 -0400 +--- crash/symbols.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/symbols.c 2006-08-22 12:06:27.000000000 -0400 @@ -1,8 +1,8 @@ /* symbols.c - core analysis suite * @@ -13769,7 +18252,16 @@ fprintf(fp, "%lx (%lx): %s syms: %d gplsyms: %d ksyms: %ld\n", mod, lm->mod_base, lm->mod_name, nsyms, -@@ -3463,6 +3463,22 @@ +@@ -2121,6 +2121,8 @@ + fprintf(fp, "%sFORCE_DEBUGINFO", others++ ? "|" : ""); + if (st->flags & CRC_MATCHES) + fprintf(fp, "%sCRC_MATCHES", others++ ? "|" : ""); ++ if (st->flags & ADD_SYMBOL_FILE) ++ fprintf(fp, "%sADD_SYMBOL_FILE", others++ ? "|" : ""); + fprintf(fp, ")\n"); + + fprintf(fp, " bfd: %lx\n", (ulong)st->bfd); +@@ -3463,6 +3465,22 @@ } /* @@ -13792,7 +18284,49 @@ * Return the value of a given symbol. */ ulong -@@ -5433,6 +5449,8 @@ +@@ -5079,7 +5097,8 @@ + + s = dm->member; + indent = 0; +- on = array = FALSE; ++ array = FALSE; ++ on = 0; + rewind(pc->tmpfile); + + switch (flag) +@@ -5090,7 +5109,7 @@ + next_item: + while (fgets(buf, BUFSIZE, pc->tmpfile)) { + if (STRNEQ(buf, lookfor1) || STRNEQ(buf, lookfor2)) { +- on = TRUE; ++ on++; + if (strstr(buf, "= {")) + indent = count_leading_spaces(buf); + if (strstr(buf, "[")) +@@ -5098,16 +5117,22 @@ + } + + if (on) { ++ if ((indent && (on > 1) && (count_leading_spaces(buf) == indent) && ++ !strstr(buf, "}")) || (buf[0] == '}')) { ++ break; ++ } + fprintf(pc->saved_fp, buf); + if (!indent) + break; + if (strstr(buf, "}") && + (count_leading_spaces(buf) == indent)) + break; ++ on++; + } + } + if (array) { + on = array = FALSE; ++ on = 0; + goto next_item; + } + break; +@@ -5433,6 +5458,8 @@ lenptr = &array_table.kmem_cache_s_c_name; else if (STREQ(s, "kmem_cache_s.array")) lenptr = &array_table.kmem_cache_s_array; @@ -13801,7 +18335,7 @@ else if (STREQ(s, "kmem_cache_s.cpudata")) lenptr = &array_table.kmem_cache_s_cpudata; else if (STREQ(s, "log_buf")) -@@ -5766,6 +5784,8 @@ +@@ -5766,6 +5793,8 @@ OFFSET(mm_struct_pgd)); fprintf(fp, " mm_struct_rss: %ld\n", OFFSET(mm_struct_rss)); @@ -13810,7 +18344,7 @@ fprintf(fp, " mm_struct_total_vm: %ld\n", OFFSET(mm_struct_total_vm)); fprintf(fp, " mm_struct_start_code: %ld\n", -@@ -5972,6 +5992,16 @@ +@@ -5972,6 +6001,16 @@ fprintf(fp, " irq_cpustat_t___softirq_mask: %ld\n", OFFSET(irq_cpustat_t___softirq_mask)); @@ -13827,7 +18361,7 @@ fprintf(fp, " files_struct_max_fds: %ld\n", OFFSET(files_struct_max_fds)); fprintf(fp, " files_struct_max_fdset: %ld\n", -@@ -6217,6 +6247,11 @@ +@@ -6217,6 +6256,11 @@ fprintf(fp, " inet_opt_num: %ld\n", OFFSET(inet_opt_num)); @@ -13839,7 +18373,7 @@ fprintf(fp, " timer_list_list: %ld\n", OFFSET(timer_list_list)); fprintf(fp, " timer_list_next: %ld\n", -@@ -6291,6 +6326,8 @@ +@@ -6291,6 +6335,8 @@ OFFSET(zone_struct_size)); fprintf(fp, " zone_struct_memsize: %ld\n", OFFSET(zone_struct_memsize)); @@ -13848,7 +18382,7 @@ fprintf(fp, " zone_struct_zone_start_paddr: %ld\n", OFFSET(zone_struct_zone_start_paddr)); fprintf(fp, " zone_struct_zone_start_mapnr: %ld\n", -@@ -6471,10 +6508,25 @@ +@@ -6471,10 +6517,25 @@ OFFSET(x8664_pda_irqstackptr)); fprintf(fp, " x8664_pda_level4_pgt: %ld\n", OFFSET(x8664_pda_level4_pgt)); @@ -13874,7 +18408,7 @@ fprintf(fp, "\n size_table:\n"); fprintf(fp, " page: %ld\n", SIZE(page)); -@@ -6512,6 +6564,7 @@ +@@ -6512,6 +6573,7 @@ fprintf(fp, " fs_struct: %ld\n", SIZE(fs_struct)); fprintf(fp, " files_struct: %ld\n", SIZE(files_struct)); @@ -13882,7 +18416,7 @@ fprintf(fp, " file: %ld\n", SIZE(file)); fprintf(fp, " inode: %ld\n", SIZE(inode)); fprintf(fp, " vfsmount: %ld\n", SIZE(vfsmount)); -@@ -6546,6 +6599,7 @@ +@@ -6546,6 +6608,7 @@ fprintf(fp, " sock: %ld\n", SIZE(sock)); fprintf(fp, " inet_sock: %ld\n", SIZE(inet_sock)); fprintf(fp, " socket: %ld\n", SIZE(socket)); @@ -13890,7 +18424,7 @@ fprintf(fp, " signal_struct: %ld\n", SIZE(signal_struct)); fprintf(fp, " signal_queue: %ld\n", -@@ -6601,6 +6655,8 @@ +@@ -6601,6 +6664,8 @@ fprintf(fp, " x8664_pda: %ld\n", SIZE(x8664_pda)); @@ -13899,7 +18433,7 @@ fprintf(fp, " gate_struct: %ld\n", SIZE(gate_struct)); fprintf(fp, " tss_struct: %ld\n", -@@ -6609,7 +6665,10 @@ +@@ -6609,7 +6674,10 @@ SIZE(task_struct_start_time)); fprintf(fp, " cputime_t: %ld\n", SIZE(cputime_t)); @@ -13911,8 +18445,18 @@ fprintf(fp, "\n array_table:\n"); /* ---- crash/cmdline.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/cmdline.c 2006-07-10 10:59:57.000000000 -0400 +@@ -7261,7 +7329,9 @@ + if (!CRASHDEBUG(1)) + req->fp = pc->nullfp; + ++ st->flags |= ADD_SYMBOL_FILE; + gdb_interface(req); ++ st->flags &= ~ADD_SYMBOL_FILE; + + sprintf(buf, "set complaints 0"); + gdb_pass_through(buf, NULL, 0); +--- crash/cmdline.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/cmdline.c 2006-08-21 12:06:39.000000000 -0400 @@ -71,14 +71,17 @@ * 4. from a terminal. * 5. from a pipe, if stdin is a pipe rather than a terminal. @@ -13951,8 +18495,30 @@ restore_gdb_sanity(); ---- crash/lkcd_common.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_common.c 2006-06-15 10:34:53.000000000 -0400 +@@ -1706,15 +1710,20 @@ + error(FATAL, + "scrolling must be turned off when repeating an input file\n"); + ++ pc->curcmd_flags |= REPEAT; ++ + while (TRUE) { + optind = 0; +-console("exec_command...\n"); ++ + exec_command(); + free_all_bufs(); + + if (received_SIGINT() || !output_open()) + break; + ++ if (!(pc->curcmd_flags & REPEAT)) ++ break; ++ + if (delay) + sleep(delay); + +--- crash/lkcd_common.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/lkcd_common.c 2006-06-15 10:36:08.000000000 -0400 @@ -53,6 +53,8 @@ struct lkcd_environment lkcd_environment = { 0 }; @@ -14131,8 +18697,8 @@ if ((lkcd->flags & LKCD_VALID) && (page > lkcd->total_pages)) lkcd->total_pages = page; ---- crash/lkcd_v7.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_v7.c 2005-11-10 15:21:50.000000000 -0500 +--- crash/lkcd_v7.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/lkcd_v7.c 2005-11-10 15:25:45.000000000 -0500 @@ -89,7 +89,11 @@ ifd = 0; @@ -14146,8 +18712,8 @@ dump_index_size = (lkcd->memory_pages * sizeof(off_t)); lkcd->page_offsets = 0; strcpy(dumpfile_index_name, dumpfile); ---- crash/lkcd_v8.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_v8.c 2005-12-15 08:59:52.000000000 -0500 +--- crash/lkcd_v8.c.orig 2006-09-13 11:10:22.000000000 -0400 ++++ crash/lkcd_v8.c 2005-12-15 15:19:21.000000000 -0500 @@ -26,6 +26,7 @@ // static dump_header_asm_t dump_header_asm_v8 = { 0 }; static dump_page_t dump_page = { 0 }; @@ -14207,8 +18773,8 @@ set_mb_benchmark((granularity * (i+1))/lkcd->page_size); } } ---- crash/s390_dump.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/s390_dump.c 2006-05-15 17:15:56.000000000 -0400 +--- crash/s390_dump.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/s390_dump.c 2006-05-15 17:21:03.000000000 -0400 @@ -16,7 +16,7 @@ * GNU General Public License for more details. */ @@ -14233,8 +18799,8 @@ } int ---- crash/lkcd_x86_trace.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_x86_trace.c 2006-05-15 16:28:35.000000000 -0400 +--- crash/lkcd_x86_trace.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/lkcd_x86_trace.c 2006-05-15 16:26:15.000000000 -0400 @@ -47,11 +47,13 @@ static int setup_trace_rec(kaddr_t, kaddr_t, int, trace_t *); static int valid_ra(kaddr_t); @@ -14603,34 +19169,39 @@ * Cache 2k starting from the passed-in text address. This sits on top * of the instrbuf 256-byte cache, but we don't want to extend its size * because we can run off the end of a module segment -- if this routine ---- crash/netdump.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/netdump.c 2006-07-10 11:01:03.000000000 -0400 -@@ -22,12 +22,12 @@ - physaddr_t phys_end; - }; +--- crash/netdump.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/netdump.c 2006-08-31 15:59:44.000000000 -0400 +@@ -16,35 +16,9 @@ + #include "defs.h" + #include "netdump.h" +-struct pt_load_segment { +- off_t file_offset; +- physaddr_t phys_start; +- physaddr_t phys_end; +-}; +- -struct netdump_data { -+struct vmcore_data { - ulong flags; - int ndfd; - FILE *ofp; - uint header_size; +- ulong flags; +- int ndfd; +- FILE *ofp; +- uint header_size; - char *netdump_header; -+ char *elf_header; - uint num_pt_load_segments; - struct pt_load_segment *pt_load_segments; - Elf32_Ehdr *elf32; -@@ -40,11 +40,16 @@ - void *nt_prpsinfo; - void *nt_taskstruct; - ulong task_struct; -+ uint page_size; - ulong switch_stack; -+ uint num_prstatus_notes; -+ void *nt_prstatus_percpu[NR_CPUS]; -+ struct xen_kdump_data *xen_kdump_data; - }; - +- uint num_pt_load_segments; +- struct pt_load_segment *pt_load_segments; +- Elf32_Ehdr *elf32; +- Elf32_Phdr *notes32; +- Elf32_Phdr *load32; +- Elf64_Ehdr *elf64; +- Elf64_Phdr *notes64; +- Elf64_Phdr *load64; +- void *nt_prstatus; +- void *nt_prpsinfo; +- void *nt_taskstruct; +- ulong task_struct; +- ulong switch_stack; +-}; +- -static struct netdump_data netdump_data = { 0 }; -static struct netdump_data *nd = &netdump_data; +static struct vmcore_data vmcore_data = { 0 }; @@ -14639,7 +19210,7 @@ static void netdump_print(char *, ...); static void dump_Elf32_Ehdr(Elf32_Ehdr *); static void dump_Elf32_Phdr(Elf32_Phdr *, int); -@@ -52,19 +57,20 @@ +@@ -52,19 +26,20 @@ static void dump_Elf64_Ehdr(Elf64_Ehdr *); static void dump_Elf64_Phdr(Elf64_Phdr *, int); static size_t dump_Elf64_Nhdr(Elf64_Off offset, int); @@ -14665,7 +19236,7 @@ { int i; int fd; -@@ -77,6 +83,8 @@ +@@ -77,6 +52,8 @@ size_t size, len, tot; Elf32_Off offset32; Elf64_Off offset64; @@ -14674,7 +19245,7 @@ if ((fd = open(file, O_RDWR)) < 0) { if ((fd = open(file, O_RDONLY)) < 0) { -@@ -99,11 +107,24 @@ +@@ -99,11 +76,24 @@ goto bailout; } @@ -14700,7 +19271,7 @@ */ if (STRNEQ(elf32->e_ident, ELFMAG) && (elf32->e_ident[EI_CLASS] == ELFCLASS32) && -@@ -120,10 +141,16 @@ +@@ -120,10 +110,16 @@ default: goto bailout; } @@ -14718,7 +19289,7 @@ } else if (STRNEQ(elf64->e_ident, ELFMAG) && (elf64->e_ident[EI_CLASS] == ELFCLASS64) && (elf64->e_ident[EI_VERSION] == EV_CURRENT) && -@@ -153,35 +180,68 @@ +@@ -153,35 +149,68 @@ else goto bailout; @@ -14794,7 +19365,7 @@ nd->num_pt_load_segments = nd->elf32->e_phnum - 1; if ((nd->pt_load_segments = (struct pt_load_segment *) malloc(sizeof(struct pt_load_segment) * -@@ -190,9 +250,11 @@ +@@ -190,9 +219,11 @@ clean_exit(1); } nd->notes32 = (Elf32_Phdr *) @@ -14808,7 +19379,7 @@ dump_Elf32_Ehdr(nd->elf32); dump_Elf32_Phdr(nd->notes32, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -205,8 +267,9 @@ +@@ -205,8 +236,9 @@ break; case NETDUMP_ELF64: @@ -14819,7 +19390,7 @@ nd->num_pt_load_segments = nd->elf64->e_phnum - 1; if ((nd->pt_load_segments = (struct pt_load_segment *) malloc(sizeof(struct pt_load_segment) * -@@ -215,9 +278,11 @@ +@@ -215,9 +247,11 @@ clean_exit(1); } nd->notes64 = (Elf64_Phdr *) @@ -14833,7 +19404,7 @@ dump_Elf64_Ehdr(nd->elf64); dump_Elf64_Phdr(nd->notes64, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -230,6 +295,9 @@ +@@ -230,6 +264,9 @@ break; } @@ -14843,7 +19414,7 @@ return nd->header_size; bailout: -@@ -243,7 +311,7 @@ +@@ -243,7 +280,7 @@ int netdump_init(char *unused, FILE *fptr) { @@ -14852,7 +19423,7 @@ return FALSE; nd->ofp = fptr; -@@ -263,19 +331,19 @@ +@@ -263,19 +300,19 @@ /* * The Elf32_Phdr has 32-bit fields for p_paddr, p_filesz and * p_memsz, so for now, multiple PT_LOAD segment support is @@ -14878,7 +19449,7 @@ if (nd->num_pt_load_segments == 1) { offset = (off_t)paddr + (off_t)nd->header_size; break; -@@ -302,24 +370,57 @@ +@@ -302,24 +339,57 @@ if (read(nd->ndfd, bufptr, cnt) != cnt) return READ_ERROR; @@ -14904,8 +19475,7 @@ + case NETDUMP_ELF32: + offset = (off_t)paddr + (off_t)nd->header_size; + break; - -- offset = (off_t)paddr + (off_t)nd->header_size; ++ + case NETDUMP_ELF64: + case KDUMP_ELF32: + case KDUMP_ELF64: @@ -14914,7 +19484,7 @@ + break; + } -- if (lseek(nd->ndfd, offset, SEEK_SET) != offset) +- offset = (off_t)paddr + (off_t)nd->header_size; + for (i = offset = 0; i < nd->num_pt_load_segments; i++) { + pls = &nd->pt_load_segments[i]; + if ((paddr >= pls->phys_start) && @@ -14930,7 +19500,8 @@ + + break; + } -+ + +- if (lseek(nd->ndfd, offset, SEEK_SET) != offset) + if (lseek(nd->ndfd, offset, SEEK_SET) == -1) return SEEK_ERROR; @@ -14940,7 +19511,7 @@ return cnt; } -@@ -330,7 +431,7 @@ +@@ -330,7 +400,7 @@ FILE * set_netdump_fp(FILE *fp) { @@ -14949,7 +19520,7 @@ return NULL; nd->ofp = fp; -@@ -346,7 +447,7 @@ +@@ -346,7 +416,7 @@ char buf[BUFSIZE]; va_list ap; @@ -14958,7 +19529,7 @@ return; va_start(ap, fmt); -@@ -362,33 +463,21 @@ +@@ -362,33 +432,21 @@ uint netdump_page_size(void) { @@ -14996,7 +19567,7 @@ } /* -@@ -414,21 +503,57 @@ +@@ -414,21 +472,57 @@ #ifdef DAEMON return nd->task_struct; #else @@ -15062,7 +19633,7 @@ len = sizeof(Elf32_Nhdr); len = roundup(len + note32->n_namesz, 4); len = roundup(len + note32->n_descsz, 4); -@@ -437,14 +562,15 @@ +@@ -437,14 +531,15 @@ - SIZE(user_regs_struct) - sizeof(int); ebp = ULONG(user_regs + OFFSET(user_regs_struct_ebp)); esp = ULONG(user_regs + OFFSET(user_regs_struct_esp)); @@ -15081,7 +19652,7 @@ "get_netdump_panic_task: esp: %lx -> task: %lx\n", esp, task); for (i = 0; task && (i < NR_CPUS); i++) { -@@ -455,7 +581,7 @@ +@@ -455,7 +550,7 @@ if (IS_KVADDR(ebp)) { task = stkptr_to_task(ebp); if (CRASHDEBUG(1)) @@ -15090,7 +19661,7 @@ "get_netdump_panic_task: ebp: %lx -> task: %lx\n", ebp, task); for (i = 0; task && (i < NR_CPUS); i++) { -@@ -464,25 +590,37 @@ +@@ -464,25 +559,37 @@ } } } else if (nd->elf64) { @@ -15134,7 +19705,7 @@ "get_netdump_panic_task: esp: %lx -> task: %lx\n", esp, task); for (i = 0; task && (i < NR_CPUS); i++) { -@@ -493,8 +631,10 @@ +@@ -493,8 +600,10 @@ } } @@ -15146,7 +19717,7 @@ return NO_TASK; #endif -@@ -512,7 +652,7 @@ +@@ -512,7 +621,7 @@ return nd->switch_stack; return 0; #else @@ -15155,7 +19726,7 @@ return 0; if (nd->task_struct == task) -@@ -525,32 +665,40 @@ +@@ -525,32 +634,40 @@ int netdump_memory_dump(FILE *fp) { @@ -15199,7 +19770,7 @@ netdump_print(")\n"); netdump_print(" ndfd: %d\n", nd->ndfd); netdump_print(" ofp: %lx\n", nd->ofp); -@@ -566,7 +714,7 @@ +@@ -566,7 +683,7 @@ netdump_print(" phys_end: %llx\n", pls->phys_end); } @@ -15208,7 +19779,7 @@ netdump_print(" elf32: %lx\n", nd->elf32); netdump_print(" notes32: %lx\n", nd->notes32); netdump_print(" load32: %lx\n", nd->load32); -@@ -577,11 +725,64 @@ +@@ -577,11 +694,64 @@ netdump_print(" nt_prpsinfo: %lx\n", nd->nt_prpsinfo); netdump_print(" nt_taskstruct: %lx\n", nd->nt_taskstruct); netdump_print(" task_struct: %lx\n", nd->task_struct); @@ -15275,7 +19846,7 @@ dump_Elf32_Ehdr(nd->elf32); dump_Elf32_Phdr(nd->notes32, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -594,6 +795,7 @@ +@@ -594,6 +764,7 @@ break; case NETDUMP_ELF64: @@ -15283,7 +19854,7 @@ dump_Elf64_Ehdr(nd->elf64); dump_Elf64_Phdr(nd->notes64, ELFREAD); for (i = 0; i < nd->num_pt_load_segments; i++) -@@ -865,6 +1067,9 @@ +@@ -865,6 +1036,9 @@ netdump_print(" e_machine: %d ", elf->e_machine); switch (elf->e_machine) { @@ -15293,7 +19864,7 @@ case EM_IA_64: netdump_print("(EM_IA_64)\n"); break; -@@ -1061,7 +1266,7 @@ +@@ -1061,7 +1235,7 @@ */ static size_t @@ -15302,7 +19873,7 @@ { int i, lf; Elf32_Nhdr *note; -@@ -1085,17 +1290,26 @@ +@@ -1085,17 +1259,26 @@ { case NT_PRSTATUS: netdump_print("(NT_PRSTATUS)\n"); @@ -15333,7 +19904,7 @@ nd->nt_taskstruct = (void *)note; nd->task_struct = *((ulong *)(ptr + note->n_namesz)); nd->switch_stack = *((ulong *) -@@ -1105,14 +1319,59 @@ +@@ -1105,14 +1288,59 @@ case NT_DISKDUMP: netdump_print("(NT_DISKDUMP)\n"); uptr = (ulong *)(ptr + note->n_namesz); @@ -15394,7 +19965,7 @@ for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) { if (((i%4)==0)) { netdump_print("%s ", -@@ -1123,7 +1382,8 @@ +@@ -1123,7 +1351,8 @@ netdump_print("%08lx ", *uptr++); } if (!lf || (note->n_type == NT_TASKSTRUCT) || @@ -15404,7 +19975,7 @@ netdump_print("\n"); len = sizeof(Elf32_Nhdr); -@@ -1135,7 +1395,7 @@ +@@ -1135,7 +1364,7 @@ static size_t @@ -15413,7 +19984,7 @@ { int i, lf; Elf64_Nhdr *note; -@@ -1144,6 +1404,7 @@ +@@ -1144,6 +1373,7 @@ char *ptr; ulonglong *uptr; int *iptr; @@ -15421,7 +19992,7 @@ note = (Elf64_Nhdr *)((char *)nd->elf64 + offset); -@@ -1160,17 +1421,26 @@ +@@ -1160,17 +1390,26 @@ { case NT_PRSTATUS: netdump_print("(NT_PRSTATUS)\n"); @@ -15452,7 +20023,7 @@ nd->nt_taskstruct = (void *)note; nd->task_struct = *((ulong *)(ptr + note->n_namesz)); nd->switch_stack = *((ulong *) -@@ -1180,16 +1450,72 @@ +@@ -1180,16 +1419,72 @@ case NT_DISKDUMP: netdump_print("(NT_DISKDUMP)\n"); iptr = (int *)(ptr + note->n_namesz); @@ -15526,7 +20097,7 @@ for (i = lf = 0; i < note->n_descsz/sizeof(ulonglong); i++) { if (((i%2)==0)) { netdump_print("%s ", -@@ -1251,12 +1577,12 @@ +@@ -1251,12 +1546,12 @@ default: error(FATAL, @@ -15541,7 +20112,7 @@ get_netdump_regs_x86_64(struct bt_info *bt, ulong *ripp, ulong *rspp) { Elf64_Nhdr *note; -@@ -1267,8 +1593,13 @@ +@@ -1267,8 +1562,13 @@ if (is_task_active(bt->task)) bt->flags |= BT_DUMPFILE_SEARCH; @@ -15557,7 +20128,7 @@ len = sizeof(Elf64_Nhdr); len = roundup(len + note->n_namesz, 4); -@@ -1295,7 +1626,7 @@ +@@ -1295,7 +1595,7 @@ * the raw stack for some reasonable hooks. */ @@ -15566,7 +20137,7 @@ get_netdump_regs_x86(struct bt_info *bt, ulong *eip, ulong *esp) { int i, search, panic; -@@ -1320,6 +1651,7 @@ +@@ -1320,6 +1620,7 @@ if (STREQ(sym, "netconsole_netdump") || STREQ(sym, "netpoll_start_netdump") || STREQ(sym, "start_disk_dump") || @@ -15574,7 +20145,7 @@ STREQ(sym, "disk_dump")) { *eip = *up; *esp = search ? -@@ -1354,7 +1686,7 @@ +@@ -1354,7 +1655,7 @@ next_sysrq: *eip = *up; *esp = bt->stackbase + ((char *)(up+4) - bt->stackbuf); @@ -15583,7 +20154,7 @@ for (i++, up++; i < LONGS_PER_STACK; i++, up++) { sym = closest_symbol(*up); if (STREQ(sym, "sysrq_handle_crash")) -@@ -1371,7 +1703,15 @@ +@@ -1371,7 +1672,15 @@ *esp = search ? bt->stackbase + ((char *)(up+1) - bt->stackbuf) : *(up-1); @@ -15600,7 +20171,7 @@ return; } -@@ -1418,7 +1758,7 @@ +@@ -1418,7 +1727,7 @@ goto retry; } @@ -15609,7 +20180,7 @@ machdep->get_stack_frame(bt, eip, esp); } -@@ -1429,8 +1769,18 @@ +@@ -1429,8 +1738,18 @@ Elf64_Nhdr *note; size_t len; @@ -15630,7 +20201,7 @@ len = sizeof(Elf64_Nhdr); len = roundup(len + note->n_namesz, 4); -@@ -1446,3 +1796,147 @@ +@@ -1446,3 +1765,156 @@ { return (nd->flags & PARTIAL_DUMP ? TRUE : FALSE); } @@ -15778,8 +20349,17 @@ + + return paddr; +} ---- crash/diskdump.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/diskdump.c 2006-03-23 14:29:25.000000000 -0500 ++ ++struct vmcore_data * ++get_kdump_vmcore_data(void) ++{ ++ if (!VMCORE_VALID() || !KDUMP_DUMPFILE()) ++ return NULL; ++ ++ return &vmcore_data; ++} +--- crash/diskdump.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/diskdump.c 2006-03-23 14:30:14.000000000 -0500 @@ -1,16 +1,16 @@ /* * diskdump.c @@ -16302,8 +20882,8 @@ } /* ---- crash/xendump.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/xendump.c 2006-07-11 09:36:03.000000000 -0400 +--- crash/xendump.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/xendump.c 2006-07-11 15:49:24.000000000 -0400 @@ -0,0 +1,1170 @@ +/* + * xendump.c @@ -17475,8 +22055,8 @@ + } + } +} ---- crash/unwind.c.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/unwind.c 2005-11-23 09:37:52.000000000 -0500 +--- crash/unwind.c.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/unwind.c 2005-11-23 09:40:14.000000000 -0500 @@ -1397,9 +1397,22 @@ req = &request; @@ -17503,8 +22083,8 @@ machdep->machspec->unw_tables_offset = req->member_offset/BITS_PER_BYTE; ---- crash/defs.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/defs.h 2006-08-03 17:25:55.000000000 -0400 +--- crash/defs.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/defs.h 2006-08-31 16:00:41.000000000 -0400 @@ -1,8 +1,8 @@ /* defs.h - core analysis suite * @@ -17614,16 +22194,17 @@ #define CRASHDEBUG(x) (pc->debug >= (x)) #define CRASHDEBUG_SUSPEND(X) { pc->debug_save = pc->debug; pc->debug = X; } -@@ -328,6 +346,8 @@ +@@ -328,6 +346,9 @@ char *lastcmd; /* previously-executed command */ ulong cmdgencur; /* current command generation number */ ulong cmdgenspec; /* specified command generation num */ + ulong curcmd_flags; /* general purpose per-command flag */ +#define XEN_MACHINE_ADDR (0x1) ++#define REPEAT (0x2) int cur_gdb_cmd; /* current gdb command */ int last_gdb_cmd; /* previously-executed gdb command */ int sigint_cnt; /* number of ignored SIGINTs */ -@@ -407,9 +427,23 @@ +@@ -407,9 +428,23 @@ #define KALLSYMS_V2 (0x2000) #define TVEC_BASES_V2 (0x4000) #define GCC_3_3_3 (0x8000) @@ -17647,7 +22228,7 @@ struct kernel_table { /* kernel data */ ulong flags; ulong stext; -@@ -420,6 +454,7 @@ +@@ -420,6 +455,7 @@ ulong init_end; ulong end; int cpus; @@ -17655,7 +22236,7 @@ void (*display_bh)(void); ulong module_list; ulong kernel_module; -@@ -430,11 +465,32 @@ +@@ -430,11 +466,32 @@ uint kernel_version[3]; uint gcc_version[3]; int runq_siblings; @@ -17689,7 +22270,7 @@ }; /* -@@ -602,6 +658,8 @@ +@@ -602,6 +659,8 @@ (void *)(&bt->stackbuf[(ulong)STACK_OFFSET_TYPE(OFF)]), (size_t)(SZ)) struct machine_specific; /* uniquely defined below each machine's area */ @@ -17698,7 +22279,7 @@ struct machdep_table { ulong flags; -@@ -645,14 +703,24 @@ +@@ -645,14 +704,24 @@ char **file; } *line_number_hooks; ulong last_pgd_read; @@ -17723,7 +22304,7 @@ }; /* -@@ -660,19 +728,23 @@ +@@ -660,19 +729,23 @@ * as defined in their processor-specific files below. (see KSYMS_START defs). */ #define HWRESET (0x80000000) @@ -17754,7 +22335,7 @@ #define FILL_PGD(PGD, TYPE, SIZE) \ if (!IS_LAST_PGD_READ(PGD)) { \ -@@ -681,6 +753,13 @@ +@@ -681,6 +754,13 @@ machdep->last_pgd_read = (ulong)(PGD); \ } @@ -17768,7 +22349,7 @@ #define FILL_PMD(PMD, TYPE, SIZE) \ if (!IS_LAST_PMD_READ(PMD)) { \ readmem((ulonglong)(PMD), TYPE, machdep->pmd, \ -@@ -737,6 +816,7 @@ +@@ -737,6 +817,7 @@ #define FOREACH_c_FLAG (0x40000) #define FOREACH_f_FLAG (0x80000) #define FOREACH_o_FLAG (0x100000) @@ -17776,7 +22357,7 @@ struct foreach_data { ulong flags; -@@ -875,6 +955,7 @@ +@@ -875,6 +956,7 @@ long mm_struct_mmap; long mm_struct_pgd; long mm_struct_rss; @@ -17784,7 +22365,7 @@ long mm_struct_total_vm; long mm_struct_start_code; long vm_area_struct_vm_mm; -@@ -970,6 +1051,11 @@ +@@ -970,6 +1052,11 @@ long hw_interrupt_type_set_affinity; long irq_cpustat_t___softirq_active; long irq_cpustat_t___softirq_mask; @@ -17796,7 +22377,7 @@ long files_struct_max_fds; long files_struct_max_fdset; long files_struct_open_fds; -@@ -1088,6 +1174,8 @@ +@@ -1088,6 +1175,8 @@ long inet_opt_dport; long inet_opt_sport; long inet_opt_num; @@ -17805,7 +22386,7 @@ long timer_list_list; long timer_list_next; long timer_list_entry; -@@ -1123,6 +1211,7 @@ +@@ -1123,6 +1212,7 @@ long zone_struct_name; long zone_struct_size; long zone_struct_memsize; @@ -17813,7 +22394,7 @@ long zone_struct_zone_start_paddr; long zone_struct_zone_start_mapnr; long zone_struct_zone_mem_map; -@@ -1210,7 +1299,14 @@ +@@ -1210,7 +1300,14 @@ long x8664_pda_irqstackptr; long x8664_pda_level4_pgt; long x8664_pda_cpunumber; @@ -17828,7 +22409,7 @@ }; struct size_table { /* stash of commonly-used sizes */ -@@ -1239,6 +1335,7 @@ +@@ -1239,6 +1336,7 @@ long umode_t; long dentry; long files_struct; @@ -17836,7 +22417,7 @@ long fs_struct; long file; long inode; -@@ -1292,15 +1389,19 @@ +@@ -1292,15 +1390,19 @@ long address_space; long char_device_struct; long inet_sock; @@ -17856,7 +22437,7 @@ }; struct array_table { -@@ -1389,6 +1490,7 @@ +@@ -1389,6 +1491,7 @@ #define ULONGLONG(ADDR) *((ulonglong *)((char *)(ADDR))) #define ULONG_PTR(ADDR) *((ulong **)((char *)(ADDR))) #define USHORT(ADDR) *((ushort *)((char *)(ADDR))) @@ -17864,7 +22445,7 @@ #define VOID_PTR(ADDR) *((void **)((char *)(ADDR))) struct node_table { -@@ -1420,6 +1522,7 @@ +@@ -1420,6 +1523,7 @@ ulong kmem_max_limit; ulong kmem_max_cpus; ulong kmem_cache_count; @@ -17872,14 +22453,12 @@ ulong PG_reserved; ulong PG_slab; int kmem_cache_namelen; -@@ -1441,17 +1544,29 @@ +@@ -1441,17 +1545,35 @@ ulong cached_vma_hits[VMA_CACHE]; int vma_cache_index; ulong vma_cache_fills; -+ void *mem_sec; -+ int ZONE_HIGHMEM; - }; - +-}; +- -#define NODES (0x1) -#define ZONES (0x2) -#define PERCPU_KMALLOC_V1 (0x4) @@ -17889,6 +22468,14 @@ -#define PERCPU_KMALLOC_V2 (0x40) -#define KMEM_CACHE_UNAVAIL (0x80) -#define DISCONTIGMEM (0x100) ++ void *mem_sec; ++ int ZONE_HIGHMEM; ++ ulong *node_online_map; ++ int node_online_map_len; ++ int nr_vm_stat_items; ++ char **vm_stat_items; ++}; ++ +#define NODES (0x1) +#define ZONES (0x2) +#define PERCPU_KMALLOC_V1 (0x4) @@ -17903,6 +22490,8 @@ +#define SPARSEMEM_EX (0x800) +#define PERCPU_KMALLOC_V2_NODES (0x1000) +#define KMEM_CACHE_DELAY (0x2000) ++#define NODES_ONLINE (0x4000) ++#define VM_STAT (0x8000) + +#define IS_FLATMEM() (vt->flags & FLATMEM) +#define IS_DISCONTIGMEM() (vt->flags & DISCONTIGMEM) @@ -17911,7 +22500,15 @@ #define COMMON_VADDR_SPACE() (vt->flags & COMMON_VADDR) #define PADDR_PRLEN (vt->paddr_prlen) -@@ -1659,6 +1774,7 @@ +@@ -1596,6 +1718,7 @@ + #define NO_SEC_CONTENTS (0x40) + #define FORCE_DEBUGINFO (0x80) + #define CRC_MATCHES (0x100) ++#define ADD_SYMBOL_FILE (0x200) + + #endif /* !GDB_COMMON */ + +@@ -1659,6 +1782,7 @@ #define KVADDR (0x1) #define UVADDR (0x2) #define PHYSADDR (0x4) @@ -17919,7 +22516,7 @@ #define AMBIGUOUS (~0) #define USE_USER_PGD (UVADDR << 2) -@@ -1680,6 +1796,33 @@ +@@ -1680,6 +1804,33 @@ #define VIRTPAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) #define PHYSPAGEBASE(X) (((physaddr_t)(X)) & (physaddr_t)machdep->pagemask) @@ -17953,7 +22550,7 @@ /* * Machine specific stuff */ -@@ -1689,8 +1832,8 @@ +@@ -1689,8 +1840,8 @@ #define MACHINE_TYPE "X86" #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) @@ -17964,7 +22561,7 @@ #define PGDIR_SHIFT_2LEVEL (22) #define PTRS_PER_PTE_2LEVEL (1024) -@@ -1724,22 +1867,68 @@ +@@ -1724,22 +1875,68 @@ #define TIF_SIGPENDING (2) @@ -18002,18 +22599,19 @@ -#define USERSPACE_TOP 0x0000008000000000 -#define __START_KERNEL_map 0xffffffff80000000 -#define PAGE_OFFSET 0x0000010000000000 +- +-#define VMALLOC_START 0xffffff0000000000 +-#define VMALLOC_END 0xffffff7fffffffff +-#define MODULES_VADDR 0xffffffffa0000000 +-#define MODULES_END 0xffffffffafffffff +#define USERSPACE_TOP (machdep->machspec->userspace_top) +#define PAGE_OFFSET (machdep->machspec->page_offset) +#define VMALLOC_START (machdep->machspec->vmalloc_start_addr) +#define VMALLOC_END (machdep->machspec->vmalloc_end) +#define MODULES_VADDR (machdep->machspec->modules_vaddr) +#define MODULES_END (machdep->machspec->modules_end) - --#define VMALLOC_START 0xffffff0000000000 --#define VMALLOC_END 0xffffff7fffffffff --#define MODULES_VADDR 0xffffffffa0000000 --#define MODULES_END 0xffffffffafffffff -+#define __START_KERNEL_map 0xffffffff80000000 ++ ++#define __START_KERNEL_map 0xffffffff80000000UL #define MODULES_LEN (MODULES_END - MODULES_VADDR) +#define USERSPACE_TOP_ORIG 0x0000008000000000 @@ -18040,7 +22638,7 @@ #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) x86_64_VTOP((ulong)(X)) #define IS_VMALLOC_ADDR(X) x86_64_IS_VMALLOC_ADDR((ulong)(X)) -@@ -1757,12 +1946,25 @@ +@@ -1757,12 +1954,25 @@ #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) @@ -18067,7 +22665,7 @@ /* * PHYSICAL_PAGE_MASK changed (enlarged) between 2.4 and 2.6, so * for safety, use the 2.6 values to generate it. -@@ -1796,6 +1998,15 @@ +@@ -1796,6 +2006,15 @@ #define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask) @@ -18083,7 +22681,7 @@ #define CPU_PDA_READ(CPU, BUFFER) \ (STRNEQ("cpu_pda", closest_symbol((symbol_value("cpu_pda") + \ ((CPU) * SIZE(x8664_pda))))) && \ -@@ -1806,6 +2017,9 @@ +@@ -1806,6 +2025,9 @@ #define VALID_LEVEL4_PGT_ADDR(X) \ (((X) == VIRTPAGEBASE(X)) && IS_KVADDR(X) && !IS_VMALLOC_ADDR(X)) @@ -18093,7 +22691,7 @@ #endif /* X86_64 */ #ifdef ALPHA -@@ -1816,7 +2030,7 @@ +@@ -1816,7 +2038,7 @@ #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) @@ -18102,7 +22700,7 @@ #define KSEG_BASE_48_BIT (0xffff800000000000) #define KSEG_BASE (0xfffffc0000000000) #define _PFN_MASK (0xFFFFFFFF00000000) -@@ -1861,7 +2075,7 @@ +@@ -1861,7 +2083,7 @@ #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) @@ -18111,7 +22709,7 @@ #define PGDIR_SHIFT (22) #define PTRS_PER_PTE (1024) -@@ -1884,6 +2098,9 @@ +@@ -1884,6 +2106,9 @@ #define TIF_SIGPENDING (2) @@ -18121,7 +22719,17 @@ #endif /* PPC */ #ifdef IA64 -@@ -1917,16 +2134,57 @@ +@@ -1908,6 +2133,9 @@ + #define KERNEL_UNCACHED_BASE ((ulong)KERNEL_UNCACHED_REGION << REGION_SHIFT) + #define KERNEL_CACHED_BASE ((ulong)KERNEL_CACHED_REGION << REGION_SHIFT) + ++#define _SECTION_SIZE_BITS 30 ++#define _MAX_PHYSMEM_BITS 50 ++ + /* + * As of 2.6, these are no longer straight forward. + */ +@@ -1917,16 +2145,57 @@ #define SWITCH_STACK_ADDR(X) (ia64_get_switch_stack((ulong)(X))) @@ -18185,7 +22793,7 @@ * First, define the various bits in a PTE. Note that the PTE format * matches the VHPT short format, the firt doubleword of the VHPD long * format, and the first doubleword of the TLB insertion format. -@@ -1978,6 +2236,7 @@ +@@ -1978,6 +2247,7 @@ #define __DIRTY_BITS _PAGE_ED | __DIRTY_BITS_NO_ED #define EFI_PAGE_SHIFT (12) @@ -18193,7 +22801,7 @@ /* * NOTE: #include'ing creates too many compiler problems, so * this stuff is hardwired here; it's probably etched in stone somewhere. -@@ -2042,7 +2301,7 @@ +@@ -2042,7 +2312,7 @@ #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) @@ -18202,7 +22810,7 @@ #define KERNELBASE machdep->pageoffset #define PGDIR_SHIFT (machdep->pageshift + (machdep->pageshift -3) + (machdep->pageshift - 2)) -@@ -2067,6 +2326,32 @@ +@@ -2067,6 +2337,32 @@ #define PGD_OFFSET(vaddr) ((vaddr >> PGDIR_SHIFT) & 0x7ff) #define PMD_OFFSET(vaddr) ((vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) @@ -18235,7 +22843,7 @@ #define _PAGE_PRESENT 0x001UL /* software: pte contains a translation */ #define _PAGE_USER 0x002UL /* matches one of the PP bits */ #define _PAGE_RW 0x004UL /* software: user write access allowed */ -@@ -2087,6 +2372,9 @@ +@@ -2087,6 +2383,9 @@ #define STACK_FRAME_OVERHEAD 112 #define EXCP_FRAME_MARKER 0x7265677368657265 @@ -18245,7 +22853,16 @@ #endif /* PPC64 */ #ifdef S390 -@@ -2116,7 +2404,7 @@ +@@ -2095,7 +2394,7 @@ + + #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) + #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) +-#define IS_VMALLOC_ADDR(X) s390_IS_VMALLOC_ADDR(X) ++#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) + + #define PTRS_PER_PTE 1024 + #define PTRS_PER_PMD 1 +@@ -2116,7 +2415,7 @@ #define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) #define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) @@ -18254,7 +22871,25 @@ #define PTRS_PER_PTE 512 #define PTRS_PER_PMD 1024 #define PTRS_PER_PGD 2048 -@@ -2685,6 +2973,9 @@ +@@ -2186,6 +2485,7 @@ + #define UNUSED (-1) + + #define BITS_PER_BYTE (8) ++#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long)) + + /* + * precision lengths for fprintf +@@ -2534,6 +2834,9 @@ + void cmd_gdb(void); /* gdb_interface.c */ + void cmd_net(void); /* net.c */ + void cmd_extend(void); /* extensions.c */ ++#if defined(S390) || defined(S390X) ++void cmd_s390dbf(void); ++#endif + + /* + * main.c +@@ -2685,6 +2988,9 @@ int machine_type(char *); void command_not_supported(void); void option_not_supported(int); @@ -18264,7 +22899,7 @@ /* -@@ -2721,6 +3012,7 @@ +@@ -2721,6 +3027,7 @@ struct syment *next_symbol(char *, struct syment *); struct syment *prev_symbol(char *, struct syment *); void get_symbol_data(char *, long, void *); @@ -18272,7 +22907,7 @@ char *value_to_symstr(ulong, char *, ulong); char *value_symbol(ulong); ulong symbol_value(char *); -@@ -2807,6 +3099,7 @@ +@@ -2807,6 +3114,7 @@ char *swap_location(ulonglong, char *); void clear_swap_info_cache(void); uint memory_page_size(void); @@ -18280,7 +22915,7 @@ ulong first_vmalloc_address(void); int l1_cache_size(void); int dumpfile_memory(int); -@@ -2838,6 +3131,7 @@ +@@ -2838,6 +3146,7 @@ void open_files_dump(ulong, int, struct reference *); void get_pathname(ulong, char *, int, int, ulong); ulong file_to_dentry(ulong); @@ -18288,7 +22923,17 @@ void nlm_files_dump(void); int get_proc_version(void); int file_checksum(char *, long *); -@@ -3005,6 +3299,8 @@ +@@ -2945,6 +3254,9 @@ + extern char *help_waitq[]; + extern char *help_whatis[]; + extern char *help_wr[]; ++#if defined(S390) || defined(S390X) ++extern char *help_s390dbf[]; ++#endif + + /* + * task.c +@@ -3005,11 +3317,13 @@ */ void register_extension(struct command_table_entry *); void dump_extension_table(int); @@ -18297,7 +22942,13 @@ /* * kernel.c -@@ -3020,7 +3316,8 @@ + */ +-void kernel_init(int); ++void kernel_init(void); + void module_init(void); + void verify_version(void); + void verify_spinlock(void); +@@ -3020,7 +3334,8 @@ void generic_dump_irq(int); int generic_dis_filter(ulong, char *); void display_sys_stats(void); @@ -18307,7 +22958,7 @@ void dump_bt_info(struct bt_info *); void dump_log(int); void set_cpu(int); -@@ -3069,6 +3366,8 @@ +@@ -3069,6 +3384,8 @@ #define BT_DUMPFILE_SEARCH (0x800000000ULL) #define BT_EFRAME_SEARCH2 (0x1000000000ULL) #define BT_START (0x2000000000ULL) @@ -18316,7 +22967,7 @@ #define BT_REF_HEXVAL (0x1) #define BT_REF_SYMBOL (0x2) -@@ -3101,6 +3400,17 @@ +@@ -3101,6 +3418,17 @@ #define TYPE_S390D (REMOTE_VERBOSE << 6) #define TYPE_NETDUMP (REMOTE_VERBOSE << 7) @@ -18334,7 +22985,7 @@ /* * dev.c */ -@@ -3140,6 +3450,8 @@ +@@ -3140,6 +3468,8 @@ ulong entry_tramp_start; ulong entry_tramp_end; physaddr_t entry_tramp_start_phys; @@ -18343,7 +22994,7 @@ }; struct syment *x86_is_entry_tramp_address(ulong, ulong *); -@@ -3194,7 +3506,16 @@ +@@ -3194,7 +3524,17 @@ #define NMI_STACK 2 /* ebase[] offset to NMI exception stack */ struct machine_specific { @@ -18353,6 +23004,7 @@ + ulong vmalloc_end; + ulong modules_vaddr; + ulong modules_end; ++ ulong phys_base; char *pml4; + char *upml; + ulong last_upml_read; @@ -18360,7 +23012,7 @@ char *irqstack; struct x86_64_pt_regs_offsets pto; struct x86_64_stkinfo stkinfo; -@@ -3202,6 +3523,11 @@ +@@ -3202,6 +3542,12 @@ #define KSYMS_START (0x1) #define PT_REGS_INIT (0x2) @@ -18369,10 +23021,11 @@ +#define VM_XEN (0x10) +#define NO_TSS (0x20) +#define SCHED_TEXT (0x40) ++#define PHYS_BASE (0x80) #define _2MB_PAGE_MASK (~((MEGABYTES(2))-1)) #endif -@@ -3240,13 +3566,42 @@ +@@ -3240,13 +3586,42 @@ ulong hwintrstack[NR_CPUS]; char *hwstackbuf; uint hwstacksize; @@ -18416,7 +23069,7 @@ #endif /* -@@ -3396,10 +3751,23 @@ +@@ -3396,10 +3771,24 @@ int netdump_init(char *, FILE *); ulong get_netdump_panic_task(void); ulong get_netdump_switch_stack(ulong); @@ -18427,7 +23080,8 @@ int is_partial_netdump(void); +void get_netdump_regs_x86(struct bt_info *, ulong *, ulong *); +void get_netdump_regs_x86_64(struct bt_info *, ulong *, ulong *); -+ ++struct vmcore_data; ++struct vmcore_data *get_kdump_vmcore_data(void); +int read_kdump(int, void *, int, ulong, physaddr_t); +int write_kdump(int, void *, int, ulong, physaddr_t); +int is_kdump(char *, ulong); @@ -18441,7 +23095,7 @@ /* * diskdump.c -@@ -3418,6 +3786,23 @@ +@@ -3418,6 +3807,23 @@ void get_diskdump_regs(struct bt_info *, ulong *, ulong *); /* @@ -18465,7 +23119,7 @@ * net.c */ void net_init(void); -@@ -3560,6 +3945,7 @@ +@@ -3560,6 +3966,7 @@ #define LKCD_DUMP_V7 (0x7) /* DUMP_VERSION_NUMBER */ #define LKCD_DUMP_V8 (0x8) /* DUMP_VERSION_NUMBER */ #define LKCD_DUMP_V9 (0x9) /* DUMP_VERSION_NUMBER */ @@ -18473,8 +23127,8 @@ #define LKCD_DUMP_VERSION_NUMBER_MASK (0xf) #define LKCD_DUMP_RAW (0x1) /* DUMP_[DH_]RAW */ ---- crash/vas_crash.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/vas_crash.h 2006-05-15 16:50:28.000000000 -0400 +--- crash/vas_crash.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/vas_crash.h 2006-05-15 16:51:28.000000000 -0400 @@ -19,7 +19,7 @@ */ @@ -18484,9 +23138,9 @@ void save_core(void); ---- crash/netdump.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/netdump.h 2006-06-28 14:16:16.000000000 -0400 -@@ -24,3 +24,37 @@ +--- crash/netdump.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/netdump.h 2006-08-31 15:59:44.000000000 -0400 +@@ -24,3 +24,68 @@ #define NT_TASKSTRUCT 4 #define NT_DISKDUMP 0x70000001 @@ -18502,6 +23156,37 @@ + +#endif /* NOTDEF */ + ++struct pt_load_segment { ++ off_t file_offset; ++ physaddr_t phys_start; ++ physaddr_t phys_end; ++}; ++ ++struct vmcore_data { ++ ulong flags; ++ int ndfd; ++ FILE *ofp; ++ uint header_size; ++ char *elf_header; ++ uint num_pt_load_segments; ++ struct pt_load_segment *pt_load_segments; ++ Elf32_Ehdr *elf32; ++ Elf32_Phdr *notes32; ++ Elf32_Phdr *load32; ++ Elf64_Ehdr *elf64; ++ Elf64_Phdr *notes64; ++ Elf64_Phdr *load64; ++ void *nt_prstatus; ++ void *nt_prpsinfo; ++ void *nt_taskstruct; ++ ulong task_struct; ++ uint page_size; ++ ulong switch_stack; ++ uint num_prstatus_notes; ++ void *nt_prstatus_percpu[NR_CPUS]; ++ struct xen_kdump_data *xen_kdump_data; ++}; ++ +/* + * Proposed ELF note for Xen (writable pagetable) per-vcpu CR3. + */ @@ -18524,8 +23209,8 @@ +#define KDUMP_MFN_LIST (0x4) + +#define P2M_FAILURE ((physaddr_t)(0xffffffffffffffffLL)) ---- crash/diskdump.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/diskdump.h 2005-11-30 15:15:00.000000000 -0500 +--- crash/diskdump.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/diskdump.h 2005-11-30 15:50:28.000000000 -0500 @@ -3,6 +3,8 @@ * * Copyright (C) 2004, 2005 David Anderson @@ -18597,8 +23282,8 @@ +#define PAGE_VALID (0x1) /* flags */ +#define DISKDUMP_VALID_PAGE(flags) ((flags) & PAGE_VALID) + ---- crash/xendump.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/xendump.h 2006-06-09 11:26:09.000000000 -0400 +--- crash/xendump.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/xendump.h 2006-06-09 16:55:17.000000000 -0400 @@ -0,0 +1,97 @@ +/* + * xendump.h @@ -18697,8 +23382,8 @@ + +#define MFN_NOT_FOUND (-1) +#define PFN_NOT_FOUND (-1) ---- crash/lkcd_vmdump_v1.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_vmdump_v1.h 2006-08-07 13:50:37.000000000 -0400 +--- crash/lkcd_vmdump_v1.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/lkcd_vmdump_v1.h 2006-08-07 13:51:35.000000000 -0400 @@ -114,8 +114,12 @@ /* the dump registers */ @@ -18712,8 +23397,8 @@ /* the address of the current task */ struct task_struct *dh_current_task; ---- crash/lkcd_vmdump_v2_v3.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_vmdump_v2_v3.h 2006-08-07 14:55:38.000000000 -0400 +--- crash/lkcd_vmdump_v2_v3.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/lkcd_vmdump_v2_v3.h 2006-08-07 15:00:27.000000000 -0400 @@ -81,7 +81,11 @@ uint32_t dha_eip; @@ -18726,8 +23411,8 @@ } dump_header_asm_t; ---- crash/lkcd_dump_v5.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_dump_v5.h 2006-03-22 08:45:35.000000000 -0500 +--- crash/lkcd_dump_v5.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/lkcd_dump_v5.h 2006-03-22 09:11:11.000000000 -0500 @@ -35,7 +35,7 @@ #ifndef _DUMP_H #define _DUMP_H @@ -18737,8 +23422,8 @@ /* define TRUE and FALSE for use in our dump modules */ #ifndef FALSE ---- crash/lkcd_dump_v7.h.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/lkcd_dump_v7.h 2006-03-22 08:45:57.000000000 -0500 +--- crash/lkcd_dump_v7.h.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/lkcd_dump_v7.h 2006-03-22 09:11:11.000000000 -0500 @@ -35,7 +35,7 @@ #ifndef _DUMP_H #define _DUMP_H @@ -18748,8 +23433,8 @@ /* define TRUE and FALSE for use in our dump modules */ #ifndef FALSE ---- crash/Makefile.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/Makefile 2006-08-07 15:00:37.000000000 -0400 +--- crash/Makefile.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/Makefile 2006-09-13 11:10:22.000000000 -0400 @@ -3,8 +3,8 @@ # Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. # www.missioncriticallinux.com, info@missioncriticallinux.com @@ -18761,8 +23446,14 @@ # # 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 -@@ -39,6 +39,8 @@ - GDB_FILES= +@@ -35,10 +35,12 @@ + # + # GDB, GDB_FILES and GDB_OFILES will be configured automatically by configure + # +-GDB=gdb-6.1 +-GDB_FILES=${GDB_6.1_FILES} ++GDB= ++GDB_FILES= GDB_OFILES= +GDB_PATCH_FILES=gdb-6.1.patch @@ -18779,7 +23470,12 @@ LKCD_DUMP_HFILES=lkcd_vmdump_v1.h lkcd_vmdump_v2_v3.h lkcd_dump_v5.h \ lkcd_dump_v7.h lkcd_dump_v8.h lkcd_fix_mem.h LKCD_TRACE_HFILES=lkcd_x86_trace.h -@@ -75,7 +77,7 @@ +@@ -71,11 +73,11 @@ + + CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \ + kernel.c test.c gdb_interface.c configure.c net.c dev.c \ +- alpha.c x86.c ppc.c ia64.c s390.c s390x.c ppc64.c x86_64.c \ ++ alpha.c x86.c ppc.c ia64.c s390.c s390x.c s390dbf.c ppc64.c x86_64.c \ extensions.c remote.c va_server.c va_server_v1.c symbols.c cmdline.c \ lkcd_common.c lkcd_v1.c lkcd_v2_v3.c lkcd_v5.c lkcd_v7.c lkcd_v8.c\ lkcd_fix_mem.c s390_dump.c lkcd_x86_trace.c \ @@ -18788,8 +23484,12 @@ SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \ ${REDHAT_CFILES} ${REDHAT_HFILES} ${UNWIND_HFILES} \ -@@ -86,9 +88,18 @@ - alpha.o x86.o ppc.o ia64.o s390.o s390x.o ppc64.o x86_64.o \ +@@ -83,12 +85,21 @@ + + OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \ + build_data.o kernel.o test.o gdb_interface.o net.o dev.o \ +- alpha.o x86.o ppc.o ia64.o s390.o s390x.o ppc64.o x86_64.o \ ++ alpha.o x86.o ppc.o ia64.o s390.o s390x.o s390dbf.o ppc64.o x86_64.o \ extensions.o remote.o va_server.o va_server_v1.o symbols.o cmdline.o \ lkcd_common.o lkcd_v1.o lkcd_v2_v3.o lkcd_v5.o lkcd_v7.o lkcd_v8.o \ - lkcd_fix_mem.o s390_dump.o netdump.o diskdump.o \ @@ -18867,7 +23567,17 @@ cc -c ${CFLAGS} -DMCLX x86.c ${WARNING_OPTIONS} ${WARNING_ERROR} alpha.o: ${GENERIC_HFILES} alpha.c -@@ -353,6 +375,9 @@ +@@ -342,6 +364,9 @@ + s390x.o: ${GENERIC_HFILES} ${IBM_HFILES} s390x.c + cc -c ${CFLAGS} s390x.c ${WARNING_OPTIONS} ${WARNING_ERROR} + ++s390dbf.o: ${GENERIC_HFILES} ${IBM_HFILES} s390dbf.c ++ cc -c ${CFLAGS} s390dbf.c ${WARNING_OPTIONS} ${WARNING_ERROR} ++ + s390_dump.o: ${GENERIC_HFILES} ${IBM_HFILES} s390_dump.c + cc -c ${CFLAGS} s390_dump.c ${WARNING_OPTIONS} ${WARNING_ERROR} + +@@ -353,6 +378,9 @@ diskdump.o: ${GENERIC_HFILES} ${REDHAT_HFILES} diskdump.c cc -c ${CFLAGS} diskdump.c ${WARNING_OPTIONS} ${WARNING_ERROR} @@ -18877,7 +23587,7 @@ extensions.o: ${GENERIC_HFILES} extensions.c cc -c ${CFLAGS} extensions.c ${WARNING_OPTIONS} ${WARNING_ERROR} -@@ -393,13 +418,13 @@ +@@ -393,13 +421,13 @@ gdb_files: make_configure @./configure -q -b @@ -18894,7 +23604,7 @@ ctags: ctags ${SOURCE_FILES} -@@ -411,7 +436,7 @@ +@@ -411,7 +439,7 @@ do_tar: @if [ -f ${PROGRAM} ]; then \ ./${PROGRAM} --no_crashrc -h README > README; fi @@ -18903,7 +23613,16 @@ @echo; ls -l ${PROGRAM}.tar.gz # To create a base tar file for Red Hat RPM packaging, pass the base RPM -@@ -446,8 +471,8 @@ +@@ -421,7 +449,7 @@ + # spec file will have its own release number, which will in turn get passed + # to the "all" target upon the initial build. + +-RELEASE=4.0 ++RELEASE= + + release: make_configure + @if [ "`id --user`" != "0" ]; then \ +@@ -446,8 +474,8 @@ @rm -f ${PROGRAM}-${RELEASE}.tar.gz @rm -f ${PROGRAM}-${RELEASE}.src.rpm @chown root ./RELDIR/${PROGRAM}-${RELEASE} @@ -18914,7 +23633,7 @@ @cp ${GDB}.tar.gz ./RELDIR/${PROGRAM}-${RELEASE} @./${PROGRAM} --no_crashrc -h README > ./RELDIR/${PROGRAM}-${RELEASE}/README @(cd ./RELDIR; find . -exec chown root {} ";") -@@ -488,3 +513,10 @@ +@@ -488,3 +516,10 @@ dis: objdump --disassemble --line-numbers ${PROGRAM} > ${PROGRAM}.dis @@ -18925,8 +23644,8 @@ + +do_extensions: + @(cd extensions; make -i OBJECTS="$(EXTENSION_OBJECT_FILES)" TARGET=$(TARGET)) ---- crash/gdb-6.1.patch.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/gdb-6.1.patch 2006-01-03 13:36:25.000000000 -0500 +--- crash/gdb-6.1.patch.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/gdb-6.1.patch 2006-01-03 14:48:26.000000000 -0500 @@ -0,0 +1,11 @@ +--- gdb-6.1/bfd/coff-alpha.c.orig ++++ gdb-6.1/bfd/coff-alpha.c @@ -18939,14 +23658,14 @@ + } + + if (lita_sec_data->gp != 0) ---- crash/README.orig 2006-08-07 15:00:37.000000000 -0400 -+++ crash/README 2006-08-07 15:00:33.000000000 -0400 +--- crash/README.orig 2006-09-13 11:10:23.000000000 -0400 ++++ crash/README 2006-09-13 11:10:21.000000000 -0400 @@ -69,7 +69,7 @@ After the kernel is re-compiled, the uncompressed "vmlinux" kernel that is created in the top-level kernel build directory must be saved. - To build this utility, simply uncompress the tar file, enter the crash-4.0 -+ To build this utility, simply uncompress the tar file, enter the crash-4.0-3.1 ++ To build this utility, simply uncompress the tar file, enter the crash-4.0-3.3 subdirectory, and type "make". The initial build will take several minutes because the gdb module must be configured and and built. Alternatively, the crash source RPM file may be installed and built, and the resultant crash @@ -18958,7 +23677,7 @@ - Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - Copyright (C) 2004, 2005 IBM Corporation - Copyright (C) 1999-2005 Hewlett-Packard Co -+ crash 4.0-3.1 ++ crash 4.0-3.3 + Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006 IBM Corporation + Copyright (C) 1999-2006 Hewlett-Packard Co @@ -18972,7 +23691,7 @@ DUMPFILE: /dev/mem CPUS: 1 - DATE: Wed Jul 13 13:26:00 2005 -+ DATE: Mon Aug 7 15:00:33 2006 ++ DATE: Wed Sep 13 11:10:21 2006 UPTIME: 10 days, 22:55:18 LOAD AVERAGE: 0.08, 0.03, 0.01 TASKS: 42 @@ -18981,7 +23700,7 @@ extend mach repeat timer - crash version: 4.0 gdb version: 6.1 -+ crash version: 4.0-3.1 gdb version: 6.1 ++ crash version: 4.0-3.3 gdb version: 6.1 For help on any command above, enter "help ". For help on input options, enter "help input". For help on output options, enter "help output". @@ -18993,7 +23712,7 @@ - Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - Copyright (C) 2004, 2005 IBM Corporation - Copyright (C) 1999-2005 Hewlett-Packard Co -+ crash 4.0-3.1 ++ crash 4.0-3.3 + Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006 IBM Corporation + Copyright (C) 1999-2006 Hewlett-Packard Co @@ -19010,7 +23729,7 @@ - Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. - Copyright (C) 2004, 2005 IBM Corporation - Copyright (C) 1999-2005 Hewlett-Packard Co -+ crash 4.0-3.1 ++ crash 4.0-3.3 + Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. + Copyright (C) 2004, 2005, 2006 IBM Corporation + Copyright (C) 1999-2006 Hewlett-Packard Co diff --git a/crash.spec b/crash.spec index 09fda88..8e6f02e 100644 --- a/crash.spec +++ b/crash.spec @@ -4,7 +4,7 @@ Summary: crash utility for live systems; netdump, diskdump, LKCD or mcore dumpfiles Name: crash Version: 4.0 -Release: 3.1 +Release: 3.3 License: GPL Group: Development/Debuggers Source: %{name}-%{version}.tar.gz @@ -45,6 +45,10 @@ rm -rf %{buildroot} %doc README %changelog +* Wed Sep 13 2006 Dave Anderson - 4.0-3.3 +- Updated crash.patch to match upstream version 4.0-3.3. +- Support for x86_64 relocatable kernels. BZ #204557 + * Mon Aug 7 2006 Dave Anderson - 4.0-3.1 - Updated crash.patch to match upstream version 4.0-3.1. - Added kdump reference to description.