[PATCH 08/33] Fills elf header

Janani Venkataraman
2014-03-20T09:40:09Z

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@linux.vnet.ibm.com>
---
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@in.ibm.com>
*/

+#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"