diff --git a/.crash.metadata b/.crash.metadata new file mode 100644 index 0000000..d966af7 --- /dev/null +++ b/.crash.metadata @@ -0,0 +1 @@ +1a9fa8cd6869da42314ec47df6a750e053f4bece SOURCES/crash-7.2.3.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32212ef --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/crash-7.2.3.tar.gz diff --git a/SOURCES/github_0f65ae0c_readline_tab_completion.patch b/SOURCES/github_0f65ae0c_readline_tab_completion.patch new file mode 100644 index 0000000..8175dfb --- /dev/null +++ b/SOURCES/github_0f65ae0c_readline_tab_completion.patch @@ -0,0 +1,154 @@ +commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe +Author: Dave Anderson +Date: Fri Dec 7 15:17:37 2018 -0500 + + Implemented a new plugin function for the readline library's tab + completion feature. Without the patch, the use of the default plugin + from the embedded gdb module has been seen to cause segmentation + violations or other fatal malloc/free/corruption assertions. The new + plugin takes gdb out of the picture entirely, and also restricts the + matching options to just symbol names, so as not to clutter the + results with irrelevant filenames. + (anderson@redhat.com) + +diff --git a/cmdline.c b/cmdline.c +index cf3e150..665f48c 100644 +--- a/cmdline.c ++++ b/cmdline.c +@@ -40,6 +40,8 @@ int shell_command(char *); + static void modify_orig_line(char *, struct args_input_file *); + static void modify_expression_arg(char *, char **, struct args_input_file *); + static int verify_args_input_file(char *); ++static char *crash_readline_completion_generator(const char *, int); ++static char **crash_readline_completer(const char *, int, int); + + #define READLINE_LIBRARY + +@@ -2071,6 +2073,9 @@ readline_init(void) + if (STREQ(pc->editing_mode, "emacs")) { + rl_editing_mode = emacs_mode; + } ++ ++ rl_attempted_completion_function = crash_readline_completer; ++ rl_attempted_completion_over = 1; + } + + /* +@@ -2605,3 +2610,27 @@ exec_args_input_file(struct command_table_entry *ct, struct args_input_file *aif + fclose(pc->args_ifile); + pc->args_ifile = NULL; + } ++ ++static char * ++crash_readline_completion_generator(const char *match, int state) ++{ ++ static struct syment *sp_match; ++ ++ if (state == 0) ++ sp_match = NULL; ++ ++ sp_match = symbol_complete_match(match, sp_match); ++ ++ if (sp_match) ++ return(strdup(sp_match->name)); ++ else ++ return NULL; ++} ++ ++static char ** ++crash_readline_completer(const char *match, int start, int end) ++{ ++ rl_attempted_completion_over = 1; ++ return rl_completion_matches(match, crash_readline_completion_generator); ++} ++ +diff --git a/defs.h b/defs.h +index 9ce32c1..a3cb5a4 100644 +--- a/defs.h ++++ b/defs.h +@@ -5138,6 +5138,7 @@ void parse_for_member_extended(struct datatype_member *, ulong); + void add_to_downsized(char *); + int is_downsized(char *); + int is_string(char *, char *); ++struct syment *symbol_complete_match(const char *, struct syment *); + + /* + * memory.c +diff --git a/symbols.c b/symbols.c +index 05628ff..0769294 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -13071,3 +13071,73 @@ is_downsized(char *name) + + return FALSE; + } ++ ++struct syment * ++symbol_complete_match(const char *match, struct syment *sp_last) ++{ ++ int i; ++ struct syment *sp, *sp_end, *sp_start; ++ struct load_module *lm; ++ int search_init; ++ ++ if (sp_last) { ++ sp_start = next_symbol(NULL, sp_last); ++ if (!sp_start) ++ return NULL; ++ } else ++ sp_start = st->symtable; ++ ++ if ((sp_start >= st->symtable) && (sp_start < st->symend)) { ++ for (sp = sp_start; sp < st->symend; sp++) { ++ if (STRNEQ(sp->name, match)) ++ return sp; ++ } ++ sp_start = NULL; ++ } ++ ++ search_init = FALSE; ++ ++ for (i = 0; i < st->mods_installed; i++) { ++ lm = &st->load_modules[i]; ++ if (lm->mod_flags & MOD_INIT) ++ search_init = TRUE; ++ sp_end = lm->mod_symend; ++ if (!sp_start) ++ sp_start = lm->mod_symtable; ++ ++ if ((sp_start >= lm->mod_symtable) && (sp_start < sp_end)) { ++ for (sp = sp_start; sp < sp_end; sp++) { ++ if (MODULE_START(sp)) ++ continue; ++ ++ if (STRNEQ(sp->name, match)) ++ return sp; ++ } ++ sp_start = NULL; ++ } ++ } ++ ++ if (!search_init) ++ return NULL; ++ ++ for (i = 0; i < st->mods_installed; i++) { ++ lm = &st->load_modules[i]; ++ if (!lm->mod_init_symtable) ++ continue; ++ sp_end = lm->mod_init_symend; ++ if (!sp_start) ++ sp_start = lm->mod_init_symtable; ++ ++ if ((sp_start >= lm->mod_init_symtable) && (sp_start < sp_end)) { ++ for (sp = sp_start; sp < sp_end; sp++) { ++ if (MODULE_START(sp)) ++ continue; ++ ++ if (STRNEQ(sp->name, match)) ++ return sp; ++ } ++ } ++ } ++ ++ return NULL; ++} diff --git a/SOURCES/github_1926150e_ppc64_stacksize.patch b/SOURCES/github_1926150e_ppc64_stacksize.patch new file mode 100644 index 0000000..5da09da --- /dev/null +++ b/SOURCES/github_1926150e_ppc64_stacksize.patch @@ -0,0 +1,27 @@ +commit 1926150ee350e17fee2aeabb8ef781222d94366e +Author: Dave Anderson +Date: Mon Jun 11 13:46:41 2018 -0400 + + Fix for the ppc64/ppc64le "bt" command on Linux 4.7 and later kernels + that contain commit d8bff643d81a58181356c0aa3ab771ac10da6894, + titled "[x86] asm: Make sure verify_cpu() has a good stack", which + inadvertently breaks the ppc64/ppc64le kernel stack size calculation + when running with crash-7.2.2 or later. Without the patch, "bt" may + fail with a filtered kdump dumpfile with the two error messages + "bt: page excluded: kernel virtual address:
type: stack + contents" and "bt: read of stack at
failed". + (anderson@redhat.com) + +diff --git a/task.c b/task.c +index f6956d5..1b32629 100644 +--- a/task.c ++++ b/task.c +@@ -440,7 +440,7 @@ task_init(void) + } else if (VALID_SIZE(thread_union) && + ((len = SIZE(thread_union)) != STACKSIZE())) { + machdep->stacksize = len; +- } else { ++ } else if (!VALID_SIZE(thread_union) && !VALID_SIZE(task_union)) { + if (kernel_symbol_exists("__start_init_task") && + kernel_symbol_exists("__end_init_task")) { + len = symbol_value("__end_init_task"); diff --git a/SOURCES/github_28fa7bd0_ppc64_increase_VA_range.patch b/SOURCES/github_28fa7bd0_ppc64_increase_VA_range.patch new file mode 100644 index 0000000..119ddf6 --- /dev/null +++ b/SOURCES/github_28fa7bd0_ppc64_increase_VA_range.patch @@ -0,0 +1,45 @@ +commit 28fa7bd09013455b5ddc020dea4706278cda0d65 +Author: Dave Anderson +Date: Tue Jun 19 16:31:54 2018 -0400 + + Fix for PPC64 kernel virtual address translation in Linux 4.17 and + later kernels with commit c2b4d8b7417a59b7f9a52d0d8402f5257cbbd398, + titled "powerpc/mm/hash64: Increase the VA range", in which the + maximum virtual address value has been increased to 4PB. Without + the patch, the translation/access of high vmalloc space addresses + fails; for example, the "kmem -[sS]" option fails the translation + of per-cpu kmem_cache_cpu addresses located in vmalloc space, with + the error messages "kmem: invalid kernel virtual address:
+ type: kmem_cache_cpu.freelist" and "kmem: invalid kernel virtual + address:
type: kmem_cache_cpu.page", and the "vtop" + command shows the addresses as "(not mapped)". + (hbathini@linux.ibm.com) + +diff --git a/defs.h b/defs.h +index 6e6f6be..e6e3850 100644 +--- a/defs.h ++++ b/defs.h +@@ -3978,6 +3978,7 @@ struct efi_memory_desc_t { + #define PMD_INDEX_SIZE_L4_64K_4_12 10 + #define PUD_INDEX_SIZE_L4_64K_4_12 7 + #define PGD_INDEX_SIZE_L4_64K_4_12 8 ++#define PUD_INDEX_SIZE_L4_64K_4_17 10 + #define PTE_INDEX_SIZE_RADIX_64K 5 + #define PMD_INDEX_SIZE_RADIX_64K 9 + #define PUD_INDEX_SIZE_RADIX_64K 9 +diff --git a/ppc64.c b/ppc64.c +index 0dd8a2a..f5d0dac 100644 +--- a/ppc64.c ++++ b/ppc64.c +@@ -451,7 +451,10 @@ ppc64_init(int when) + + if (THIS_KERNEL_VERSION >= LINUX(4,12,0)) { + m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12; +- m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12; ++ if (THIS_KERNEL_VERSION >= LINUX(4,17,0)) ++ m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_17; ++ else ++ m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12; + m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12; + } else { + m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6; diff --git a/SOURCES/github_46d21219.patch b/SOURCES/github_46d21219.patch new file mode 100644 index 0000000..297cb84 --- /dev/null +++ b/SOURCES/github_46d21219.patch @@ -0,0 +1,34 @@ +commit 46d2121960d81354facf4e2558c81f82257b740e +Author: Dave Anderson +Date: Tue May 29 14:04:03 2018 -0400 + + Fix for the "timer -r" command on Linux 4.10 and later kernels that + contain commit 2456e855354415bfaeb7badaa14e11b3e02c8466, titled + "ktime: Get rid of the union". Without the patch, the command fails + with the error message "timer: invalid structure member offset: + ktime_t_sec". + (k-hagio@ab.jp.nec.com) + +diff --git a/kernel.c b/kernel.c +index b1886ce..138a47f 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -7740,7 +7740,7 @@ ktime_to_ns(const void *ktime) + if (VALID_MEMBER(ktime_t_tv64)) { + readmem((ulong)ktime + OFFSET(ktime_t_tv64), KVADDR, &ns, + sizeof(ns), "ktime_t tv64", QUIET|RETURN_ON_ERROR); +- } else { ++ } else if (VALID_MEMBER(ktime_t_sec) && VALID_MEMBER(ktime_t_nsec)) { + uint32_t sec, nsec; + + sec = 0; +@@ -7753,6 +7753,9 @@ ktime_to_ns(const void *ktime) + sizeof(nsec), "ktime_t nsec", QUIET|RETURN_ON_ERROR); + + ns = sec * 1000000000L + nsec; ++ } else { ++ readmem((ulong)ktime, KVADDR, &ns, ++ sizeof(ns), "ktime_t", QUIET|RETURN_ON_ERROR); + } + + return ns; diff --git a/SOURCES/github_5fe78861_ppc64_invalid_NIP.patch b/SOURCES/github_5fe78861_ppc64_invalid_NIP.patch new file mode 100644 index 0000000..1b6a41e --- /dev/null +++ b/SOURCES/github_5fe78861_ppc64_invalid_NIP.patch @@ -0,0 +1,207 @@ +commit 5fe78861ea1589084f6a2956a6ff63677c9269e1 +Author: Dave Anderson +Date: Fri Sep 7 16:05:52 2018 -0400 + + Commit 3db3d3992d781c1e42587d2d2bf81e785408e0c2 in crash-7.1.8 was + aimed at making the PPC64 "bt" command work for dumpfiles saved + with the FADUMP facility, but it introduced a bit of unwarranted + complexity in "bt" command processing. Reworked the "bt" command + processing for PPC64 arch to make it a little less compilated and + also to print symbols for NIP and LR registers in exception frames. + Without the patch, "bt" on non-panic active tasks may fail with + the message "bt: invalid kernel virtual address:
+ type: Regs NIP value". + (hbathini@linux.ibm.com) + +diff --git a/ppc64.c b/ppc64.c +index f5d0dac..03fecd3 100644 +--- a/ppc64.c ++++ b/ppc64.c +@@ -2093,15 +2093,10 @@ ppc64_print_stack_entry(int frame, + lr); + return; + } +- if (req->pc != lr) { +- fprintf(fp, "\n%s[Link Register] ", +- frame < 10 ? " " : ""); +- fprintf(fp, "[%lx] %s at %lx", +- req->sp, lrname, lr); +- } + req->ra = lr; + } +- if (!req->name || STREQ(req->name,lrname)) ++ if (!req->name || STREQ(req->name, lrname) || ++ !is_kernel_text(req->pc)) + fprintf(fp, " (unreliable)"); + + fprintf(fp, "\n"); +@@ -2219,6 +2214,22 @@ ppc64_print_regs(struct ppc64_pt_regs *regs) + fprintf(fp, " Syscall Result: %016lx\n", regs->result); + } + ++static void ppc64_print_nip_lr(struct ppc64_pt_regs *regs, int print_lr) ++{ ++ char buf[BUFSIZE]; ++ char *sym_buf; ++ ++ sym_buf = value_to_symstr(regs->nip, buf, 0); ++ if (sym_buf[0] != NULLCHAR) ++ fprintf(fp, " [NIP : %s]\n", sym_buf); ++ ++ if (print_lr) { ++ sym_buf = value_to_symstr(regs->link, buf, 0); ++ if (sym_buf[0] != NULLCHAR) ++ fprintf(fp, " [LR : %s]\n", sym_buf); ++ } ++} ++ + /* + * Print the exception frame information + */ +@@ -2231,6 +2242,59 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs, + + fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap); + ppc64_print_regs(regs); ++ ppc64_print_nip_lr(regs, 1); ++} ++ ++/* ++ * For vmcore typically saved with KDump or FADump, get SP and IP values ++ * from the saved ptregs. ++ */ ++static int ++ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) ++{ ++ struct ppc64_pt_regs *pt_regs; ++ unsigned long unip; ++ ++ pt_regs = (struct ppc64_pt_regs *)bt_in->machdep; ++ if (!pt_regs || !pt_regs->gpr[1]) { ++ /* ++ * Not collected regs. May be the corresponding CPU not ++ * responded to an IPI in case of KDump OR f/w has not ++ * not provided the register info in case of FADump. ++ */ ++ fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n", ++ bt_in->task); ++ return FALSE; ++ } ++ *ksp = pt_regs->gpr[1]; ++ if (IS_KVADDR(*ksp)) { ++ readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value", ++ FAULT_ON_ERROR); ++ *nip = unip; ++ } else { ++ if (IN_TASK_VMA(bt_in->task, *ksp)) ++ fprintf(fp, "%0lx: Task is running in user space\n", ++ bt_in->task); ++ else ++ fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", ++ bt_in->task, *ksp); ++ *nip = pt_regs->nip; ++ } ++ ++ if (bt_in->flags && ++ ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT))) ++ return TRUE; ++ ++ /* ++ * Print the collected regs for the active task ++ */ ++ ppc64_print_regs(pt_regs); ++ if (!IS_KVADDR(*ksp)) ++ return FALSE; ++ ++ ppc64_print_nip_lr(pt_regs, (unip != pt_regs->link) ? 1 : 0); ++ ++ return TRUE; + } + + /* +@@ -2239,7 +2303,7 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs, + static int + ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) + { +- int i; ++ int i, ret, panic_task; + char *sym; + ulong *up; + struct bt_info bt_local, *bt; +@@ -2251,11 +2315,29 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) + struct ppc64_pt_regs *pt_regs; + struct syment *sp; + +- bt = &bt_local; +- BCOPY(bt_in, bt, sizeof(struct bt_info)); +- ms = machdep->machspec; ++ bt = &bt_local; ++ BCOPY(bt_in, bt, sizeof(struct bt_info)); ++ ms = machdep->machspec; ++ ur_nip = ur_ksp = 0; ++ ++ panic_task = tt->panic_task == bt->task ? TRUE : FALSE; + + check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE; ++ if (panic_task && bt->machdep) { ++ pt_regs = (struct ppc64_pt_regs *)bt->machdep; ++ ur_nip = pt_regs->nip; ++ ur_ksp = pt_regs->gpr[1]; ++ } else if ((pc->flags & KDUMP) || ++ ((pc->flags & DISKDUMP) && ++ (*diskdump_flags & KDUMP_CMPRS_LOCAL))) { ++ /* ++ * For the KDump or FADump vmcore, use SP and IP values ++ * that are saved in ptregs. ++ */ ++ ret = ppc64_vmcore_stack_frame(bt_in, nip, ksp); ++ if (ret) ++ return TRUE; ++ } + + if (bt->task != tt->panic_task) { + char cpu_frozen = FALSE; +@@ -2385,38 +2467,14 @@ retry: + check_intrstack = FALSE; + goto retry; + } +- + /* +- * We didn't find what we were looking for, so try to use +- * the SP and IP values saved in ptregs. ++ * We didn't find what we were looking for, so just use what was ++ * passed in the ELF header. + */ +- pt_regs = (struct ppc64_pt_regs *)bt_in->machdep; +- if (!pt_regs || !pt_regs->gpr[1]) { +- /* +- * Not collected regs. May be the corresponding CPU did not +- * respond to an IPI. +- */ +- if (CRASHDEBUG(1)) +- fprintf(fp, "%0lx: GPR1(SP) register value not saved\n", +- bt_in->task); +- } else { +- *ksp = pt_regs->gpr[1]; +- if (IS_KVADDR(*ksp)) { +- readmem(*ksp+16, KVADDR, nip, sizeof(ulong), +- "Regs NIP value", FAULT_ON_ERROR); +- ppc64_print_regs(pt_regs); +- return TRUE; +- } else { +- if (IN_TASK_VMA(bt_in->task, *ksp)) +- fprintf(fp, "%0lx: Task is running in user space\n", +- bt_in->task); +- else +- fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", +- bt_in->task, *ksp); +- *nip = pt_regs->nip; +- ppc64_print_regs(pt_regs); +- return FALSE; +- } ++ if (ur_nip && ur_ksp) { ++ *nip = ur_nip; ++ *ksp = ur_ksp; ++ return TRUE; + } + + console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic task\n"); diff --git a/SOURCES/github_6596f112_alternate_list_loop_detect.patch b/SOURCES/github_6596f112_alternate_list_loop_detect.patch new file mode 100644 index 0000000..6980e9d --- /dev/null +++ b/SOURCES/github_6596f112_alternate_list_loop_detect.patch @@ -0,0 +1,397 @@ +commit 6596f1121b89162f96d1e1825c2905b83b59bec1 +Author: Dave Anderson +Date: Wed Jul 11 16:25:59 2018 -0400 + + The existing "list" command uses a hash table to detect duplicate + items as it traverses the list. The hash table approach has worked + well for many years. However, with increasing memory sizes and list + sizes, the overhead of the hash table can be substantial, often + leading to commands running for a very long time. For large lists, + we have found that the existing hash based approach may slow the + system to a crawl and possibly never complete. You can turn off + the hash with "set hash off" but then there is no loop detection; in + that case, loop detection must be done manually after dumping the + list to disk or some other method. This patch is an implementation + of the cycle detection algorithm from R. P. Brent as an alternative + algorithm for the "list" command. The algorithm both avoids the + overhead of the hash table and yet is able to detect a loop. In + addition, further loop characteristics are printed, such as the + distance to the start of the loop as well as the loop length. + An excellent description of the algorithm can be found here on + the crash-utility mailing list: + + https://www.redhat.com/archives/crash-utility/2018-July/msg00019.html + + A new "list -B" option has been added to the "list" command to + invoke this new algorithm rather than using the hash table. In + addition to low memory usage, the output of the list command is + slightly different when a loop is detected. In addition to printing + the first duplicate entry, the length of the loop, and the distance + to the loop is output. + (dwysocha@redhat.com) + +diff --git a/defs.h b/defs.h +index b05aecc..5af82be 100644 +--- a/defs.h ++++ b/defs.h +@@ -2491,6 +2491,7 @@ struct list_data { /* generic structure used by do_list() to walk */ + #define CALLBACK_RETURN (VERBOSE << 12) + #define LIST_PARSE_MEMBER (VERBOSE << 13) + #define LIST_READ_MEMBER (VERBOSE << 14) ++#define LIST_BRENT_ALGO (VERBOSE << 15) + + struct tree_data { + ulong flags; +@@ -4944,6 +4945,7 @@ char *shift_string_right(char *, int); + int bracketed(char *, char *, int); + void backspace(int); + int do_list(struct list_data *); ++int do_list_no_hash(struct list_data *); + struct radix_tree_ops { + void (*entry)(ulong node, ulong slot, const char *path, + ulong index, void *private); +diff --git a/help.c b/help.c +index 638c6ec..54bf9b4 100644 +--- a/help.c ++++ b/help.c +@@ -5724,7 +5724,7 @@ char *help__list[] = { + "list", + "linked list", + "[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]" +-"\n [-r|-h|-H] start", ++"\n [-r|-B] [-h|-H] start", + " ", + " This command dumps the contents of a linked list. The entries in a linked", + " list are typically data structures that are tied together in one of two", +@@ -5822,6 +5822,12 @@ char *help__list[] = { + " -r For a list linked with list_head structures, traverse the list", + " in the reverse order by using the \"prev\" pointer instead", + " of \"next\".", ++" -B Use the algorithm from R. P. Brent to detect loops instead of", ++" using a hash table. This algorithm uses a tiny fixed amount of", ++" memory and so is especially helpful for longer lists. The output", ++" is slightly different than the normal list output as it will", ++" print the length of the loop, the start of the loop, and the", ++" first duplicate in the list.", + " ", + " The meaning of the \"start\" argument, which can be expressed symbolically,", + " in hexadecimal format, or an expression evaluating to an address, depends", +diff --git a/tools.c b/tools.c +index 1a83643..634aec6 100644 +--- a/tools.c ++++ b/tools.c +@@ -3266,9 +3266,12 @@ cmd_list(void) + BZERO(ld, sizeof(struct list_data)); + struct_list_offset = 0; + +- while ((c = getopt(argcnt, args, "Hhrs:S:e:o:xdl:")) != EOF) { ++ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) { + switch(c) + { ++ case 'B': ++ ld->flags |= LIST_BRENT_ALGO; ++ break; + case 'H': + ld->flags |= LIST_HEAD_FORMAT; + ld->flags |= LIST_HEAD_POINTER; +@@ -3516,9 +3519,13 @@ next_arg: + ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED); + ld->flags |= VERBOSE; + +- hq_open(); +- c = do_list(ld); +- hq_close(); ++ if (ld->flags & LIST_BRENT_ALGO) ++ c = do_list_no_hash(ld); ++ else { ++ hq_open(); ++ c = do_list(ld); ++ hq_close(); ++ } + + if (ld->structname_args) + FREEBUF(ld->structname); +@@ -3862,6 +3869,283 @@ do_list(struct list_data *ld) + return count; + } + ++static void ++do_list_debug_entry(struct list_data *ld) ++{ ++ int i, others; ++ ++ if (CRASHDEBUG(1)) { ++ others = 0; ++ console(" flags: %lx (", ld->flags); ++ if (ld->flags & VERBOSE) ++ console("%sVERBOSE", others++ ? "|" : ""); ++ if (ld->flags & LIST_OFFSET_ENTERED) ++ console("%sLIST_OFFSET_ENTERED", others++ ? "|" : ""); ++ if (ld->flags & LIST_START_ENTERED) ++ console("%sLIST_START_ENTERED", others++ ? "|" : ""); ++ if (ld->flags & LIST_HEAD_FORMAT) ++ console("%sLIST_HEAD_FORMAT", others++ ? "|" : ""); ++ if (ld->flags & LIST_HEAD_POINTER) ++ console("%sLIST_HEAD_POINTER", others++ ? "|" : ""); ++ if (ld->flags & RETURN_ON_DUPLICATE) ++ console("%sRETURN_ON_DUPLICATE", others++ ? "|" : ""); ++ if (ld->flags & RETURN_ON_LIST_ERROR) ++ console("%sRETURN_ON_LIST_ERROR", others++ ? "|" : ""); ++ if (ld->flags & RETURN_ON_LIST_ERROR) ++ console("%sRETURN_ON_LIST_ERROR", others++ ? "|" : ""); ++ if (ld->flags & LIST_STRUCT_RADIX_10) ++ console("%sLIST_STRUCT_RADIX_10", others++ ? "|" : ""); ++ if (ld->flags & LIST_STRUCT_RADIX_16) ++ console("%sLIST_STRUCT_RADIX_16", others++ ? "|" : ""); ++ if (ld->flags & LIST_ALLOCATE) ++ console("%sLIST_ALLOCATE", others++ ? "|" : ""); ++ if (ld->flags & LIST_CALLBACK) ++ console("%sLIST_CALLBACK", others++ ? "|" : ""); ++ if (ld->flags & CALLBACK_RETURN) ++ console("%sCALLBACK_RETURN", others++ ? "|" : ""); ++ console(")\n"); ++ console(" start: %lx\n", ld->start); ++ console(" member_offset: %ld\n", ld->member_offset); ++ console(" list_head_offset: %ld\n", ld->list_head_offset); ++ console(" end: %lx\n", ld->end); ++ console(" searchfor: %lx\n", ld->searchfor); ++ console(" structname_args: %lx\n", ld->structname_args); ++ if (!ld->structname_args) ++ console(" structname: (unused)\n"); ++ for (i = 0; i < ld->structname_args; i++) ++ console(" structname[%d]: %s\n", i, ld->structname[i]); ++ console(" header: %s\n", ld->header); ++ console(" list_ptr: %lx\n", (ulong)ld->list_ptr); ++ console(" callback_func: %lx\n", (ulong)ld->callback_func); ++ console(" callback_data: %lx\n", (ulong)ld->callback_data); ++ console("struct_list_offset: %lx\n", ld->struct_list_offset); ++ } ++} ++ ++ ++static void ++do_list_output_struct(struct list_data *ld, ulong next, ulong offset, ++ unsigned int radix, struct req_entry **e) ++{ ++ int i; ++ ++ for (i = 0; i < ld->structname_args; i++) { ++ switch (count_chars(ld->structname[i], '.')) ++ { ++ case 0: ++ dump_struct(ld->structname[i], ++ next - offset, radix); ++ break; ++ default: ++ if (ld->flags & LIST_PARSE_MEMBER) ++ dump_struct_members(ld, i, next); ++ else if (ld->flags & LIST_READ_MEMBER) ++ dump_struct_members_fast(e[i], ++ radix, next - offset); ++ break; ++ } ++ } ++} ++ ++static int ++do_list_no_hash_readmem(struct list_data *ld, ulong *next_ptr, ++ ulong readflag) ++{ ++ if (!readmem(*next_ptr + ld->member_offset, KVADDR, next_ptr, ++ sizeof(void *), "list entry", readflag)) { ++ error(INFO, "\ninvalid list entry: %lx\n", *next_ptr); ++ return -1; ++ } ++ return 0; ++} ++ ++static ulong brent_x; /* tortoise */ ++static ulong brent_y; /* hare */ ++static ulong brent_r; /* power */ ++static ulong brent_lambda; /* loop length */ ++static ulong brent_mu; /* distance to start of loop */ ++static ulong brent_loop_detect; ++static ulong brent_loop_exit; ++/* ++ * 'ptr': representative of x or y; modified on return ++ */ ++static int ++brent_f(ulong *ptr, struct list_data *ld, ulong readflag) ++{ ++ return do_list_no_hash_readmem(ld, ptr, readflag); ++} ++ ++/* ++ * Similar to do_list() but without the hash_table or LIST_ALLOCATE. ++ * Useful for the 'list' command and other callers needing faster list ++ * enumeration. ++ */ ++int ++do_list_no_hash(struct list_data *ld) ++{ ++ ulong next, last, first, offset; ++ ulong searchfor, readflag; ++ int i, count, ret; ++ unsigned int radix; ++ struct req_entry **e = NULL; ++ ++ do_list_debug_entry(ld); ++ ++ count = 0; ++ searchfor = ld->searchfor; ++ ld->searchfor = 0; ++ if (ld->flags & LIST_STRUCT_RADIX_10) ++ radix = 10; ++ else if (ld->flags & LIST_STRUCT_RADIX_16) ++ radix = 16; ++ else ++ radix = 0; ++ next = ld->start; ++ ++ readflag = ld->flags & RETURN_ON_LIST_ERROR ? ++ (RETURN_ON_ERROR|QUIET) : FAULT_ON_ERROR; ++ ++ if (!readmem(next + ld->member_offset, KVADDR, &first, sizeof(void *), ++ "first list entry", readflag)) { ++ error(INFO, "\ninvalid list entry: %lx\n", next); ++ return -1; ++ } ++ ++ if (ld->header) ++ fprintf(fp, "%s", ld->header); ++ ++ offset = ld->list_head_offset + ld->struct_list_offset; ++ ++ if (ld->structname && (ld->flags & LIST_READ_MEMBER)) { ++ e = (struct req_entry **)GETBUF(sizeof(*e) * ld->structname_args); ++ for (i = 0; i < ld->structname_args; i++) ++ e[i] = fill_member_offsets(ld->structname[i]); ++ } ++ ++ brent_loop_detect = brent_loop_exit = 0; ++ brent_lambda = 0; ++ brent_r = 2; ++ brent_x = brent_y = next; ++ ret = brent_f(&brent_y, ld, readflag); ++ if (ret == -1) ++ return -1; ++ while (1) { ++ if (!brent_loop_detect && ld->flags & VERBOSE) { ++ fprintf(fp, "%lx\n", next - ld->list_head_offset); ++ if (ld->structname) { ++ do_list_output_struct(ld, next, offset, radix, e); ++ } ++ } ++ ++ if (next && brent_loop_exit) { ++ if (ld->flags & ++ (RETURN_ON_DUPLICATE|RETURN_ON_LIST_ERROR)) { ++ error(INFO, "\nduplicate list entry: %lx\n", ++ brent_x); ++ return -1; ++ } ++ error(FATAL, "\nduplicate list entry: %lx\n", brent_x); ++ } ++ ++ if ((searchfor == next) || ++ (searchfor == (next - ld->list_head_offset))) ++ ld->searchfor = searchfor; ++ ++ count++; ++ last = next; ++ ++ if ((ld->flags & LIST_CALLBACK) && ++ ld->callback_func((void *)(next - ld->list_head_offset), ++ ld->callback_data) && (ld->flags & CALLBACK_RETURN)) ++ break; ++ ++ ret = do_list_no_hash_readmem(ld, &next, readflag); ++ if (ret == -1) ++ return -1; ++ ++ if (!brent_loop_detect) { ++ if (brent_x == brent_y) { ++ brent_loop_detect = 1; ++ error(INFO, "loop detected, loop length: %lx\n", brent_lambda); ++ /* reset x and y to start; advance y loop length */ ++ brent_mu = 0; ++ brent_x = brent_y = ld->start; ++ while (brent_lambda--) { ++ ret = brent_f(&brent_y, ld, readflag); ++ if (ret == -1) ++ return -1; ++ } ++ } else { ++ if (brent_r == brent_lambda) { ++ brent_x = brent_y; ++ brent_r *= 2; ++ brent_lambda = 0; ++ } ++ brent_y = next; ++ brent_lambda++; ++ } ++ } else { ++ if (!brent_loop_exit && brent_x == brent_y) { ++ brent_loop_exit = 1; ++ error(INFO, "length from start to loop: %lx", ++ brent_mu); ++ } else { ++ ret = brent_f(&brent_x, ld, readflag); ++ if (ret == -1) ++ return -1; ++ ret = brent_f(&brent_y, ld, readflag); ++ if (ret == -1) ++ return -1; ++ brent_mu++; ++ } ++ } ++ ++ if (next == 0) { ++ if (ld->flags & LIST_HEAD_FORMAT) { ++ error(INFO, "\ninvalid list entry: 0\n"); ++ return -1; ++ } ++ if (CRASHDEBUG(1)) ++ console("do_list end: next:%lx\n", next); ++ ++ break; ++ } ++ ++ if (next == ld->end) { ++ if (CRASHDEBUG(1)) ++ console("do_list end: next:%lx == end:%lx\n", ++ next, ld->end); ++ break; ++ } ++ ++ if (next == ld->start) { ++ if (CRASHDEBUG(1)) ++ console("do_list end: next:%lx == start:%lx\n", ++ next, ld->start); ++ break; ++ } ++ ++ if (next == last) { ++ if (CRASHDEBUG(1)) ++ console("do_list end: next:%lx == last:%lx\n", ++ next, last); ++ break; ++ } ++ ++ if ((next == first) && (count != 1)) { ++ if (CRASHDEBUG(1)) ++ console("do_list end: next:%lx == first:%lx (count %d)\n", ++ next, last, count); ++ break; ++ } ++ } ++ ++ if (CRASHDEBUG(1)) ++ console("do_list count: %d\n", count); ++ ++ return count; ++} ++ + /* + * Issue a dump_struct_member() call for one or more structure + * members. Multiple members are passed in a comma-separated diff --git a/SOURCES/github_6b93714b_cmdline.patch b/SOURCES/github_6b93714b_cmdline.patch new file mode 100644 index 0000000..8cb3a20 --- /dev/null +++ b/SOURCES/github_6b93714b_cmdline.patch @@ -0,0 +1,39 @@ +commit 6b93714b83d59ae4147b8ec3887261aca7fd6f65 +Author: Dave Anderson +Date: Mon Jan 7 10:44:29 2019 -0500 + + Prevent a SIGSEGV if a user attempts to input a command line that + exceeds the maximum length of 1500 bytes. The patch displays an + error message and ignores the command line. + (anderson@redhat.com) + +diff --git a/cmdline.c b/cmdline.c +index 665f48c..796f7c5 100644 +--- a/cmdline.c ++++ b/cmdline.c +@@ -1,8 +1,8 @@ + /* cmdline.c - core analysis suite + * + * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. +- * Copyright (C) 2002-2015,2017 David Anderson +- * Copyright (C) 2002-2015,2017 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2002-2015,2019 David Anderson ++ * Copyright (C) 2002-2015,2019 Red Hat, Inc. All rights reserved. + * + * 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 +@@ -121,9 +121,11 @@ process_command_line(void) + args[0] = NULL; + fprintf(fp, "\n"); + return; +- } +- +- strcpy(pc->command_line, pc->readline); ++ } ++ if (strlen(pc->readline) >= BUFSIZE) ++ error(FATAL, "input line exceeds maximum of 1500 bytes\n"); ++ else ++ strcpy(pc->command_line, pc->readline); + free(pc->readline); + + clean_line(pc->command_line); diff --git a/SOURCES/github_7e393689_ppc64_bt_user_space.patch b/SOURCES/github_7e393689_ppc64_bt_user_space.patch new file mode 100644 index 0000000..dfe886b --- /dev/null +++ b/SOURCES/github_7e393689_ppc64_bt_user_space.patch @@ -0,0 +1,49 @@ +commit 7e3936895386ea6e85a6dc01bc5027f8133d12bb +Author: Dave Anderson +Date: Mon Sep 17 14:33:08 2018 -0400 + + An addendum to crash commit 5fe78861ea1589084f6a2956a6ff63677c9269e1, + this patch for the PPC64 "bt" command prevents an invalid error + message from being displayed when an active non-panic task is + interrupted while running in user space. Without the patch, the + command correctly indicates "Task is running in user space", dumps + the user-space exception frame, but then prints the invalid error + message "bt: invalid kernel virtual address: ffffffffffffff90 type: + Regs NIP value". + (anderson@redhat.com) + +diff --git a/ppc64.c b/ppc64.c +index 03fecd3..8badcde 100644 +--- a/ppc64.c ++++ b/ppc64.c +@@ -2254,6 +2254,7 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) + { + struct ppc64_pt_regs *pt_regs; + unsigned long unip; ++ int in_user_space = FALSE; + + pt_regs = (struct ppc64_pt_regs *)bt_in->machdep; + if (!pt_regs || !pt_regs->gpr[1]) { +@@ -2272,10 +2273,11 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) + FAULT_ON_ERROR); + *nip = unip; + } else { +- if (IN_TASK_VMA(bt_in->task, *ksp)) ++ if (IN_TASK_VMA(bt_in->task, *ksp)) { + fprintf(fp, "%0lx: Task is running in user space\n", + bt_in->task); +- else ++ in_user_space = TRUE; ++ } else + fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n", + bt_in->task, *ksp); + *nip = pt_regs->nip; +@@ -2289,6 +2291,8 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp) + * Print the collected regs for the active task + */ + ppc64_print_regs(pt_regs); ++ if (in_user_space) ++ return TRUE; + if (!IS_KVADDR(*ksp)) + return FALSE; + diff --git a/SOURCES/github_9446958f_95daa11b_bpf_covscan.patch b/SOURCES/github_9446958f_95daa11b_bpf_covscan.patch new file mode 100644 index 0000000..fb07782 --- /dev/null +++ b/SOURCES/github_9446958f_95daa11b_bpf_covscan.patch @@ -0,0 +1,45 @@ +commit 9446958fe211825ed5524317b05d5ea020bb00d6 +Author: Dave Anderson +Date: Fri Jun 1 14:01:01 2018 -0400 + + Fix to address a "__builtin___snprintf_chk" compiler warning if bpf.c + is compiled with -D_FORTIFY_SOURCE=2. + (anderson@redhat.com) + +diff --git a/bpf.c b/bpf.c +index 305d49f..ee1986f 100644 +--- a/bpf.c ++++ b/bpf.c +@@ -362,7 +362,7 @@ do_bpf(ulong flags, ulong prog_id, ulong map_id, int radix) + fprintf(fp, " LOAD_TIME: "); + if (VALID_MEMBER(bpf_prog_aux_load_time)) { + load_time = ULONGLONG(bpf->bpf_prog_aux_buf + OFFSET(bpf_prog_aux_load_time)); +- print_boot_time(load_time, buf5, BUFSIZE); ++ print_boot_time(load_time, buf5, BUFSIZE/2); + fprintf(fp, "%s\n", buf5); + } else + fprintf(fp, "(unknown)\n"); + +commit 95daa11b82dfa6aa3e68ffc92e1282abc1b2b62a +Author: Dave Anderson +Date: Fri Jun 1 15:28:55 2018 -0400 + + Fix for the "bpf -t" option. Although highly unlikely, without the + patch, the target function name of a BPF bytecode call instruction + may fail to be resolved correctly. + (anderson@redhat.com) + +diff --git a/bpf.c b/bpf.c +index ee1986f..427263d 100644 +--- a/bpf.c ++++ b/bpf.c +@@ -1060,8 +1060,7 @@ static char *__func_get_name(const struct bpf_insn *insn, + return buff; + + if (insn->src_reg != BPF_PSEUDO_CALL && +- insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID && +- func_id_str[insn->imm]) { ++ insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID) { + // return func_id_str[insn->imm]; + if (!readmem(symbol_value("func_id_str") + (insn->imm * sizeof(void *)), + KVADDR, &func_id_ptr, sizeof(void *), "func_id_str pointer", diff --git a/SOURCES/github_a6cd8408_mach-m.patch b/SOURCES/github_a6cd8408_mach-m.patch new file mode 100644 index 0000000..a1aaa77 --- /dev/null +++ b/SOURCES/github_a6cd8408_mach-m.patch @@ -0,0 +1,223 @@ +commit a6cd8408d1d214a67ed0c4b09343fec77a8e2ae7 +Author: Dave Anderson +Date: Thu May 31 11:43:14 2018 -0400 + + Fix for the x86 and x86_64 "mach -m" option on Linux 4.12 and later + kernels to account for the structure name changes "e820map" to + "e820_table", and "e820entry" to "e820_entry", and for the symbol + name change from "e820" to "e820_table". Also updated the display + output to properly translate E820_PRAM and E820_RESERVED_KERN entries. + Without the patch on all kernels, E820_PRAM and E820_RESERVED_KERN + entries show "type 12" and "type 128" respectively. Without the + patch on Linux 4.12 and later kernels, the command fails with the + error message "mach: cannot resolve e820". + (anderson@redhat.com) + +diff --git a/x86.c b/x86.c +index 47767b6..88562b6 100644 +--- a/x86.c ++++ b/x86.c +@@ -1,8 +1,8 @@ + /* x86.c - core analysis suite + * + * Portions Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. +- * Copyright (C) 2002-2014,2017 David Anderson +- * Copyright (C) 2002-2014,2017 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2002-2014,2017-2018 David Anderson ++ * Copyright (C) 2002-2014,2017-2018 Red Hat, Inc. All rights reserved. + * + * 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 +@@ -1967,15 +1967,27 @@ x86_init(int when) + } + MEMBER_OFFSET_INIT(thread_struct_cr3, "thread_struct", "cr3"); + STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86"); +- STRUCT_SIZE_INIT(e820map, "e820map"); +- STRUCT_SIZE_INIT(e820entry, "e820entry"); + STRUCT_SIZE_INIT(irq_ctx, "irq_ctx"); ++ if (STRUCT_EXISTS("e820map")) { ++ STRUCT_SIZE_INIT(e820map, "e820map"); ++ MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map"); ++ } else { ++ STRUCT_SIZE_INIT(e820map, "e820_table"); ++ MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries"); ++ } ++ if (STRUCT_EXISTS("e820entry")) { ++ STRUCT_SIZE_INIT(e820entry, "e820entry"); ++ MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr"); ++ MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size"); ++ MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type"); ++ } else { ++ STRUCT_SIZE_INIT(e820entry, "e820_entry"); ++ MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr"); ++ MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size"); ++ MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type"); ++ } + if (!VALID_STRUCT(irq_ctx)) + STRUCT_SIZE_INIT(irq_ctx, "irq_stack"); +- MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map"); +- MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr"); +- MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size"); +- MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type"); + if (KVMDUMP_DUMPFILE()) + set_kvm_iohole(NULL); + if (symbol_exists("irq_desc")) +@@ -4415,33 +4427,54 @@ static char *e820type[] = { + static void + x86_display_memmap(void) + { +- ulong e820; +- int nr_map, i; +- char *buf, *e820entry_ptr; +- ulonglong addr, size; +- ulong type; ++ ulong e820; ++ int nr_map, i; ++ char *buf, *e820entry_ptr; ++ ulonglong addr, size; ++ uint type; ++ ++ if (kernel_symbol_exists("e820")) { ++ if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR) ++ get_symbol_data("e820", sizeof(void *), &e820); ++ else ++ e820 = symbol_value("e820"); ++ ++ } else if (kernel_symbol_exists("e820_table")) ++ get_symbol_data("e820_table", sizeof(void *), &e820); ++ else ++ error(FATAL, "neither e820 or e820_table symbols exist\n"); + +- e820 = symbol_value("e820"); +- buf = (char *)GETBUF(SIZE(e820map)); ++ if (CRASHDEBUG(1)) { ++ if (STRUCT_EXISTS("e820map")) ++ dump_struct("e820map", e820, RADIX(16)); ++ else if (STRUCT_EXISTS("e820_table")) ++ dump_struct("e820_table", e820, RADIX(16)); ++ } ++ buf = (char *)GETBUF(SIZE(e820map)); + +- readmem(e820, KVADDR, &buf[0], SIZE(e820map), +- "e820map", FAULT_ON_ERROR); ++ readmem(e820, KVADDR, &buf[0], SIZE(e820map), ++ "e820map", FAULT_ON_ERROR); + +- nr_map = INT(buf + OFFSET(e820map_nr_map)); ++ nr_map = INT(buf + OFFSET(e820map_nr_map)); + +- fprintf(fp, " PHYSICAL ADDRESS RANGE TYPE\n"); ++ fprintf(fp, " PHYSICAL ADDRESS RANGE TYPE\n"); + +- for (i = 0; i < nr_map; i++) { +- e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i); +- addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr)); +- size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size)); +- type = ULONG(e820entry_ptr + OFFSET(e820entry_type)); ++ for (i = 0; i < nr_map; i++) { ++ e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i); ++ addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr)); ++ size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size)); ++ type = UINT(e820entry_ptr + OFFSET(e820entry_type)); + fprintf(fp, "%016llx - %016llx ", addr, addr+size); +- if (type >= (sizeof(e820type)/sizeof(char *))) +- fprintf(fp, "type %ld\n", type); +- else ++ if (type >= (sizeof(e820type)/sizeof(char *))) { ++ if (type == 12) ++ fprintf(fp, "E820_PRAM\n"); ++ else if (type == 128) ++ fprintf(fp, "E820_RESERVED_KERN\n"); ++ else ++ fprintf(fp, "type %d\n", type); ++ } else + fprintf(fp, "%s\n", e820type[type]); +- } ++ } + } + + /* +diff --git a/x86_64.c b/x86_64.c +index 921552b..1d5e155 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -415,12 +415,26 @@ x86_64_init(int when) + STRUCT_SIZE_INIT(gate_struct, "gate_desc"); + else + STRUCT_SIZE_INIT(gate_struct, "gate_struct"); +- STRUCT_SIZE_INIT(e820map, "e820map"); +- STRUCT_SIZE_INIT(e820entry, "e820entry"); +- MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map"); +- MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr"); +- MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size"); +- MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type"); ++ ++ if (STRUCT_EXISTS("e820map")) { ++ STRUCT_SIZE_INIT(e820map, "e820map"); ++ MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map"); ++ } else { ++ STRUCT_SIZE_INIT(e820map, "e820_table"); ++ MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries"); ++ } ++ if (STRUCT_EXISTS("e820entry")) { ++ STRUCT_SIZE_INIT(e820entry, "e820entry"); ++ MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr"); ++ MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size"); ++ MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type"); ++ } else { ++ STRUCT_SIZE_INIT(e820entry, "e820_entry"); ++ MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr"); ++ MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size"); ++ MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type"); ++ } ++ + if (KVMDUMP_DUMPFILE()) + set_kvm_iohole(NULL); + MEMBER_OFFSET_INIT(thread_struct_rip, "thread_struct", "rip"); +@@ -5643,12 +5657,23 @@ x86_64_display_memmap(void) + ulonglong addr, size; + uint type; + +- if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR) +- get_symbol_data("e820", sizeof(void *), &e820); ++ if (kernel_symbol_exists("e820")) { ++ if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR) ++ get_symbol_data("e820", sizeof(void *), &e820); ++ else ++ e820 = symbol_value("e820"); ++ ++ } else if (kernel_symbol_exists("e820_table")) ++ get_symbol_data("e820_table", sizeof(void *), &e820); + else +- e820 = symbol_value("e820"); +- if (CRASHDEBUG(1)) +- dump_struct("e820map", e820, RADIX(16)); ++ error(FATAL, "neither e820 or e820_table symbols exist\n"); ++ ++ if (CRASHDEBUG(1)) { ++ if (STRUCT_EXISTS("e820map")) ++ dump_struct("e820map", e820, RADIX(16)); ++ else if (STRUCT_EXISTS("e820_table")) ++ dump_struct("e820_table", e820, RADIX(16)); ++ } + buf = (char *)GETBUF(SIZE(e820map)); + + readmem(e820, KVADDR, &buf[0], SIZE(e820map), +@@ -5664,9 +5689,14 @@ x86_64_display_memmap(void) + size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size)); + type = UINT(e820entry_ptr + OFFSET(e820entry_type)); + fprintf(fp, "%016llx - %016llx ", addr, addr+size); +- if (type >= (sizeof(e820type)/sizeof(char *))) +- fprintf(fp, "type %d\n", type); +- else ++ if (type >= (sizeof(e820type)/sizeof(char *))) { ++ if (type == 12) ++ fprintf(fp, "E820_PRAM\n"); ++ else if (type == 128) ++ fprintf(fp, "E820_RESERVED_KERN\n"); ++ else ++ fprintf(fp, "type %d\n", type); ++ } else + fprintf(fp, "%s\n", e820type[type]); + } + } diff --git a/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch b/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch new file mode 100644 index 0000000..0d84189 --- /dev/null +++ b/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch @@ -0,0 +1,149 @@ +commit b9d76838372d1b4087bb506ce6da425afad68876 +Author: Dave Anderson +Date: Thu Jun 7 13:20:16 2018 -0400 + + If /proc/kcore gets selected for the live memory source because + /dev/mem was configured with CONFIG_STRICT_DEVMEM, its ELF header + contents are not displayed by "help -[dD]", and are not displayed + when the crash session is invoked with -d". Without the + patch, the ELF contents are only displayed in those two situations + if "/proc/kcore" is explicitly entered on the crash command line. + (anderson@redhat.com) + +diff --git a/netdump.c b/netdump.c +index 25683eb..1f3e26c 100644 +--- a/netdump.c ++++ b/netdump.c +@@ -4334,11 +4334,8 @@ kcore_memory_dump(FILE *ofp) + Elf32_Phdr *lp32; + Elf64_Phdr *lp64; + +- if (!(pkd->flags & KCORE_LOCAL)) +- return FALSE; +- + fprintf(ofp, "proc_kcore_data:\n"); +- fprintf(ofp, " flags: %lx (", nd->flags); ++ fprintf(ofp, " flags: %x (", pkd->flags); + others = 0; + if (pkd->flags & KCORE_LOCAL) + fprintf(ofp, "%sKCORE_LOCAL", others++ ? "|" : ""); +commit c79a11fa10da94b71ddf341ec996c522fbd75237 +Author: Dave Anderson +Date: Fri Jun 8 14:31:08 2018 -0400 + + If the default live memory source /dev/mem is determined to be + unusable because the kernel was configured with CONFIG_STRICT_DEVMEM, + the first memory read during session initialization will fail. The + current behavior results in a readmem() error message, followed by two + notification messages that indicate that /dev/mem is restricted and + a switch to using /proc/kcore will be attempted; the readmem is + reattempted from /proc/kcore, and if successful, the session will + continue initialization. With this patch, the behavior will change + such that if the switch to /proc/kcore and the reattempted readmem() + are successful, no messages will be displayed unless the crash + session is invoked with "crash -d<number>". + (anderson@redhat.com) + +diff --git a/kernel.c b/kernel.c +index 138a47f..3cd5bf1 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -882,7 +882,7 @@ cpu_maps_init(void) + { + int i, c, m, cpu, len; + char *buf; +- ulong *maskptr, addr; ++ ulong *maskptr, addr, error_handle; + struct mapinfo { + ulong cpu_flag; + char *name; +@@ -902,8 +902,9 @@ cpu_maps_init(void) + if (!(addr = cpu_map_addr(mapinfo[m].name))) + continue; + ++ error_handle = pc->flags & DEVMEM ? RETURN_ON_ERROR|QUIET : RETURN_ON_ERROR; + if (!readmem(addr, KVADDR, buf, len, +- mapinfo[m].name, RETURN_ON_ERROR)) { ++ mapinfo[m].name, error_handle)) { + error(WARNING, "cannot read cpu_%s_map\n", + mapinfo[m].name); + continue; +diff --git a/memory.c b/memory.c +index 82f9cbf..2f568d5 100644 +--- a/memory.c ++++ b/memory.c +@@ -2243,9 +2243,11 @@ readmem(ulonglong addr, int memtype, void *buffer, long size, + error(INFO, READ_ERRMSG, memtype_string(memtype, 0), addr, type); + if ((pc->flags & DEVMEM) && (kt->flags & PRE_KERNEL_INIT) && + !(error_handle & NO_DEVMEM_SWITCH) && devmem_is_restricted() && +- switch_to_proc_kcore()) ++ switch_to_proc_kcore()) { ++ error_handle &= ~QUIET; + return(readmem(addr, memtype, bufptr, size, + type, error_handle)); ++ } + goto readmem_error; + + case PAGE_EXCLUDED: +@@ -2457,7 +2459,7 @@ devmem_is_restricted(void) + QUIET|RETURN_ON_ERROR|NO_DEVMEM_SWITCH)) + restricted = TRUE; + +- if (restricted) ++ if (restricted && CRASHDEBUG(1)) + error(INFO, + "this kernel may be configured with CONFIG_STRICT_DEVMEM," + " which\n renders /dev/mem unusable as a live memory " +@@ -2472,9 +2474,10 @@ switch_to_proc_kcore(void) + { + close(pc->mfd); + +- if (file_exists("/proc/kcore", NULL)) +- error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n"); +- else ++ if (file_exists("/proc/kcore", NULL)) { ++ if (CRASHDEBUG(1)) ++ error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n"); ++ } else + return FALSE; + + if ((pc->mfd = open("/proc/kcore", O_RDONLY)) < 0) { +diff --git a/ppc64.c b/ppc64.c +index 0b04187..0dd8a2a 100644 +--- a/ppc64.c ++++ b/ppc64.c +@@ -1,7 +1,7 @@ + /* ppc64.c -- core analysis suite + * +- * Copyright (C) 2004-2015,2017 David Anderson +- * Copyright (C) 2004-2015,2017 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2004-2015,2018 David Anderson ++ * Copyright (C) 2004-2015,2018 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004, 2006 Haren Myneni, IBM Corporation + * + * This program is free software; you can redistribute it and/or modify +@@ -343,8 +343,9 @@ ppc64_init(int when) + + if (symbol_exists("vmemmap_populate")) { + if (symbol_exists("vmemmap")) { +- get_symbol_data("vmemmap", sizeof(void *), +- &machdep->machspec->vmemmap_base); ++ readmem(symbol_value("vmemmap"), KVADDR, ++ &machdep->machspec->vmemmap_base, ++ sizeof(void *), "vmemmap", QUIET|FAULT_ON_ERROR); + } else + machdep->machspec->vmemmap_base = + VMEMMAP_REGION_ID << REGION_SHIFT; +diff --git a/x86_64.c b/x86_64.c +index 54b6539..e01082b 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -356,7 +356,7 @@ x86_64_init(int when) + machdep->flags |= RANDOMIZED; + readmem(symbol_value("page_offset_base"), KVADDR, + &machdep->machspec->page_offset, sizeof(ulong), +- "page_offset_base", FAULT_ON_ERROR); ++ "page_offset_base", QUIET|FAULT_ON_ERROR); + machdep->kvbase = machdep->machspec->page_offset; + machdep->identity_map_base = machdep->machspec->page_offset; + } diff --git a/SOURCES/github_da49e201_cpu_entry_area.patch b/SOURCES/github_da49e201_cpu_entry_area.patch new file mode 100644 index 0000000..8829afb --- /dev/null +++ b/SOURCES/github_da49e201_cpu_entry_area.patch @@ -0,0 +1,133 @@ +commit da49e2010b3cb88b4755d69d38fe90af6ba218b2 +Author: Dave Anderson +Date: Fri Jun 1 10:58:00 2018 -0400 + + Update for the recognition of the new x86_64 CPU_ENTRY_AREA virtual + address range introduced in Linux 4.15. The memory range exists + above the vmemmap range and below the mapped kernel static text/data + region, and where all of the x86_64 exception stacks have been moved. + Without the patch, reads from the new memory region fail because the + address range is not recognized as a legitimate virtual address. + Most notable is the failure of "bt" on tasks whose backtraces + originate from any of the exception stacks, which fail with the two + error messages "bt: seek error: kernel virtual address:
+ type: stack contents" followed by "bt: read of stack at
+ failed". + (anderson@redhat.com) + +diff --git a/defs.h b/defs.h +index 931be07..6e6f6be 100644 +--- a/defs.h ++++ b/defs.h +@@ -3391,6 +3391,9 @@ struct arm64_stackframe { + #define VSYSCALL_START 0xffffffffff600000 + #define VSYSCALL_END 0xffffffffff601000 + ++#define CPU_ENTRY_AREA_START 0xfffffe0000000000 ++#define CPU_ENTRY_AREA_END 0xfffffe7fffffffff ++ + #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)) +@@ -5829,6 +5832,8 @@ struct machine_specific { + ulong kpti_entry_stack; + ulong kpti_entry_stack_size; + ulong ptrs_per_pgd; ++ ulong cpu_entry_area_start; ++ ulong cpu_entry_area_end; + }; + + #define KSYMS_START (0x1) +diff --git a/x86_64.c b/x86_64.c +index 1d5e155..54b6539 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -407,6 +407,11 @@ x86_64_init(int when) + machdep->machspec->modules_end = MODULES_END_2_6_31; + } + } ++ if (STRUCT_EXISTS("cpu_entry_area")) { ++ machdep->machspec->cpu_entry_area_start = CPU_ENTRY_AREA_START; ++ machdep->machspec->cpu_entry_area_end = CPU_ENTRY_AREA_END; ++ } ++ + STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86"); + /* + * Before 2.6.25 the structure was called gate_struct +@@ -879,20 +884,21 @@ x86_64_dump_machdep_table(ulong arg) + + /* pml4 and upml is legacy for extension modules */ + if (ms->pml4) { +- fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4); +- fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read); ++ fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4); ++ fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read); + + } else { +- fprintf(fp, " pml4: (unused)\n"); +- fprintf(fp, " last_pml4_read: (unused)\n"); ++ fprintf(fp, " pml4: (unused)\n"); ++ fprintf(fp, " last_pml4_read: (unused)\n"); + } + + if (ms->upml) { +- fprintf(fp, " upml: %lx\n", (ulong)ms->upml); +- fprintf(fp, " last_upml_read: %lx\n", (ulong)ms->last_upml_read); ++ fprintf(fp, " upml: %lx\n", (ulong)ms->upml); ++ fprintf(fp, " last_upml_read: %lx\n", (ulong)ms->last_upml_read); + } else { +- fprintf(fp, " upml: (unused)\n"); +- fprintf(fp, " last_upml_read: (unused)\n"); ++ fprintf(fp, " GART_end: %lx\n", ms->GART_end); ++ fprintf(fp, " upml: (unused)\n"); ++ fprintf(fp, " last_upml_read: (unused)\n"); + } + + if (ms->p4d) { +@@ -1016,10 +1022,14 @@ x86_64_dump_machdep_table(ulong arg) + fprintf(fp, "\n "); + fprintf(fp, "%016lx ", ms->stkinfo.ibase[c]); + } +- fprintf(fp, "\n kpti_entry_stack_size: %ld", ms->kpti_entry_stack_size); +- fprintf(fp, "\n kpti_entry_stack: "); ++ fprintf(fp, "\n kpti_entry_stack_size: "); ++ if (ms->kpti_entry_stack_size) ++ fprintf(fp, "%ld", ms->kpti_entry_stack_size); ++ else ++ fprintf(fp, "(unused)"); ++ fprintf(fp, "\n kpti_entry_stack: "); + if (machdep->flags & KPTI) { +- fprintf(fp, "%lx\n ", ms->kpti_entry_stack); ++ fprintf(fp, "(percpu: %lx):\n ", ms->kpti_entry_stack); + for (c = 0; c < cpus; c++) { + if (c && !(c%4)) + fprintf(fp, "\n "); +@@ -1028,6 +1038,16 @@ x86_64_dump_machdep_table(ulong arg) + fprintf(fp, "\n"); + } else + fprintf(fp, "(unused)\n"); ++ fprintf(fp, " cpu_entry_area_start: "); ++ if (ms->cpu_entry_area_start) ++ fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_start); ++ else ++ fprintf(fp, "(unused)\n"); ++ fprintf(fp, " cpu_entry_area_end: "); ++ if (ms->cpu_entry_area_end) ++ fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end); ++ else ++ fprintf(fp, "(unused)\n"); + } + + /* +@@ -1586,7 +1606,10 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr) + ((machdep->flags & VMEMMAP) && + (vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END)) || + (vaddr >= MODULES_VADDR && vaddr <= MODULES_END) || +- (vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END)); ++ (vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) || ++ (machdep->machspec->cpu_entry_area_start && ++ vaddr >= machdep->machspec->cpu_entry_area_start && ++ vaddr <= machdep->machspec->cpu_entry_area_end)); + } + + static int diff --git a/SOURCES/github_f294197b_bpf_idr.patch b/SOURCES/github_f294197b_bpf_idr.patch new file mode 100644 index 0000000..b0d601a --- /dev/null +++ b/SOURCES/github_f294197b_bpf_idr.patch @@ -0,0 +1,250 @@ +commit f294197b5511537e6b14d5e1db324f4fc4fdd3f8 +Author: Dave Anderson +Date: Fri Jul 6 10:57:50 2018 -0400 + + Support for the "bpf" command on RHEL 3.10.0-913.el7 and later + 3.10-based RHEL7 kernels, which contain a backport of the upstream + eBPF code, but still use the older, pre-4.11, IDR facility that does + not use radix trees for linking the active bpf_prog and bpf_map + structures. Without the patch, the command indicates "bpf: command + not supported or applicable on this architecture or kernel". + (anderson@redhat.com) + +diff --git a/bpf.c b/bpf.c +index 427263d..8871b76 100644 +--- a/bpf.c ++++ b/bpf.c +@@ -45,6 +45,10 @@ static void bpf_prog_gpl_compatible(char *, ulong); + static void dump_xlated_plain(void *, unsigned int, int); + static void print_boot_time(unsigned long long, char *, unsigned int); + ++static int do_old_idr(int, ulong, struct radix_tree_pair *); ++#define OLD_IDR_INIT (1) ++#define OLD_IDR_COUNT (2) ++#define OLD_IDR_GATHER (3) + + #define PROG_ID (0x1) + #define MAP_ID (0x2) +@@ -167,7 +171,6 @@ bpf_init(struct bpf_info *bpf) + !VALID_STRUCT(bpf_map) || + !VALID_STRUCT(bpf_insn) || + INVALID_MEMBER(bpf_prog_aux) || +- INVALID_MEMBER(idr_idr_rt) || + INVALID_MEMBER(bpf_prog_type) || + INVALID_MEMBER(bpf_prog_tag) || + INVALID_MEMBER(bpf_prog_jited_len) || +@@ -210,6 +213,9 @@ bpf_init(struct bpf_info *bpf) + mkstring(buf2, VADDR_PRLEN, CENTER|LJUST, "BPF_MAP"), + mkstring(buf3, bpf->bpf_map_map_type_size, CENTER|LJUST, "BPF_MAP_TYPE")); + ++ if (INVALID_MEMBER(idr_idr_rt)) ++ do_old_idr(OLD_IDR_INIT, 0, NULL); ++ + bpf->status = TRUE; + break; + +@@ -220,24 +226,38 @@ bpf_init(struct bpf_info *bpf) + command_not_supported(); + } + +- bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), +- RADIX_TREE_COUNT, NULL); ++ if (VALID_MEMBER(idr_idr_rt)) ++ bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), ++ RADIX_TREE_COUNT, NULL); ++ else ++ bpf->progs = do_old_idr(OLD_IDR_COUNT, symbol_value("prog_idr"), NULL); ++ + if (bpf->progs) { + len = sizeof(struct radix_tree_pair) * (bpf->progs+1); + bpf->proglist = (struct radix_tree_pair *)GETBUF(len); + bpf->proglist[0].index = bpf->progs; +- bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), +- RADIX_TREE_GATHER, bpf->proglist); ++ if (VALID_MEMBER(idr_idr_rt)) ++ bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), ++ RADIX_TREE_GATHER, bpf->proglist); ++ else ++ bpf->progs = do_old_idr(OLD_IDR_GATHER, symbol_value("prog_idr"), bpf->proglist); + } + +- bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), +- RADIX_TREE_COUNT, NULL); ++ if (VALID_MEMBER(idr_idr_rt)) ++ bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), ++ RADIX_TREE_COUNT, NULL); ++ else ++ bpf->maps = do_old_idr(OLD_IDR_COUNT, symbol_value("map_idr"), NULL); ++ + if (bpf->maps) { + len = sizeof(struct radix_tree_pair) * (bpf->maps+1); + bpf->maplist = (struct radix_tree_pair *)GETBUF(len); + bpf->maplist[0].index = bpf->maps; +- bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), +- RADIX_TREE_GATHER, bpf->maplist); ++ if (VALID_MEMBER(idr_idr_rt)) ++ bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), ++ RADIX_TREE_GATHER, bpf->maplist); ++ else ++ bpf->maps = do_old_idr(OLD_IDR_GATHER, symbol_value("map_idr"), bpf->maplist); + } + + bpf->bpf_prog_buf = GETBUF(SIZE(bpf_prog)); +@@ -538,8 +558,10 @@ do_map_only: + } + + bailout: +- FREEBUF(bpf->proglist); +- FREEBUF(bpf->maplist); ++ if (bpf->proglist) ++ FREEBUF(bpf->proglist); ++ if (bpf->maplist) ++ FREEBUF(bpf->maplist); + FREEBUF(bpf->bpf_prog_buf); + FREEBUF(bpf->bpf_prog_aux_buf); + FREEBUF(bpf->bpf_map_buf); +@@ -1255,3 +1277,50 @@ print_boot_time(unsigned long long nsecs, char *buf, unsigned int size) + sprintf(buf, "(unknown)"); + #endif + } ++ ++/* ++ * Borrow the old (pre-radix_tree) IDR facility code used by ++ * the ipcs command. ++ */ ++static int ++do_old_idr(int cmd, ulong idr, struct radix_tree_pair *rtp) ++{ ++ int i, max, cur, next_id, total = 0; ++ ulong entry; ++ ++ switch (cmd) ++ { ++ case OLD_IDR_INIT: ++ ipcs_init(); ++ break; ++ ++ case OLD_IDR_COUNT: ++ readmem(idr + OFFSET(idr_cur), KVADDR, &cur, ++ sizeof(int), "idr.cur", FAULT_ON_ERROR); ++ for (total = next_id = 0; next_id < cur; next_id++) { ++ entry = idr_find(idr, next_id); ++ if (entry == 0) ++ continue; ++ total++; ++ } ++ break; ++ ++ case OLD_IDR_GATHER: ++ max = rtp[0].index; ++ readmem(idr + OFFSET(idr_cur), KVADDR, &cur, ++ sizeof(int), "idr.cur", FAULT_ON_ERROR); ++ for (i = total = next_id = 0; next_id < cur; next_id++) { ++ entry = idr_find(idr, next_id); ++ if (entry == 0) ++ continue; ++ total++; ++ rtp[i].index = next_id; ++ rtp[i].value = (void *)entry; ++ if (++i == max) ++ break; ++ } ++ break; ++ } ++ ++ return total; ++} +diff --git a/defs.h b/defs.h +index e6e3850..b05aecc 100644 +--- a/defs.h ++++ b/defs.h +@@ -2031,6 +2031,7 @@ struct offset_table { /* stash of commonly-used offsets */ + long bpf_prog_aux_load_time; + long bpf_prog_aux_user; + long user_struct_uid; ++ long idr_cur; + }; + + struct size_table { /* stash of commonly-used sizes */ +@@ -5590,6 +5591,12 @@ enum { + void dev_init(void); + void dump_dev_table(void); + ++/* ++ * ipcs.c ++ */ ++void ipcs_init(void); ++ulong idr_find(ulong, int); ++ + #ifdef ARM + void arm_init(int); + void arm_dump_machdep_table(ulong); +diff --git a/ipcs.c b/ipcs.c +index ef51fdd..80f78e4 100644 +--- a/ipcs.c ++++ b/ipcs.c +@@ -79,13 +79,11 @@ struct ipcs_table { + * function declaration + */ + +-static void ipcs_init(void); + static int dump_shared_memory(int, ulong, int, ulong); + static int dump_semaphore_arrays(int, ulong, int, ulong); + static int dump_message_queues(int, ulong, int, ulong); + static int ipc_search_idr(ulong, int, ulong, int (*)(ulong, int, ulong, int, int), int); + static int ipc_search_array(ulong, int, ulong, int (*)(ulong, int, ulong, int, int), int); +-static ulong idr_find(ulong, int); + static int dump_shm_info(ulong, int, ulong, int, int); + static int dump_sem_info(ulong, int, ulong, int, int); + static int dump_msg_info(ulong, int, ulong, int, int); +@@ -101,7 +99,7 @@ static void gather_radix_tree_entries(ulong); + */ + static struct ipcs_table ipcs_table = { 0 }; + +-static void ++void + ipcs_init(void) + { + if (ipcs_table.init_flags & IPCS_INIT) { +@@ -119,6 +117,7 @@ ipcs_init(void) + MEMBER_OFFSET_INIT(idr_layer_layer, "idr_layer", "layer"); + MEMBER_OFFSET_INIT(idr_layer_ary, "idr_layer", "ary"); + MEMBER_OFFSET_INIT(idr_top, "idr", "top"); ++ MEMBER_OFFSET_INIT(idr_cur, "idr", "cur"); + MEMBER_OFFSET_INIT(ipc_id_ary_p, "ipc_id_ary", "p"); + MEMBER_OFFSET_INIT(ipc_ids_entries, "ipc_ids", "entries"); + MEMBER_OFFSET_INIT(ipc_ids_max_id, "ipc_ids", "max_id"); +@@ -188,7 +187,10 @@ ipcs_init(void) + ipcs_table.shm_f_op_huge_addr = -1; + } + +- if (BITS32()) ++ if (VALID_MEMBER(idr_layer_ary) && ++ get_array_length("idr_layer.ary", NULL, 0) > 64) ++ ipcs_table.idr_bits = 8; ++ else if (BITS32()) + ipcs_table.idr_bits = 5; + else if (BITS64()) + ipcs_table.idr_bits = 6; +@@ -635,7 +637,7 @@ ipc_search_idr(ulong ipc_ids_p, int specified, ulong specified_value, int (*fn)( + /* + * search every idr_layer + */ +-static ulong ++ulong + idr_find(ulong idp, int id) + { + ulong idr_layer_p; +diff --git a/symbols.c b/symbols.c +index bf55319..8ff1430 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -10041,6 +10041,8 @@ dump_offset_table(char *spec, ulong makestruct) + OFFSET(idr_layers)); + fprintf(fp, " idr_top: %ld\n", + OFFSET(idr_top)); ++ fprintf(fp, " idr_cur: %ld\n", ++ OFFSET(idr_cur)); + fprintf(fp, " ipc_id_ary_p: %ld\n", + OFFSET(ipc_id_ary_p)); + fprintf(fp, " ipc_ids_entries: %ld\n", diff --git a/SOURCES/lzo_snappy.patch b/SOURCES/lzo_snappy.patch new file mode 100644 index 0000000..61af0cc --- /dev/null +++ b/SOURCES/lzo_snappy.patch @@ -0,0 +1,22 @@ +--- crash-7.1.5/diskdump.c.orig ++++ crash-7.1.5/diskdump.c +@@ -23,6 +23,8 @@ + * GNU General Public License for more details. + */ + ++#define LZO ++#define SNAPPY + #include "defs.h" + #include "diskdump.h" + #include "xen_dom0.h" +--- crash-7.1.5/Makefile.orig ++++ crash-7.1.5/Makefile +@@ -228,7 +228,7 @@ all: make_configure + gdb_merge: force + @if [ ! -f ${GDB}/README ]; then \ + make --no-print-directory gdb_unzip; fi +- @echo "${LDFLAGS} -lz -ldl -rdynamic" > ${GDB}/gdb/mergelibs ++ @echo "${LDFLAGS} -lz -llzo2 -lsnappy -ldl -rdynamic" > ${GDB}/gdb/mergelibs + @echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj + @rm -f ${PROGRAM} + @if [ ! -f ${GDB}/config.status ]; then \ diff --git a/SOURCES/rhel7.6-s390-nat.patch b/SOURCES/rhel7.6-s390-nat.patch new file mode 100644 index 0000000..e79dac2 --- /dev/null +++ b/SOURCES/rhel7.6-s390-nat.patch @@ -0,0 +1,21 @@ +--- crash-7.2.3/gdb-7.6.patch.orig ++++ crash-7.2.3/gdb-7.6.patch +@@ -2392,3 +2392,18 @@ diff -up gdb-7.6/opcodes/configure.orig + req->flags |= GNU_COMMAND_FAILED; + } + ++--- gdb-7.6/gdb/s390-nat.c.orig +++++ gdb-7.6/gdb/s390-nat.c ++@@ -31,6 +31,12 @@ ++ #include "elf/common.h" ++ ++ #include +++#undef PTRACE_PEEKUSR_AREA +++#undef PTRACE_POKEUSR_AREA +++#undef PTRACE_GET_LAST_BREAK +++#undef PTRACE_ENABLE_TE +++#undef PTRACE_DISABLE_TE +++#undef PTRACE_TE_ABORT_RAND ++ #include ++ #include ++ #include diff --git a/SPECS/crash.spec b/SPECS/crash.spec new file mode 100644 index 0000000..062b9a0 --- /dev/null +++ b/SPECS/crash.spec @@ -0,0 +1,602 @@ +# +# crash core analysis suite +# +Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles +Name: crash +Version: 7.2.3 +Release: 10%{?dist} +License: GPLv3 +Group: Development/Debuggers +Source: http://people.redhat.com/anderson/crash-%{version}.tar.gz +URL: http://people.redhat.com/anderson +ExclusiveOS: Linux +ExclusiveArch: %{ix86} ia64 x86_64 ppc ppc64 s390 s390x %{arm} aarch64 ppc64le +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n) +BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel +Requires: binutils +Patch0: lzo_snappy.patch +Patch1: rhel7.6-s390-nat.patch +Patch2: github_46d21219.patch +Patch3: github_a6cd8408_mach-m.patch +Patch4: github_da49e201_cpu_entry_area.patch +Patch5: github_9446958f_95daa11b_bpf_covscan.patch +Patch6: github_b9d76838_c79a11fa_proc_kcore.patch +Patch7: github_1926150e_ppc64_stacksize.patch +Patch8: github_f294197b_bpf_idr.patch +Patch9: github_28fa7bd0_ppc64_increase_VA_range.patch +Patch10: github_5fe78861_ppc64_invalid_NIP.patch +Patch11: github_7e393689_ppc64_bt_user_space.patch +Patch12: github_6596f112_alternate_list_loop_detect.patch +Patch13: github_0f65ae0c_readline_tab_completion.patch +Patch14: github_6b93714b_cmdline.patch + +%description +The core analysis suite is a self-contained tool that can be used to +investigate either live systems, kernel core dumps created from the +netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch +offered by Mission Critical Linux, or the LKCD kernel patch. + +%package devel +Requires: %{name} = %{version}, zlib-devel lzo-devel snappy-devel +Summary: kernel crash analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles +Group: Development/Debuggers + +%description devel +The core analysis suite is a self-contained tool that can be used to +investigate either live systems, kernel core dumps created from the +netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch +offered by Mission Critical Linux, or the LKCD kernel patch. + +%prep +%setup -n %{name}-%{version} -q +%patch0 -p1 -b lzo_snappy.patch +%patch1 -p1 -b rhel7.6-s390-nat.patch +%patch2 -p1 -b github_46d21219.patch +%patch3 -p1 -b github_a6cd8408_mach-m.patch +%patch4 -p1 -b github_da49e201_cpu_entry_area.patch +%patch5 -p1 -b github_9446958f_95daa11b_bpf_covscan.patch +%patch6 -p1 -b github_b9d76838_c79a11fa_proc_kcore.patch +%patch7 -p1 -b github_1926150e_ppc64_stacksize.patch +%patch8 -p1 -b github_f294197b_bpf_idr.patch +%patch9 -p1 -b github_28fa7bd0_ppc64_increase_VA_range.patch +%patch10 -p1 -b github_5fe78861_ppc64_invalid_NIP.patch +%patch11 -p1 -b github_7e393689_ppc64_bt_user_space.patch +%patch12 -p1 -b github_6596f112_alternate_list_loop_detect.patch +%patch13 -p1 -b github_0f65ae0c_readline_tab_completion.patch +%patch14 -p1 -b github_6b93714b_cmdline.patch + +%build +make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_bindir} +make DESTDIR=%{buildroot} install +mkdir -p %{buildroot}%{_mandir}/man8 +cp -p crash.8 %{buildroot}%{_mandir}/man8/crash.8 +mkdir -p %{buildroot}%{_includedir}/crash +chmod 0644 defs.h +cp -p defs.h %{buildroot}%{_includedir}/crash + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root,-) +%{_bindir}/crash +%{_mandir}/man8/crash.8* +%doc README COPYING3 + +%files devel +%defattr(-,root,root,-) +%{_includedir}/* + +%changelog +* Tue Jan 8 2019 Dave Anderson - 7.2.3-10 +- Restrict command line to 1500 bytes + Resolves: rhbz#1663792 + +* Wed Jan 2 2019 Dave Anderson - 7.2.3-9 +- Alternate list loop detection option + Resolves: rhbz#1595389 +- Readline library tab completion plugin + Resolves: rhbz#1656165 + +* Mon Sep 17 2018 Dave Anderson - 7.2.3-8 +- Fix ppc64 "bt" command failure reporting invalid NIP value for a user-space task. + Resolves: rhbz#1617936 + +* Thu Sep 13 2018 Dave Anderson - 7.2.3-7 +- Support ppc64 increased VA range +- Fix ppc64 "bt" command failure reporting invalid NIP value + Resolves: rhbz#1617936 + +* Fri Jul 6 2018 Dave Anderson - 7.2.3-6 +- Fix for RHEL7 kernel's eBPF support that uses old IDR facility + Resolves: rhbz#1559758 + +* Mon Jun 11 2018 Dave Anderson - 7.2.3-5 +- Rebase to github commits b9d76838 to c79a11fa + Resolves: rhbz#1559460 +- Fix ppc64/ppc6le stacksize calculation + Resolves: rhbz#1589685 + +* Fri Jun 1 2018 Dave Anderson - 7.2.3-4 +- Fix bpf.c covscan issues + Resolves: rhbz#1559758 + +* Fri Jun 1 2018 Dave Anderson - 7.2.3-3 +- Rebase to github commits a6cd8408 to da49e201 + Resolves: rhbz#1559460 + +* Tue May 29 2018 Dave Anderson - 7.2.3-2 +- Work around rhel-7.6 s390/s390x ptrace.h incompatiblity FTBFS issue +- Rebase to github commit 46d21219 + Resolves: rhbz#1559460 + +* Fri May 18 2018 Dave Anderson - 7.2.3-1 +- Rebase to upstream version 7.2.3 + Resolves: rhbz#1559460 +- eBPF support with new bpf command + Resolves: rhbz#1559758 + +* Mon Feb 12 2018 Dave Anderson - 7.2.0-6 +- Fix arm64 backtrace issues seen in Linux 4.14 + Resolves: rhbz#1542312 + +* Fri Jan 26 2018 Dave Anderson - 7.2.0-5 +- Additional support for analyzing an SADUMP dumpfile if KASLR + and KPTI are both enabled + Resolves: rhbz#1504467 + +* Mon Jan 22 2018 Dave Anderson - 7.2.0-4 +- Add support for KPTI entry trampoline stack + Resolves: rhbz#1534308 + +* Thu Jan 11 2018 Dave Anderson - 7.2.0-3 +- Rebase to github commits 494a796e to 63419fb9 + Resolves: rhbz#1497316 +- Fix IRQ stack transition failure due to kernel's removal of 64-byte gap + Resolves: rhbz#1530887 + +* Tue Nov 21 2017 Dave Anderson - 7.2.0-2 +- Rebase to github commits f852f5ce to 03a3e57b + Resolves: rhbz#1497316 + +* Wed Nov 1 2017 Dave Anderson - 7.2.0-1 +- Rebase to upstream version 7.2.0 +- Rebase to github commits da9bd35a to e2efacdd + Resolves: rhbz#1497316 +- ppc64le: fix for "WARNING: cannot access vmalloc'd module memory" + Resolves: rhbz#1485391 +- Support for analyzing an SADUMP crash dump if KASLR is enabled + Resolves: rhbz#1504467 + +* Wed May 3 2017 Dave Anderson - 7.1.9-2 +- Rebase to github commits 87179026 to ad3b8476 + Resolves: rhbz#1393534 +- Prohibit native gdb disassemble command when KASLR + Resolves: rhbz#1445649 + +* Mon Apr 24 2017 Dave Anderson - 7.1.9-1 +- Rebase to upstream version 7.1.9 + Resolves: rhbz#1393534 +- Fix gdb "set scope" option for KASLR kernels. + Resolves: rhbz#1440725 +- Fix for the determination of the x86_64 "phys_base" value when it is + not passed in the VMCOREINFO data of ELF vmcores + Resolves: rhbz#1439170 + +* Wed Mar 8 2017 Dave Anderson - 7.1.8-2 +- mod [-sS] command may erroneously reassign module symbol addresses + Resolves: rhbz#1430091 + +* Fri Feb 24 2017 Dave Anderson - 7.1.8-1 +- Rebase to upstream version 7.1.8 + Resolves: rhbz#1393534 +- POWER9 - Power ISA 3.0 related support for crash utility + Resolves: rhbz#1368711 +- crash package update - ppc64/ppc64le + Resolves: rhbz#1384944 +- exception RIP: unknown or invalid address + Resolves: rhbz#1350457 +- Crash does not always parse correctly the modules symbol tables + Resolves: rhbz#1360415 +- ARM64: crash live system from: WARNING: cannot read linux_banner string + Resolves: rhbz#1392007 +- kmem: invalid structure member offset: page_count + Resolves: rhbz#1392011 +- Kernel address space randomization [KASLR] support + Resolves: rhbz#1392658 +- invalid structure size: tnt + Resolves: rhbz#1420653 + +* Wed Sep 14 2016 Dave Anderson - 7.1.5-2 +- Fix for kernel module symbol gathering when the ordering of module + symbol name strings does not match the order of the kernel_symbol + structures. +- Resolves: rhbz#1375130 + +* Thu Apr 28 2016 Dave Anderson - 7.1.5-1 +- Rebase to upstream version 7.1.5 + Resolves: rhbz#1292566 +- Decode clflushopt instruction + Resolves: rhbz#1262479 +- Support AArch64 QEMU generated dumps + Resolves: rhbz#1299873 +- crash: zero-size memory allocation (aarch64) + Resolves: rhbz#1312738 + +* Tue Apr 5 2016 Dave Anderson - 7.1.2-4 +- crash: fails to read excluded pages by default on sadump-related format + Resolves: rhbz#1304260 + +* Mon Nov 23 2015 Dave Anderson - 7.1.2-3 +- crash fails to read or wrongly reads some parts of memory in sadump vmcore format + Resolves: rhbz#1282997 + +* Tue Aug 4 2015 Dave Anderson - 7.1.2-2 +- Fix "kmem -s
", "bt -F[F]", and "rd -S[S]" options in kernels + configured with CONFIG_SLUB having multiple-page slabs. + Resolves: rhbz#1244003 +- Fix for SIGSEGV generated by "bt -[f|F]" in ARM64 kernels. + Resolves: rhbz#1248859 + +* Mon Jul 13 2015 Dave Anderson - 7.1.2-1 +- Rebase to upstream version 7.1.2 + Resolves: rhbz#1207696 +- Fix several ppc64 backtrace issues + Resolves: rhbz#1235447 + +* Fri Jun 05 2015 Dave Anderson - 7.1.1-2 +- ARM64 backtrace enhancements + Resolves: rhbz#1227508 + +* Thu May 28 2015 Dave Anderson - 7.1.1-1 +- Rebase to upstream version 7.1.1 + Resolves: rhbz#1207696 +- Display s390x vector registers from a kernel dump. + Resolves: rhbz#1182161 +- Fix date displayed on initial system banner and by the "sys" command on ARM64. + Resolves: rhbz#1223044 +- Fix ARM64 page size calculation on 4.1 and later kernels. + Resolves: rhbz#1222645 + +* Tue Apr 21 2015 Dave Anderson - 7.0.9-6 +- Calculate ARM64 virtual memory layout based upon struct page size + Resolves: rhbz#1204941 + +* Tue Apr 7 2015 Dave Anderson - 7.0.9-5 +- Support new sadump format that can represent more than 16 TB physical memory space + Resolves: rhbz#1182383 + +* Mon Jan 26 2015 Dave Anderson - 7.0.9-4 + Fix ppc64 "bt" command for active tasks in compressed kdumps. + Resolves: rhbz#1184401 + +* Mon Jan 12 2015 Dave Anderson - 7.0.9-3 + Fix "bt" command mislabeling errors. + Resolves: rhbz#1179476 + +* Mon Dec 08 2014 Dave Anderson - 7.0.9-2 +- Use registers from QEMU-generated ELF and compressed kdump headers + for active task backtraces. +- Resolves: rhbz#1169555 + +* Fri Nov 14 2014 Dave Anderson - 7.0.9-1 +- Rebase to upstream version 7.0.9. +- Resolves: rhbz#1110513 + +* Tue Sep 23 2014 Dave Anderson - 7.0.8-2 +- Fix ps performance patch regression on live systems. +- Resolves: rhbz#1134177 +- Minor build-related fixes for ppc64le. +- Resolves: rhbz#1123991 + +* Fri Sep 12 2014 Dave Anderson - 7.0.8-1 +- Rebase to upstream version 7.0.8. +- Resolves: rhbz#1110513 +- Fix to calculate the physical base address of dumpfiles created + by a "virsh dump" of an OVMF guest. +- Resolves: rhbz#1080698 +- Support for aarch64 architecture. +- Resolves: rhbz#1110551 +- Fix to prevent crash from spinning endlessly on a corrupted/truncated + dumpfile whose bitmap data is not wholly contained within the file. +- Resolves: rhbz#1114088 +- Support for ppc64le architecture. +- Resolves: rhbz#1123991 + +* Tue Jan 28 2014 Daniel Mach - 7.0.2-6 +- Mass rebuild 2014-01-24 + +* Fri Jan 24 2014 Dave Anderson - 7.0.2-5 +- Fix for a missing kernel-mode exception frame dump by the x86_64 + "bt" command if a page fault was generated by a bogus RIP. +- Resolves: rhbz#1057353 +- Fix for the x86_64 "bt" command to prevent an unwarranted message + indicating "WARNING: possibly bogus exception frame" generated + from a blocked kernel thread that was in the process of exec'ing + a user process via the call_usermodehelper() facility. +- Resolves: rhbz#1057357 + +* Fri Jan 10 2014 Dave Anderson - 7.0.2-4 +- Fixes for "kmem -S" command for CONFIG_SLUB. +- Resolves: rhbz#1045591 +- Increase S390X NR_CPUS +- Resolves: rhbz#1051156 + +* Fri Dec 27 2013 Daniel Mach - 7.0.2-3 +- Mass rebuild 2013-12-27 + +* Tue Oct 29 2013 Dave Anderson - 7.0.2-2 +- Compressed kdump 46-bit physical memory support + Resolves: rhbz#1015250 +- Fix incorrect backtrace for dumps taken with "virsh dump --memory-only" + Resolves: rhbz#1020469 +- Fix cpu number display on systems with more than 254 cpus + Resolves: rhbz#1020536 + +* Wed Sep 04 2013 Dave Anderson - 7.0.2-1 +- Update to latest upstream release +- Fix for ppc64 embedded gdb NULL pointer translation sigsegv +- Fix for bt -F failure + +* Fri Jul 26 2013 Dave Anderson - 7.0.1-4 +- Add lzo-devel and snappy-devel to crash-devel Requires line + +* Tue Jul 23 2013 Dave Anderson - 7.0.1-3 +- Build with snappy compression support + +* Tue Jul 9 2013 Dave Anderson - 7.0.1-2 +- Fix for ppc64 Linux 3.10 vmalloc/user-space virtual address translation + +* Tue Jun 18 2013 Dave Anderson - 7.0.1-1 +- Update to latest upstream release +- Build with LZO support + +* Tue Apr 9 2013 Dave Anderson - 6.1.6-1 +- Update to latest upstream release + +* Tue Feb 19 2013 Dave Anderson - 6.1.4-1 +- Update to latest upstream release + +* Wed Feb 13 2013 Fedora Release Engineering - 6.1.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Jan 9 2013 Dave Anderson - 6.1.2-1 +- Update to latest upstream release + +* Tue Nov 27 2012 Dave Anderson - 6.1.1-1 +- Update to latest upstream release + +* Mon Sep 1 2012 Dave Anderson - 6.1.0-1 +- Add ppc to ExclusiveArch list +- Update to latest upstream release + +* Tue Aug 21 2012 Dave Anderson - 6.0.9-1 +- Update to latest upstream release + +* Wed Jul 18 2012 Fedora Release Engineering - 6.0.8-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jul 1 2012 Dave Anderson - 6.0.8-1 +- Update to latest upstream release. +- Replace usage of "struct siginfo" with "siginfo_t". + +* Mon Apr 30 2012 Dave Anderson - 6.0.6-1 +- Update to latest upstream release + +* Mon Mar 26 2012 Dave Anderson - 6.0.5-1 +- Update to latest upstream release + +* Wed Jan 4 2012 Dave Anderson - 6.0.2-1 +- Update to latest upstream release + +* Wed Oct 26 2011 Dave Anderson - 6.0.0-1 +- Update to latest upstream release + +* Tue Sep 20 2011 Dave Anderson - 5.1.8-1 +- Update to latest upstream release +- Additional fixes for gcc-4.6 -Werror compile failures for ARM architecture. + +* Thu Sep 1 2011 Dave Anderson - 5.1.7-2 +- Fixes for gcc-4.6 -Werror compile failures for ARM architecture. + +* Wed Aug 17 2011 Dave Anderson - 5.1.7-1 +- Update to latest upstream release +- Fixes for gcc-4.6 -Werror compile failures for ppc64/ppc. + +* Tue May 31 2011 Peter Robinson - 5.1.5-1 +- Update to latest upstream release +- Add ARM to the Exclusive arch + +* Wed Feb 25 2011 Dave Anderson - 5.1.2-2 +- Fixes for gcc-4.6 -Werror compile failures in gdb module. + +* Wed Feb 23 2011 Dave Anderson - 5.1.2-1 +- Upstream version. + +* Tue Feb 08 2011 Fedora Release Engineering - 5.0.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Jul 20 2010 Dave Anderson - 5.0.6-2 +- Bump version. + +* Tue Jul 20 2010 Dave Anderson - 5.0.6-1 +- Update to upstream version. + +* Fri Sep 11 2009 Dave Anderson - 4.0.9-2 + Bump version. + +* Fri Sep 11 2009 Dave Anderson - 4.0.9-1 +- Update to upstream release, which allows the removal of the + Revision tag workaround, the crash-4.0-8.11-dwarf3.patch and + the crash-4.0-8.11-optflags.patch + +* Sun Aug 05 2009 Lubomir Rintel - 4.0.8.11-2 +- Fix reading of dwarf 3 DW_AT_data_member_location +- Use proper compiler flags + +* Wed Aug 05 2009 Lubomir Rintel - 4.0.8.11-1 +- Update to later upstream release +- Fix abuse of Revision tag + +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild +* Fri Jul 24 2009 Fedora Release Engineering - 4.0-9.7.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Feb 24 2009 Fedora Release Engineering - 4.0-8.7.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 19 2009 Dave Anderson - 4.0-7.7.2 +- Replace exclusive arch i386 with ix86. + +* Thu Feb 19 2009 Dave Anderson - 4.0-7.7.1 +- Updates to this file per crash merge review +- Update to upstream version 4.0-7.7. Full changelog viewable in: + http://people.redhat.com/anderson/crash.changelog.html + +* Tue Jul 15 2008 Tom "spot" Callaway 4.0-7 +- fix license tag + +* Tue Apr 29 2008 Dave Anderson - 4.0-6.3 +- Added crash-devel subpackage +- Updated crash.patch to match upstream version 4.0-6.3 + +* Wed Feb 20 2008 Dave Anderson - 4.0-6.0.5 +- Second attempt at addressing the GCC 4.3 build, which failed due + to additional ptrace.h includes in the lkcd vmdump header files. + +* Wed Feb 20 2008 Dave Anderson - 4.0-6.0.4 +- First attempt at addressing the GCC 4.3 build, which failed on x86_64 + because ptrace-abi.h (included by ptrace.h) uses the "u32" typedef, + which relies on , and include/asm-x86_64/types.h + does not not typedef u32 as done in include/asm-x86/types.h. + +* Mon Feb 18 2008 Fedora Release Engineering - 4.0-6.0.3 +- Autorebuild for GCC 4.3 + +* Wed Jan 23 2008 Dave Anderson - 4.0-5.0.3 +- Updated crash.patch to match upstream version 4.0-5.0. + +* Wed Aug 29 2007 Dave Anderson - 4.0-4.6.2 +- Updated crash.patch to match upstream version 4.0-4.6. + +* 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. +- Added s390 and s390x to ExclusiveArch list. BZ #199125 +- Removed LKCD v1 pt_regs references for s390/s390x build. +- Removed LKCD v2_v3 pt_regs references for for s390/s390x build. + +* Fri Jul 14 2006 Jesse Keating - 4.0-3 +- rebuild + +* Mon May 15 2006 Dave Anderson - 4.0-2.26.4 +- Updated crash.patch such that is not #include'd + by s390_dump.c; IBM did not make the file s390[s] only; BZ #192719 + +* Mon May 15 2006 Dave Anderson - 4.0-2.26.3 +- Updated crash.patch such that is not #include'd + by vas_crash.h; only ia64 build complained; BZ #191719 + +* Mon May 15 2006 Dave Anderson - 4.0-2.26.2 +- Updated crash.patch such that is not #include'd + by lkcd_x86_trace.c; also for BZ #191719 + +* Mon May 15 2006 Dave Anderson - 4.0-2.26.1 +- Updated crash.patch to bring it up to 4.0-2.26, which should + address BZ #191719 - "crash fails to build in mock" + +* Tue Feb 07 2006 Jesse Keating - 4.0-2.18.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Jan 04 2006 Dave Anderson 4.0-2.18 +- Updated source package to crash-4.0.tar.gz, and crash.patch + to bring it up to 4.0-2.18. + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Mar 03 2005 Dave Anderson 3.10-13 +- Compiler error- and warning-related fixes for gcc 4 build. +- Update to enhance x86 and x86_64 gdb disassembly output so as to + symbolically display call targets from kernel module text without + requiring module debuginfo data. +- Fix hole where an ia64 vmcore could be mistakenly accepted as a + usable dumpfile on an x86_64 machine, leading eventually to a + non-related error message. +* Wed Mar 02 2005 Dave Anderson 3.10-12 +- rebuild (gcc 4) +* Thu Feb 10 2005 Dave Anderson 3.10-9 +- Updated source package to crash-3.10.tar.gz, containing + IBM's final ppc64 processor support for RHEL4 +- Fixes potential "bt -a" hang on dumpfile where netdump IPI interrupted + an x86 process while executing the instructions just after it had entered + the kernel for a syscall, but before calling the handler. BZ #139437 +- Update to handle backtraces in dumpfiles generated on IA64 with the + INIT switch (functionality intro'd in RHEL3-U5 kernel). BZ #139429 +- Fix for handling ia64 and x86_64 machines booted with maxcpus=1 on + an SMP kernel. BZ #139435 +- Update to handle backtraces in dumpfiles generated on x86_64 from the + NMI exception stack (functionality intro'd in RHEL3-U5 kernel). +- "kmem -[sS]" beefed up to more accurately verify slab cache chains + and report errors found. +- Fix for ia64 INIT switch-generated backtrace handling when + init_handler_platform() is inlined into ia64_init_handler(); + properly handles both RHEL3 and RHEL4 kernel patches. + BZ #138350 +- Update to enhance ia64 gdb disassembly output so as to + symbolically display call targets from kernel module + text without requiring module debuginfo data. + +* Wed Jul 14 2004 Dave Anderson 3.8-5 +- bump release for fc3 + +* Tue Jul 13 2004 Dave Anderson 3.8-4 +- Fix for gcc 3.4.x/gdb issue where vmlinux was mistakenly presumed non-debug + +* Fri Jun 25 2004 Dave Anderson 3.8-3 +- remove (harmless) error message during ia64 diskdump invocation when + an SMP system gets booted with maxcpus=1 +- several 2.6 kernel specific updates + +* Thu Jun 17 2004 Dave Anderson 3.8-2 +- updated source package to crash-3.8.tar.gz +- diskdump support +- x86_64 processor support + +* Mon Sep 22 2003 Dave Anderson 3.7-5 +- make bt recovery code start fix-up only upon reaching first faulting frame + +* Fri Sep 19 2003 Dave Anderson 3.7-4 +- fix "bt -e" and bt recovery code to recognize new __KERNEL_CS and DS + +* Wed Sep 10 2003 Dave Anderson 3.7-3 +- patch to recognize per-cpu GDT changes that redefine __KERNEL_CS and DS + +* Wed Sep 10 2003 Dave Anderson 3.7-2 +- patches for netdump active_set determination and slab info gathering + +* Wed Aug 20 2003 Dave Anderson 3.7-1 +- updated source package to crash-3.7.tar.gz + +* Wed Jul 23 2003 Dave Anderson 3.6-1 +- removed Packager, Distribution, and Vendor tags +- updated source package to crash-3.6.tar.gz + +* Fri Jul 18 2003 Jay Fenlason 3.5-2 +- remove ppc from arch list, since it doesn't work with ppc64 kernels +- remove alpha from the arch list since we don't build it any more + +* Fri Jul 18 2003 Matt Wilson 3.5-1 +- use %%defattr(-,root,root) + +* Tue Jul 15 2003 Jay Fenlason +- Updated spec file as first step in turning this into a real RPM for taroon. +- Wrote man page.