Hi Dave,
I've got some questions for you if you don't mind. I've got a vmcore created
from a VMWare vmss file (I think using vmss2core) and crash just does this when I run it
on it:
$ crash -d5 vmlinux vmss.core
crash64 7.1.9
Copyright (C) 2002-2016 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011 NEC Corporation
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
crash64: Elf64_Phdr pointer: 1875020 ELF header end: 1874fe4
I spent a long time running gdb on crash and found that it makes some assumptions about
the layout of ELF files that can't really be relied upon (Program headers have a fixed
offset) and apparently no section headers. For the vmss.core file I have crash works out
that the header size of the ELF and program headers is 4 bytes (which is definitely not
correct).
I made some changes (see below) and can get it to get this far (some of the later
information is definitely not correct and I've got to make changes to is_netdump since
it has a fair number of issues as well):
$ crash-7.1.9/crash -d5 vmlinux vmss.core
crash 7.1.9
Copyright (C) 2002-2016 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011 NEC Corporation
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
vmcore_data:
flags: c0 (KDUMP_LOCAL|KDUMP_ELF64)
ndfd: 3
ofp: 3b0458f040
header_size: 352
num_pt_load_segments: 3
pt_load_segment[0]:
file_offset: 4
phys_start: 0
phys_end: 0
zero_fill: 218
pt_load_segment[1]:
file_offset: 700000001
phys_start: fff80000
phys_end: 1fff00000
zero_fill: 100000000
pt_load_segment[2]:
file_offset: 700000001
phys_start: 0
phys_end: 0
zero_fill: c0000000
elf_header: 1376130
elf32: 0
notes32: 0
load32: 0
elf64: 1376130
notes64: 1376170
load64: 13761a8
nt_prstatus: 0
nt_prpsinfo: 0
nt_taskstruct: 0
task_struct: 0
page_size: 0
switch_stack: 0
xen_kdump_data: (unused)
num_prstatus_notes: 0
num_qemu_notes: 0
vmcoreinfo: 0
size_vmcoreinfo: 0
nt_prstatus_percpu:
nt_qemu_percpu:
backup_src_start: 0
backup_src_size: 0
backup_offset: 0
Elf64_Ehdr:
e_ident: \177ELF
e_ident[EI_CLASS]: 2 (ELFCLASS64)
e_ident[EI_DATA]: 1 (ELFDATA2LSB)
e_ident[EI_VERSION]: 1 (EV_CURRENT)
e_ident[EI_OSABI]: 0 (ELFOSABI_SYSV)
e_ident[EI_ABIVERSION]: 0
e_type: 4 (ET_CORE)
e_machine: 62 (EM_X86_64)
e_version: 1 (EV_CURRENT)
e_entry: 0
e_phoff: 80
e_shoff: 40
e_flags: 0
e_ehsize: 40
e_phentsize: 38
e_phnum: 4
e_shentsize: 40
e_shnum: 1
e_shstrndx: 0
Elf64_Phdr:
p_type: 0 (PT_NULL)
p_offset: 0 (0)
p_vaddr: 0
p_paddr: 0
p_filesz: 0 (0)
p_memsz: 0 (0)
p_flags: 0 ()
p_align: 0
Elf64_Phdr:
p_type: 0 (PT_NULL)
p_offset: 4 (4)
p_vaddr: 160
p_paddr: 0
p_filesz: 0 (0)
p_memsz: 536 (218)
p_flags: 0 ()
p_align: 0
Elf64_Phdr:
p_type: 0 (PT_NULL)
p_offset: 30064771073 (700000001)
p_vaddr: 4000001000
p_paddr: fff80000
p_filesz: 4294443008 (fff80000)
p_memsz: 524288 (80000)
p_flags: 0 ()
p_align: 524288
Elf64_Phdr:
p_type: 1000 (?)
p_offset: 30064771073 (700000001)
p_vaddr: 1000
p_paddr: 0
p_filesz: 0 (0)
p_memsz: 3221225472 (c0000000)
p_flags: 0 ()
p_align: 3221225472
readmem: read_kdump()
crash: pv_init_ops exists: ARCH_PVOPS
gdb vmlinux
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <
http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
<readmem: ffffffff8165e250, KVADDR, "cpu_possible_mask", 8, (FOE),
7fffd7e36838>
<read_kdump: addr: ffffffff8165e250 paddr: 165e250 cnt: 8>
<readmem: ffffffff8165e240, KVADDR, "cpu_present_mask", 8, (FOE),
7fffd7e36838>
<read_kdump: addr: ffffffff8165e240 paddr: 165e240 cnt: 8>
<readmem: ffffffff8165e248, KVADDR, "cpu_online_mask", 8, (FOE),
7fffd7e36838>
<read_kdump: addr: ffffffff8165e248 paddr: 165e248 cnt: 8>
<readmem: ffffffff8165e238, KVADDR, "cpu_active_mask", 8, (FOE),
7fffd7e36838>
<read_kdump: addr: ffffffff8165e238 paddr: 165e238 cnt: 8>
<readmem: ffffffff819658d8, KVADDR, "pv_init_ops", 8, (ROE),
7fffd7e47a38>
<read_kdump: addr: ffffffff819658d8 paddr: 19658d8 cnt: 8>
<readmem: ffffffff81db6e18, KVADDR, "timekeeper xtime_sec", 8, (ROE),
7fffd7e36838>
<read_kdump: addr: ffffffff81db6e18 paddr: 1db6e18 cnt: 8>
xtime timespec.tv_sec: 0: Wed Dec 31 18:00:00 1969
<readmem: ffffffff81951284, KVADDR, "init_uts_ns", 390, (ROE), cfe2dc>
<read_kdump: addr: ffffffff81951284 paddr: 1951284 cnt: 390>
utsname:
sysname:
nodename:
release:
version:
machine:
domainname:
base kernel version: 0.1.9
<readmem: ffffffff8164d100, KVADDR, "accessible check", 8, (ROE|Q),
7fffd7e33ba8>
<read_kdump: addr: ffffffff8164d100 paddr: 164d100 cnt: 8>
<readmem: ffffffff8164d100, KVADDR, "read_string characters", 1499, (ROE|Q),
7fffd7e35f10>
<read_kdump: addr: ffffffff8164d100 paddr: 164d100 cnt: 1499>
WARNING: cannot read linux_banner string
linux_banner:
crash: vmlinux and vmss.core do not match!
Usage:
crash [OPTION]... NAMELIST MEMORY-IMAGE[@ADDRESS] (dumpfile form)
crash [OPTION]... [NAMELIST] (live system form)
Enter "crash -h" for details.
Using something like readelf:
$ readelf --file-header vmss.core
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: CORE (Core file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 128 (bytes into file)
Start of section headers: 64 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 4
Size of section headers: 64 (bytes)
Number of section headers: 1
Section header string table index: 0
Shows that the file has one section header (resize_elf_header didn't seem to do
anything with section headers) and 4 program headers:
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
NOTE 0x0000000000000160 0x0000000000000000 0x0000000000000000
0x0000000000000218 0x0000000000000000 0
LOAD 0x0000004000001000 0x00000000fff80000 0x00000000fff80000
0x0000000000080000 0x0000000000080000 RWE 1000
LOAD 0x0000000000001000 0x0000000000000000 0x0000000000000000
0x00000000c0000000 0x00000000c0000000 RWE 1000
LOAD 0x00000000c0001000 0x0000000100000000 0x0000000100000000
0x0000003f40000000 0x0000003f40000000 RWE 1000
The changes I made (note that I only tested the ELF64 code). In the first calculation of
the header_size below it seems to assume that there will always be an ELF header followed
by program headers (one for the note program header and then e_phnum-1 load program
headers) but doesn't take into account the potential existence of a section header:
--- crash-7.1.9/netdump.c 2017-04-20 13:53:16.000000000 -0500
+++ crash-7.1.9.new/netdump.c 2017-06-22 23:48:23.282639936 -0500
@@ -455,16 +455,20 @@ resize_elf_header(int fd, char *file, ch
{
case NETDUMP_ELF32:
case KDUMP_ELF32:
- num_pt_load_segments = elf32->e_phnum - 1;
- header_size = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) +
- (sizeof(Elf32_Phdr) * num_pt_load_segments);
+ header_size = elf32->e_shoff +
+ elf32->e_shnum * elf32->e_shentsize;
+ if (elf32->e_phoff > elf32->e_shoff)
+ header_size = elf32->e_phoff +
+ elf32->e_phnum * elf32->e_phentsize;
break;
case NETDUMP_ELF64:
case KDUMP_ELF64:
- num_pt_load_segments = elf64->e_phnum - 1;
- header_size = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) +
- (sizeof(Elf64_Phdr) * num_pt_load_segments);
+ header_size = elf64->e_shoff +
+ elf64->e_shnum * elf64->e_shentsize;
+ if (elf64->e_phoff > elf64->e_shoff)
+ header_size = elf64->e_phoff +
+ elf64->e_phnum * elf64->e_phentsize;
break;
}
@@ -494,26 +498,34 @@ resize_elf_header(int fd, char *file, ch
{
case NETDUMP_ELF32:
case KDUMP_ELF32:
- load32 = (Elf32_Phdr
*)&eheader[sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr)];
+ load32 = (Elf32_Phdr *)&eheader[elf32->e_phoff];
p_offset32 = load32->p_offset;
- for (i = 0; i < num_pt_load_segments; i++, load32 += 1) {
+ for (i = 0; i < elf32->e_phnum; i++, load32 += 1) {
if (load32->p_offset &&
(p_offset32 > load32->p_offset))
p_offset32 = load32->p_offset;
}
- header_size = (size_t)p_offset32;
+ if (header_size == p_offset32) {
+ return header_size;
+ } else {
+ header_size = (size_t)p_offset32;
+ }
break;
case NETDUMP_ELF64:
case KDUMP_ELF64:
- load64 = (Elf64_Phdr
*)&eheader[sizeof(Elf64_Ehdr)+sizeof(Elf64_Phdr)];
+ load64 = (Elf64_Phdr *)&eheader[elf64->e_phoff];
p_offset64 = load64->p_offset;
- for (i = 0; i < num_pt_load_segments; i++, load64 += 1) {
+ for (i = 0; i < elf64->e_phnum; i++, load64 += 1) {
if (load64->p_offset &&
(p_offset64 > load64->p_offset))
p_offset64 = load64->p_offset;
}
- header_size = (size_t)p_offset64;
+ if (header_size == p_offset64) {
+ return header_size;
+ } else {
+ header_size = (size_t)p_offset64;
+ }
break;
}
This shouldn't be considered a patch (yet) but more of a request for comments so about
if section headers are expected in an ELF64 vmcore and if I can more generally trust
values like e_shoff, e_shnum, e_shentsize, e_phoff, e_phnum, and e_phentsize from the ELF
header in all vmcores so I can change the code to cope with the potential presense of a
section header? I'm sort of hoping that you will tell me I can rely on them being
valid.
Thanks
Shane