void *kdump_core32_header_init(const struct mrdump_control_block *mrdump_cb, uint64_t kmem_address, uint64_t kmem_size) { struct elf32_phdr *nhdr, *phdr; struct elf32_hdr *elf; off_t offset = 0; const struct mrdump_machdesc *kparams = &mrdump_cb->machdesc; uint8_t *oldbufp = malloc(KDUMP_CORE_HEADER_SIZE); uint8_t *bufp = oldbufp; elf = (struct elf32_hdr *) bufp; bufp += sizeof(struct elf32_hdr); offset += sizeof(struct elf32_hdr); mrdump_elf_setup_eident(elf->e_ident, ELFCLASS32); mrdump_elf_setup_elfhdr(elf, EM_ARM, struct elf32_hdr, struct elf32_phdr) nhdr = (struct elf32_phdr *) bufp; bufp += sizeof(struct elf32_phdr); offset += sizeof(struct elf32_phdr); memset(nhdr, 0, sizeof(struct elf32_phdr)); nhdr->p_type = PT_NOTE; phdr = (struct elf32_phdr *) bufp; bufp += sizeof(struct elf32_phdr); offset += sizeof(struct elf32_phdr); uint32_t low_memory_size = kparams->high_memory - kparams->page_offset; if (low_memory_size > kmem_size) { low_memory_size = kmem_size; } phdr->p_type = PT_LOAD; phdr->p_flags = PF_R|PF_W|PF_X; phdr->p_offset = KDUMP_CORE_HEADER_SIZE; phdr->p_vaddr = (size_t) kparams->page_offset; phdr->p_paddr = kmem_address; phdr->p_filesz = kmem_size; phdr->p_memsz = low_memory_size; phdr->p_align = 0; nhdr->p_offset = offset; /* NT_PRPSINFO */ struct elf32_prpsinfo prpsinfo; struct memelfnote notes; /* set up the process info */ notes.name = CORE_STR; notes.type = NT_PRPSINFO; notes.datasz = sizeof(struct elf32_prpsinfo); notes.data = &prpsinfo; memset(&prpsinfo, 0, sizeof(struct elf32_prpsinfo)); prpsinfo.pr_state = 0; prpsinfo.pr_sname = 'R'; prpsinfo.pr_zomb = 0; prpsinfo.pr_gid = prpsinfo.pr_uid = mrdump_cb->crash_record.fault_cpu + 1; strlcpy(prpsinfo.pr_fname, "vmlinux", sizeof(prpsinfo.pr_fname)); strlcpy(prpsinfo.pr_psargs, "vmlinux", ELF_PRARGSZ); nhdr->p_filesz += notesize(¬es); bufp = storenote(¬es, bufp); bufp = kdump_core_write_machdesc(mrdump_cb, nhdr, bufp); /* Store pre-cpu backtrace */ bufp = kdump_core_write_cpu_note(mrdump_cb, mrdump_cb->crash_record.fault_cpu, nhdr, bufp); for (unsigned int cpu = 0; cpu < kparams->nr_cpus; cpu++) { if (cpu != mrdump_cb->crash_record.fault_cpu) { bufp = kdump_core_write_cpu_note(mrdump_cb, cpu, nhdr, bufp); } } // voprintf_debug("%s cpu %d header size %d\n", __FUNCTION__, kparams->nr_cpus, bufp - oldbufp); return oldbufp; }
void *kdump_core_header_init(const struct mrdump_control_block *mrdump_cb, uint32_t kmem_address, uint32_t kmem_size) { struct elf_phdr *nhdr, *phdr; struct elfhdr *elf; off_t offset = 0; const struct mrdump_machdesc *kparams = &mrdump_cb->machdesc; uint8_t *oldbufp = malloc(KDUMP_CORE_SIZE); uint8_t *bufp = oldbufp; /* setup ELF header */ elf = (struct elfhdr *) bufp; bufp += sizeof(struct elfhdr); offset += sizeof(struct elfhdr); memcpy(elf->e_ident, ELFMAG, SELFMAG); elf->e_ident[EI_CLASS] = ELFCLASS32; elf->e_ident[EI_DATA] = ELFDATA2LSB; elf->e_ident[EI_VERSION]= EV_CURRENT; elf->e_ident[EI_OSABI] = ELFOSABI_NONE; memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); elf->e_type = ET_CORE; elf->e_machine = EM_ARM; elf->e_version = EV_CURRENT; elf->e_entry = 0; elf->e_phoff = sizeof(struct elfhdr); elf->e_shoff = 0; elf->e_flags = ELF_CORE_EFLAGS; elf->e_ehsize = sizeof(struct elfhdr); elf->e_phentsize= sizeof(struct elf_phdr); elf->e_phnum = 2; elf->e_shentsize= 0; elf->e_shnum = 0; elf->e_shstrndx = 0; nhdr = (struct elf_phdr *) bufp; bufp += sizeof(struct elf_phdr); offset += sizeof(struct elf_phdr); memset(nhdr, 0, sizeof(struct elf_phdr)); nhdr->p_type = PT_NOTE; phdr = (struct elf_phdr *) bufp; bufp += sizeof(struct elf_phdr); offset += sizeof(struct elf_phdr); uint32_t low_memory_size = kparams->high_memory - kparams->page_offset; if (low_memory_size > kmem_size) { low_memory_size = kmem_size; } phdr->p_type = PT_LOAD; phdr->p_flags = PF_R|PF_W|PF_X; phdr->p_offset = KDUMP_CORE_SIZE; phdr->p_vaddr = (size_t) kparams->page_offset; phdr->p_paddr = kmem_address; phdr->p_filesz = kmem_size; phdr->p_memsz = low_memory_size; phdr->p_align = KDUMP_CORE_SIZE; nhdr->p_offset = offset; struct elf_prpsinfo prpsinfo; /* NT_PRPSINFO */ struct memelfnote notes; /* set up the process info */ notes.name = CORE_STR; notes.type = NT_PRPSINFO; notes.datasz = sizeof(struct elf_prpsinfo); notes.data = &prpsinfo; memset(&prpsinfo, 0, sizeof(struct elf_prpsinfo)); prpsinfo.pr_state = 0; prpsinfo.pr_sname = 'R'; prpsinfo.pr_zomb = 0; prpsinfo.pr_gid = prpsinfo.pr_uid = mrdump_cb->crash_record.fault_cpu + 1; strlcpy(prpsinfo.pr_fname, "vmlinux", sizeof(prpsinfo.pr_fname)); strlcpy(prpsinfo.pr_psargs, "vmlinux", ELF_PRARGSZ); nhdr->p_filesz += notesize(¬es); bufp = storenote(¬es, bufp); bufp = kdump_core_write_machdesc(mrdump_cb, nhdr, bufp); /* Store pre-cpu backtrace */ bufp = kdump_core_write_cpu_note(mrdump_cb, mrdump_cb->crash_record.fault_cpu, nhdr, bufp); for (unsigned int cpu = 0; cpu < kparams->nr_cpus; cpu++) { if (cpu != mrdump_cb->crash_record.fault_cpu) { bufp = kdump_core_write_cpu_note(mrdump_cb, cpu, nhdr, bufp); } } voprintf_debug("%s cpu %d header size %d\n", __FUNCTION__, kparams->nr_cpus, bufp - oldbufp); return oldbufp; }