Populates the ELF header. It fills the magic number, version, machine number of program headers and other members of the ELF_HEADER. All the information is derived from the ELF_HEADER of the exe of the process to be dumped through /proc/pid/exe. Signed-off-by: Janani Venkataraman <jananive@xxxxxxxxxxxxxxxxxx> --- src/coredump.c | 3 ++ src/coredump.h | 1 + src/elf.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/elf32.c | 4 ++ src/elf64.c | 4 ++ 5 files changed, 108 insertions(+) diff --git a/src/coredump.c b/src/coredump.c index b1ee99d..de0a7ce 100644 --- a/src/coredump.c +++ b/src/coredump.c @@ -213,6 +213,9 @@ cleanup: if (cp.vmas) free_maps(cp.vmas); + if (cp.elf_hdr) + free(cp.elf_hdr); + errno = status; return ret; diff --git a/src/coredump.h b/src/coredump.h index 25042f5..4e508c1 100644 --- a/src/coredump.h +++ b/src/coredump.h @@ -32,4 +32,5 @@ struct core_proc { struct maps *vmas; /* VMAs */ int phdrs_count; /* Number of Program headers */ int elf_class; /* Elf class of the process */ + void *elf_hdr; /* Stores the ELF_header */ }; diff --git a/src/elf.c b/src/elf.c index 280df13..9f65c77 100644 --- a/src/elf.c +++ b/src/elf.c @@ -22,10 +22,106 @@ * Suzuki K. Poulose <suzuki@xxxxxxxxxx> */ +#include <errno.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/uio.h> +#include <linux/elf.h> #include "coredump.h" +/* Fetchs ELF header of the executable */ +static int get_elf_hdr_exe_file(int pid, Elf_Ehdr *elf) +{ + char filename[40]; + int ret; + FILE *fin; + + snprintf(filename, 40, "/proc/%d/exe", pid); + fin = fopen(filename, "r"); + if (fin == NULL) { + status = errno; + gencore_log("Failed to open %s for checking the ELF header.", + filename); + return -1; + } + + ret = fread(elf, sizeof(*elf), 1, fin); + if (ret != 1) { + status = errno; + gencore_log("Failure while fetching the ELF header of the executable from %s.\n", filename); + fclose(fin); + return -1; + } + + fclose(fin); + + return 0; +} + +/* Fills the ELF HEADER */ +static int fill_elf_header(int pid, struct core_proc *cp) +{ + Elf_Ehdr elf, *cp_elf; + int ret; + + cp->elf_hdr = malloc(sizeof(Elf_Ehdr)); + if (!cp->elf_hdr) { + status = errno; + gencore_log("Failure in allocating memory for ELF header.\n"); + return -1; + } + + cp_elf = (Elf_Ehdr *)cp->elf_hdr; + + memset(cp_elf, 0, EI_NIDENT); + + ret = get_elf_hdr_exe_file(pid, &elf); + if (ret == -1) + return -1; + + /* Magic Number */ + memcpy(cp_elf->e_ident, ELFMAG, SELFMAG); + + cp_elf->e_ident[EI_CLASS] = elf.e_ident[EI_CLASS]; + cp_elf->e_ident[EI_DATA] = elf.e_ident[EI_DATA]; + cp_elf->e_ident[EI_VERSION] = EV_CURRENT; + cp_elf->e_ident[EI_OSABI] = EI_OSABI; + + /* Rest of the fields */ + cp_elf->e_entry = 0; + cp_elf->e_type = ET_CORE; + cp_elf->e_machine = elf.e_machine; + cp_elf->e_version = EV_CURRENT; + cp_elf->e_phoff = sizeof(Elf_Ehdr); + cp_elf->e_shoff = 0; + cp_elf->e_flags = 0; + cp_elf->e_ehsize = sizeof(Elf_Ehdr); + cp_elf->e_phentsize = sizeof(Elf_Phdr); + + if (cp->phdrs_count > PN_XNUM) { + cp_elf->e_phnum = PN_XNUM; + cp_elf->e_shentsize = sizeof(Elf_Shdr); + cp_elf->e_shnum = 1; + } else { + cp_elf->e_phnum = cp->phdrs_count; + cp_elf->e_shentsize = 0; + cp_elf->e_shnum = 0; + } + + cp_elf->e_shstrndx = SHN_UNDEF; + + return 0; +} + int do_elf_coredump(int pid, struct core_proc *cp) { + int ret; + + /* Fill ELF Header */ + ret = fill_elf_header(pid, cp); + if (ret) + return -1; + return 0; } diff --git a/src/elf32.c b/src/elf32.c index d6b40b4..1a95ff2 100644 --- a/src/elf32.c +++ b/src/elf32.c @@ -30,4 +30,8 @@ #define do_elf_coredump do_elf32_coredump +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Phdr Elf32_Phdr +#define Elf_Shdr Elf32_Shdr + #include "elf.c" diff --git a/src/elf64.c b/src/elf64.c index d8b5e89..953b826 100644 --- a/src/elf64.c +++ b/src/elf64.c @@ -30,4 +30,8 @@ #define do_elf_coredump do_elf64_coredump +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Phdr Elf64_Phdr +#define Elf_Shdr Elf64_Shdr + #include "elf.c" -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html