--- crash-4.0-6.0/task.c 2008-02-28 11:11:35.000000000 -0500 +++ crash-4.0-6.1/task.c 2008-02-26 14:01:36.000000000 -0500 @@ -154,6 +154,15 @@ "thread_struct", "eip"); esp_offset = MEMBER_OFFSET_INIT(thread_struct_esp, "thread_struct", "esp"); + /* + * Handle x86/x86_64 merger. + */ + if (eip_offset == INVALID_OFFSET) + eip_offset = MEMBER_OFFSET_INIT(thread_struct_eip, + "thread_struct", "ip"); + if (esp_offset == INVALID_OFFSET) + esp_offset = MEMBER_OFFSET_INIT(thread_struct_esp, + "thread_struct", "sp"); ksp_offset = MEMBER_OFFSET_INIT(thread_struct_ksp, "thread_struct", "ksp"); ASSIGN_OFFSET(task_struct_thread_eip) = --- crash-4.0-6.0/kernel.c 2008-02-28 11:11:35.000000000 -0500 +++ crash-4.0-6.1/kernel.c 2008-02-27 12:06:40.000000000 -0500 @@ -386,8 +386,18 @@ "tvec_root_s", "vec"); STRUCT_SIZE_INIT(tvec_s, "tvec_s"); MEMBER_OFFSET_INIT(tvec_s_vec, "tvec_s", "vec"); + } else { + STRUCT_SIZE_INIT(tvec_root_s, "tvec_root"); + if (VALID_STRUCT(tvec_root_s)) { + STRUCT_SIZE_INIT(tvec_t_base_s, "tvec_base"); + MEMBER_OFFSET_INIT(tvec_t_base_s_tv1, + "tvec_base", "tv1"); + MEMBER_OFFSET_INIT(tvec_root_s_vec, + "tvec_root", "vec"); + STRUCT_SIZE_INIT(tvec_s, "tvec"); + MEMBER_OFFSET_INIT(tvec_s_vec, "tvec", "vec"); + } } - STRUCT_SIZE_INIT(__wait_queue, "__wait_queue"); if (VALID_STRUCT(__wait_queue)) { if (MEMBER_EXISTS("__wait_queue", "task")) @@ -4977,8 +4987,20 @@ */ vec_root_size = (i = ARRAY_LENGTH(tvec_root_s_vec)) ? i : get_array_length("tvec_root_s.vec", NULL, SIZE(list_head)); + if (!vec_root_size && + (i = get_array_length("tvec_root.vec", NULL, SIZE(list_head)))) + vec_root_size = i; + if (!vec_root_size) + error(FATAL, "cannot determine tvec_root.vec[] array size\n"); + vec_size = (i = ARRAY_LENGTH(tvec_s_vec)) ? i : get_array_length("tvec_s.vec", NULL, SIZE(list_head)); + if (!vec_size && + (i = get_array_length("tvec.vec", NULL, SIZE(list_head)))) + vec_size = i; + if (!vec_size) + error(FATAL, "cannot determine tvec.vec[] array size\n"); + vec = (ulong *)GETBUF(SIZE(list_head) * MAX(vec_root_size, vec_size)); cpu = 0; --- crash-4.0-6.0/x86.c 2008-02-28 11:11:35.000000000 -0500 +++ crash-4.0-6.1/x86.c 2008-02-26 16:37:13.000000000 -0500 @@ -1,8 +1,8 @@ /* x86.c - core analysis suite * * Portions Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. - * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 @@ -1777,6 +1777,27 @@ "user_regs_struct", "ebp"); MEMBER_OFFSET_INIT(user_regs_struct_esp, "user_regs_struct", "esp"); + if (!VALID_STRUCT(user_regs_struct)) { + /* Use this hardwired version -- sometimes the + * debuginfo doesn't pick this up even though + * it exists in the kernel; it shouldn't change. + */ + struct x86_user_regs_struct { + long ebx, ecx, edx, esi, edi, ebp, eax; + unsigned short ds, __ds, es, __es; + unsigned short fs, __fs, gs, __gs; + long orig_eax, eip; + unsigned short cs, __cs; + long eflags, esp; + unsigned short ss, __ss; + }; + ASSIGN_SIZE(user_regs_struct) = + sizeof(struct x86_user_regs_struct); + ASSIGN_OFFSET(user_regs_struct_ebp) = + offsetof(struct x86_user_regs_struct, ebp); + ASSIGN_OFFSET(user_regs_struct_esp) = + offsetof(struct x86_user_regs_struct, esp); + } MEMBER_OFFSET_INIT(thread_struct_cr3, "thread_struct", "cr3"); STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86"); STRUCT_SIZE_INIT(e820map, "e820map"); @@ -1852,23 +1873,43 @@ return; } - INT_EFRAME_SS = MEMBER_OFFSET("pt_regs", "xss") / 4; - INT_EFRAME_ESP = MEMBER_OFFSET("pt_regs", "esp") / 4; - INT_EFRAME_EFLAGS = MEMBER_OFFSET("pt_regs", "eflags") / 4; - INT_EFRAME_CS = MEMBER_OFFSET("pt_regs", "xcs") / 4; - INT_EFRAME_EIP = MEMBER_OFFSET("pt_regs", "eip") / 4; - INT_EFRAME_ERR = MEMBER_OFFSET("pt_regs", "orig_eax") / 4; - if ((INT_EFRAME_GS = MEMBER_OFFSET("pt_regs", "xgs")) != -1) - INT_EFRAME_GS /= 4; - INT_EFRAME_ES = MEMBER_OFFSET("pt_regs", "xes") / 4; - INT_EFRAME_DS = MEMBER_OFFSET("pt_regs", "xds") / 4; - INT_EFRAME_EAX = MEMBER_OFFSET("pt_regs", "eax") / 4; - INT_EFRAME_EBP = MEMBER_OFFSET("pt_regs", "ebp") / 4; - INT_EFRAME_EDI = MEMBER_OFFSET("pt_regs", "edi") / 4; - INT_EFRAME_ESI = MEMBER_OFFSET("pt_regs", "esi") / 4; - INT_EFRAME_EDX = MEMBER_OFFSET("pt_regs", "edx") / 4; - INT_EFRAME_ECX = MEMBER_OFFSET("pt_regs", "ecx") / 4; - INT_EFRAME_EBX = MEMBER_OFFSET("pt_regs", "ebx") / 4; + if (MEMBER_EXISTS("pt_regs", "esp")) { + INT_EFRAME_SS = MEMBER_OFFSET("pt_regs", "xss") / 4; + INT_EFRAME_ESP = MEMBER_OFFSET("pt_regs", "esp") / 4; + INT_EFRAME_EFLAGS = MEMBER_OFFSET("pt_regs", "eflags") / 4; + INT_EFRAME_CS = MEMBER_OFFSET("pt_regs", "xcs") / 4; + INT_EFRAME_EIP = MEMBER_OFFSET("pt_regs", "eip") / 4; + INT_EFRAME_ERR = MEMBER_OFFSET("pt_regs", "orig_eax") / 4; + if ((INT_EFRAME_GS = MEMBER_OFFSET("pt_regs", "xgs")) != -1) + INT_EFRAME_GS /= 4; + INT_EFRAME_ES = MEMBER_OFFSET("pt_regs", "xes") / 4; + INT_EFRAME_DS = MEMBER_OFFSET("pt_regs", "xds") / 4; + INT_EFRAME_EAX = MEMBER_OFFSET("pt_regs", "eax") / 4; + INT_EFRAME_EBP = MEMBER_OFFSET("pt_regs", "ebp") / 4; + INT_EFRAME_EDI = MEMBER_OFFSET("pt_regs", "edi") / 4; + INT_EFRAME_ESI = MEMBER_OFFSET("pt_regs", "esi") / 4; + INT_EFRAME_EDX = MEMBER_OFFSET("pt_regs", "edx") / 4; + INT_EFRAME_ECX = MEMBER_OFFSET("pt_regs", "ecx") / 4; + INT_EFRAME_EBX = MEMBER_OFFSET("pt_regs", "ebx") / 4; + } else { + INT_EFRAME_SS = MEMBER_OFFSET("pt_regs", "ss") / 4; + INT_EFRAME_ESP = MEMBER_OFFSET("pt_regs", "sp") / 4; + INT_EFRAME_EFLAGS = MEMBER_OFFSET("pt_regs", "flags") / 4; + INT_EFRAME_CS = MEMBER_OFFSET("pt_regs", "cs") / 4; + INT_EFRAME_EIP = MEMBER_OFFSET("pt_regs", "ip") / 4; + INT_EFRAME_ERR = MEMBER_OFFSET("pt_regs", "orig_ax") / 4; + if ((INT_EFRAME_GS = MEMBER_OFFSET("pt_regs", "gs")) != -1) + INT_EFRAME_GS /= 4; + INT_EFRAME_ES = MEMBER_OFFSET("pt_regs", "es") / 4; + INT_EFRAME_DS = MEMBER_OFFSET("pt_regs", "ds") / 4; + INT_EFRAME_EAX = MEMBER_OFFSET("pt_regs", "ax") / 4; + INT_EFRAME_EBP = MEMBER_OFFSET("pt_regs", "bp") / 4; + INT_EFRAME_EDI = MEMBER_OFFSET("pt_regs", "di") / 4; + INT_EFRAME_ESI = MEMBER_OFFSET("pt_regs", "si") / 4; + INT_EFRAME_EDX = MEMBER_OFFSET("pt_regs", "dx") / 4; + INT_EFRAME_ECX = MEMBER_OFFSET("pt_regs", "cx") / 4; + INT_EFRAME_EBX = MEMBER_OFFSET("pt_regs", "bx") / 4; + } } /* @@ -3136,6 +3177,7 @@ { int others; ulong xen_wpt; + char buf[BUFSIZE]; switch (arg) { default: @@ -3218,6 +3260,40 @@ fprintf(fp, " get_xendump_regs: x86_get_xendump_regs()\n"); fprintf(fp, "xen_kdump_p2m_create: x86_xen_kdump_p2m_create()\n"); fprintf(fp, "clear_machdep_cache: x86_clear_machdep_cache()\n"); + fprintf(fp, " INT_EFRAME_[reg]:\n"); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "SS: "), INT_EFRAME_SS); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "ESP: "), INT_EFRAME_ESP); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "EFLAGS: "), INT_EFRAME_EFLAGS); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "CS: "), INT_EFRAME_CS); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "IP: "), INT_EFRAME_EIP); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "ERR: "), INT_EFRAME_ERR); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "ES: "), INT_EFRAME_ES); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "DS: "), INT_EFRAME_DS); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "EAX: "), INT_EFRAME_EAX); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "EBP: "), INT_EFRAME_EBP); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "EDI: "), INT_EFRAME_EDI); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "ESI: "), INT_EFRAME_ESI); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "EDX: "), INT_EFRAME_EDX); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "ECX: "), INT_EFRAME_ECX); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "EBX: "), INT_EFRAME_EBX); + fprintf(fp, "%s %d\n", + mkstring(buf, 21, RJUST, "GS: "), INT_EFRAME_GS); + fprintf(fp, " machspec: x86_machine_specific\n"); fprintf(fp, " idt_table: %lx\n", (ulong)machdep->machspec->idt_table); --- crash-4.0-6.0/x86_64.c 2008-02-28 11:11:35.000000000 -0500 +++ crash-4.0-6.1/x86_64.c 2008-02-26 11:32:17.000000000 -0500 @@ -254,8 +254,23 @@ MEMBER_OFFSET_INIT(thread_struct_rip, "thread_struct", "rip"); MEMBER_OFFSET_INIT(thread_struct_rsp, "thread_struct", "rsp"); MEMBER_OFFSET_INIT(thread_struct_rsp0, "thread_struct", "rsp0"); + if (INVALID_MEMBER(thread_struct_rip)) + MEMBER_OFFSET_INIT(thread_struct_rip, "thread_struct", "ip"); + if (INVALID_MEMBER(thread_struct_rsp)) + MEMBER_OFFSET_INIT(thread_struct_rsp, "thread_struct", "sp"); + if (INVALID_MEMBER(thread_struct_rsp0)) + MEMBER_OFFSET_INIT(thread_struct_rsp0, "thread_struct", "sp0"); STRUCT_SIZE_INIT(tss_struct, "tss_struct"); MEMBER_OFFSET_INIT(tss_struct_ist, "tss_struct", "ist"); + if (INVALID_MEMBER(tss_struct_ist)) { + long x86_tss_offset, ist_offset; + x86_tss_offset = MEMBER_OFFSET("tss_struct", "x86_tss"); + ist_offset = MEMBER_OFFSET("x86_hw_tss", "ist"); + if ((x86_tss_offset != INVALID_OFFSET) && + (ist_offset != INVALID_OFFSET)) + ASSIGN_OFFSET(tss_struct_ist) = x86_tss_offset + + ist_offset; + } MEMBER_OFFSET_INIT(user_regs_struct_rip, "user_regs_struct", "rip"); MEMBER_OFFSET_INIT(user_regs_struct_rsp, @@ -3108,33 +3123,68 @@ INVALID_OFFSET); err |= ((ms->pto.r8 = MEMBER_OFFSET("pt_regs", "r8")) == INVALID_OFFSET); - err |= ((ms->pto.rax = MEMBER_OFFSET("pt_regs", "rax")) == - INVALID_OFFSET); - err |= ((ms->pto.rbx = MEMBER_OFFSET("pt_regs", "rbx")) == - INVALID_OFFSET); - err |= ((ms->pto.rcx = MEMBER_OFFSET("pt_regs", "rcx")) == - INVALID_OFFSET); - err |= ((ms->pto.rdx = MEMBER_OFFSET("pt_regs", "rdx")) == - INVALID_OFFSET); - err |= ((ms->pto.rsi = MEMBER_OFFSET("pt_regs", "rsi")) == - INVALID_OFFSET); - err |= ((ms->pto.rdi = MEMBER_OFFSET("pt_regs", "rdi")) == - INVALID_OFFSET); - err |= ((ms->pto.rip = MEMBER_OFFSET("pt_regs", "rip")) == - INVALID_OFFSET); - err |= ((ms->pto.rsp = MEMBER_OFFSET("pt_regs", "rsp")) == - INVALID_OFFSET); err |= ((ms->pto.cs = MEMBER_OFFSET("pt_regs", "cs")) == INVALID_OFFSET); err |= ((ms->pto.ss = MEMBER_OFFSET("pt_regs", "ss")) == INVALID_OFFSET); - err |= ((ms->pto.eflags = MEMBER_OFFSET("pt_regs", "eflags")) == - INVALID_OFFSET); - err |= ((ms->pto.orig_rax = - MEMBER_OFFSET("pt_regs", "orig_rax")) == - INVALID_OFFSET); - err |= ((ms->pto.rbp = MEMBER_OFFSET("pt_regs", "rbp")) == - INVALID_OFFSET); + /* + * x86/x86_64 merge changed traditional register names. + */ + if (((ms->pto.rbp = MEMBER_OFFSET("pt_regs", "rbp")) == + INVALID_OFFSET) && + ((ms->pto.rbp = MEMBER_OFFSET("pt_regs", "bp")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rax = MEMBER_OFFSET("pt_regs", "rax")) == + INVALID_OFFSET) && + ((ms->pto.rax = MEMBER_OFFSET("pt_regs", "ax")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rbx = MEMBER_OFFSET("pt_regs", "rbx")) == + INVALID_OFFSET) && + ((ms->pto.rbx = MEMBER_OFFSET("pt_regs", "bx")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rcx = MEMBER_OFFSET("pt_regs", "rcx")) == + INVALID_OFFSET) && + ((ms->pto.rcx = MEMBER_OFFSET("pt_regs", "cx")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rdx = MEMBER_OFFSET("pt_regs", "rdx")) == + INVALID_OFFSET) && + ((ms->pto.rdx = MEMBER_OFFSET("pt_regs", "dx")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rsi = MEMBER_OFFSET("pt_regs", "rsi")) == + INVALID_OFFSET) && + ((ms->pto.rsi = MEMBER_OFFSET("pt_regs", "si")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rdi = MEMBER_OFFSET("pt_regs", "rdi")) == + INVALID_OFFSET) && + ((ms->pto.rdi = MEMBER_OFFSET("pt_regs", "di")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rip = MEMBER_OFFSET("pt_regs", "rip")) == + INVALID_OFFSET) && + ((ms->pto.rip = MEMBER_OFFSET("pt_regs", "ip")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.rsp = MEMBER_OFFSET("pt_regs", "rsp")) == + INVALID_OFFSET) && + ((ms->pto.rsp = MEMBER_OFFSET("pt_regs", "sp")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.eflags = MEMBER_OFFSET("pt_regs", "eflags")) == + INVALID_OFFSET) && + ((ms->pto.eflags = MEMBER_OFFSET("pt_regs", "flags")) == + INVALID_OFFSET)) + err++; + if (((ms->pto.orig_rax = MEMBER_OFFSET("pt_regs", "orig_rax")) == + INVALID_OFFSET) && + ((ms->pto.orig_rax = MEMBER_OFFSET("pt_regs", "orig_ax")) == + INVALID_OFFSET)) + err++; if (err) error(WARNING, "pt_regs structure has changed\n"); --- crash-4.0-6.0/symbols.c 2008-02-28 11:11:35.000000000 -0500 +++ crash-4.0-6.1/symbols.c 2008-02-26 11:32:11.000000000 -0500 @@ -8999,7 +8999,8 @@ if (pc->flags & DROP_CORE) drop_core("DROP_CORE flag set: forcing a segmentation fault\n"); - gdb_readnow_warning(); + if (CRASHDEBUG(1)) + gdb_readnow_warning(); if (pc->flags & RUNTIME) { sprintf(buf, "%s\n%s FILE: %s LINE: %d FUNCTION: %s()\n", --- crash-4.0-6.0/lkcd_x86_trace.c 2008-02-28 11:11:35.000000000 -0500 +++ crash-4.0-6.1/lkcd_x86_trace.c 2008-02-26 15:55:48.000000000 -0500 @@ -5,8 +5,8 @@ /* * lkcd_x86_trace.c * - * Copyright (C) 2002, 2003, 2004, 2005, 2006 David Anderson - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 David Anderson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. All rights reserved. * * Adapted as noted from the following LKCD files: * @@ -2534,7 +2534,8 @@ efp->tracesys_exit = symbol_search("tracesys_exit"); } - if ((efp->sysenter = symbol_search("sysenter_entry"))) { + if ((efp->sysenter = symbol_search("sysenter_entry")) || + (efp->sysenter = symbol_search("ia32_sysenter_target"))) { if ((sp = symbol_search("sysexit_ret_end_marker"))) efp->sysenter_end = sp; else if ((sp = symbol_search("system_call")))