📄 vmcore.c
字号:
if (nhdr_ptr->n_namesz == 0) break; sz = sizeof(Elf32_Nhdr) + ((nhdr_ptr->n_namesz + 3) & ~3) + ((nhdr_ptr->n_descsz + 3) & ~3); real_sz += sz; nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); } /* Add this contiguous chunk of notes section to vmcore list.*/ new = get_new_element(); if (!new) { kfree(notes_section); return -ENOMEM; } new->paddr = phdr_ptr->p_offset; new->size = real_sz; list_add_tail(&new->list, vc_list); phdr_sz += real_sz; kfree(notes_section); } /* Prepare merged PT_NOTE program header. */ phdr.p_type = PT_NOTE; phdr.p_flags = 0; note_off = sizeof(Elf32_Ehdr) + (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf32_Phdr); phdr.p_offset = note_off; phdr.p_vaddr = phdr.p_paddr = 0; phdr.p_filesz = phdr.p_memsz = phdr_sz; phdr.p_align = 0; /* Add merged PT_NOTE program header*/ tmp = elfptr + sizeof(Elf32_Ehdr); memcpy(tmp, &phdr, sizeof(phdr)); tmp += sizeof(phdr); /* Remove unwanted PT_NOTE program headers. */ i = (nr_ptnote - 1) * sizeof(Elf32_Phdr); *elfsz = *elfsz - i; memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf32_Ehdr)-sizeof(Elf32_Phdr))); /* Modify e_phnum to reflect merged headers. */ ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1; return 0;}/* Add memory chunks represented by program headers to vmcore list. Also update * the new offset fields of exported program headers. */static int __init process_ptload_program_headers_elf64(char *elfptr, size_t elfsz, struct list_head *vc_list){ int i; Elf64_Ehdr *ehdr_ptr; Elf64_Phdr *phdr_ptr; loff_t vmcore_off; struct vmcore *new; ehdr_ptr = (Elf64_Ehdr *)elfptr; phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); /* PT_NOTE hdr */ /* First program header is PT_NOTE header. */ vmcore_off = sizeof(Elf64_Ehdr) + (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr) + phdr_ptr->p_memsz; /* Note sections */ for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { if (phdr_ptr->p_type != PT_LOAD) continue; /* Add this contiguous chunk of memory to vmcore list.*/ new = get_new_element(); if (!new) return -ENOMEM; new->paddr = phdr_ptr->p_offset; new->size = phdr_ptr->p_memsz; list_add_tail(&new->list, vc_list); /* Update the program header offset. */ phdr_ptr->p_offset = vmcore_off; vmcore_off = vmcore_off + phdr_ptr->p_memsz; } return 0;}static int __init process_ptload_program_headers_elf32(char *elfptr, size_t elfsz, struct list_head *vc_list){ int i; Elf32_Ehdr *ehdr_ptr; Elf32_Phdr *phdr_ptr; loff_t vmcore_off; struct vmcore *new; ehdr_ptr = (Elf32_Ehdr *)elfptr; phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); /* PT_NOTE hdr */ /* First program header is PT_NOTE header. */ vmcore_off = sizeof(Elf32_Ehdr) + (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr) + phdr_ptr->p_memsz; /* Note sections */ for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) { if (phdr_ptr->p_type != PT_LOAD) continue; /* Add this contiguous chunk of memory to vmcore list.*/ new = get_new_element(); if (!new) return -ENOMEM; new->paddr = phdr_ptr->p_offset; new->size = phdr_ptr->p_memsz; list_add_tail(&new->list, vc_list); /* Update the program header offset */ phdr_ptr->p_offset = vmcore_off; vmcore_off = vmcore_off + phdr_ptr->p_memsz; } return 0;}/* Sets offset fields of vmcore elements. */static void __init set_vmcore_list_offsets_elf64(char *elfptr, struct list_head *vc_list){ loff_t vmcore_off; Elf64_Ehdr *ehdr_ptr; struct vmcore *m; ehdr_ptr = (Elf64_Ehdr *)elfptr; /* Skip Elf header and program headers. */ vmcore_off = sizeof(Elf64_Ehdr) + (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr); list_for_each_entry(m, vc_list, list) { m->offset = vmcore_off; vmcore_off += m->size; }}/* Sets offset fields of vmcore elements. */static void __init set_vmcore_list_offsets_elf32(char *elfptr, struct list_head *vc_list){ loff_t vmcore_off; Elf32_Ehdr *ehdr_ptr; struct vmcore *m; ehdr_ptr = (Elf32_Ehdr *)elfptr; /* Skip Elf header and program headers. */ vmcore_off = sizeof(Elf32_Ehdr) + (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr); list_for_each_entry(m, vc_list, list) { m->offset = vmcore_off; vmcore_off += m->size; }}static int __init parse_crash_elf64_headers(void){ int rc=0; Elf64_Ehdr ehdr; u64 addr; addr = elfcorehdr_addr; /* Read Elf header */ rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0); if (rc < 0) return rc; /* Do some basic Verification. */ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || (ehdr.e_type != ET_CORE) || !vmcore_elf_check_arch(&ehdr) || ehdr.e_ident[EI_CLASS] != ELFCLASS64 || ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT || ehdr.e_ehsize != sizeof(Elf64_Ehdr) || ehdr.e_phentsize != sizeof(Elf64_Phdr) || ehdr.e_phnum == 0) { printk(KERN_WARNING "Warning: Core image elf header is not" "sane\n"); return -EINVAL; } /* Read in all elf headers. */ elfcorebuf_sz = sizeof(Elf64_Ehdr) + ehdr.e_phnum * sizeof(Elf64_Phdr); elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL); if (!elfcorebuf) return -ENOMEM; addr = elfcorehdr_addr; rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0); if (rc < 0) { kfree(elfcorebuf); return rc; } /* Merge all PT_NOTE headers into one. */ rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, &vmcore_list); if (rc) { kfree(elfcorebuf); return rc; } rc = process_ptload_program_headers_elf64(elfcorebuf, elfcorebuf_sz, &vmcore_list); if (rc) { kfree(elfcorebuf); return rc; } set_vmcore_list_offsets_elf64(elfcorebuf, &vmcore_list); return 0;}static int __init parse_crash_elf32_headers(void){ int rc=0; Elf32_Ehdr ehdr; u64 addr; addr = elfcorehdr_addr; /* Read Elf header */ rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0); if (rc < 0) return rc; /* Do some basic Verification. */ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || (ehdr.e_type != ET_CORE) || !elf_check_arch(&ehdr) || ehdr.e_ident[EI_CLASS] != ELFCLASS32|| ehdr.e_ident[EI_VERSION] != EV_CURRENT || ehdr.e_version != EV_CURRENT || ehdr.e_ehsize != sizeof(Elf32_Ehdr) || ehdr.e_phentsize != sizeof(Elf32_Phdr) || ehdr.e_phnum == 0) { printk(KERN_WARNING "Warning: Core image elf header is not" "sane\n"); return -EINVAL; } /* Read in all elf headers. */ elfcorebuf_sz = sizeof(Elf32_Ehdr) + ehdr.e_phnum * sizeof(Elf32_Phdr); elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL); if (!elfcorebuf) return -ENOMEM; addr = elfcorehdr_addr; rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0); if (rc < 0) { kfree(elfcorebuf); return rc; } /* Merge all PT_NOTE headers into one. */ rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, &vmcore_list); if (rc) { kfree(elfcorebuf); return rc; } rc = process_ptload_program_headers_elf32(elfcorebuf, elfcorebuf_sz, &vmcore_list); if (rc) { kfree(elfcorebuf); return rc; } set_vmcore_list_offsets_elf32(elfcorebuf, &vmcore_list); return 0;}static int __init parse_crash_elf_headers(void){ unsigned char e_ident[EI_NIDENT]; u64 addr; int rc=0; addr = elfcorehdr_addr; rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0); if (rc < 0) return rc; if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { printk(KERN_WARNING "Warning: Core image elf header" " not found\n"); return -EINVAL; } if (e_ident[EI_CLASS] == ELFCLASS64) { rc = parse_crash_elf64_headers(); if (rc) return rc; /* Determine vmcore size. */ vmcore_size = get_vmcore_size_elf64(elfcorebuf); } else if (e_ident[EI_CLASS] == ELFCLASS32) { rc = parse_crash_elf32_headers(); if (rc) return rc; /* Determine vmcore size. */ vmcore_size = get_vmcore_size_elf32(elfcorebuf); } else { printk(KERN_WARNING "Warning: Core image elf header is not" " sane\n"); return -EINVAL; } return 0;}/* Init function for vmcore module. */static int __init vmcore_init(void){ int rc = 0; /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/ if (!(elfcorehdr_addr < ELFCORE_ADDR_MAX)) return rc; rc = parse_crash_elf_headers(); if (rc) { printk(KERN_WARNING "Kdump: vmcore not initialized\n"); return rc; } /* Initialize /proc/vmcore size if proc is already up. */ if (proc_vmcore) proc_vmcore->size = vmcore_size; return 0;}module_init(vmcore_init)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -