/*
 * elf header parsing.
 *
 * Copyright (C) 2013 Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "elfparsing.h"
#include "common.h"
#include "cbfs.h"

/*
 * Short form: this is complicated, but we've tried making it simple
 * and we keep hitting problems with our ELF parsing.
 *
 * The ELF parsing situation has always been a bit tricky.  In fact,
 * we (and most others) have been getting it wrong in small ways for
 * years. Recently this has caused real trouble for the ARM V8 build.
 * In this file we attempt to finally get it right for all variations
 * of endian-ness and word size and target architectures and
 * architectures we might get run on. Phew!. To do this we borrow a
 * page from the FreeBSD NFS xdr model (see elf_ehdr and elf_phdr),
 * the Plan 9 endianness functions (see xdr.c), and Go interfaces (see
 * how we use buffer structs in this file). This ends up being a bit
 * wordy at the lowest level, but greatly simplifies the elf parsing
 * code and removes a common source of bugs, namely, forgetting to
 * flip type endianness when referencing a struct member.
 *
 * ELF files can have four combinations of data layout: 32/64, and
 * big/little endian.  Further, to add to the fun, depending on the
 * word size, the size of the ELF structs varies. The coreboot SELF
 * format is simpler in theory: it's supposed to be always BE, and the
 * various struct members allow room for growth: the entry point is
 * always 64 bits, for example, so the size of a SELF struct is
 * constant, regardless of target architecture word size.  Hence, we
 * need to do some transformation of the ELF files.
 *
 * A given architecture, realistically, only supports one of the four
 * combinations at a time as the 'native' format. Hence, our code has
 * been sprinkled with every variation of [nh]to[hn][sll] over the
 * years. We've never quite gotten it all right, however, and a quick
 * pass over this code revealed another bug.  It's all worked because,
 * until now, all the working platforms that had CBFS were 32 LE. Even then,
 * however, bugs crept in: we recently realized that we're not
 * transforming the entry point to big format when we store into the
 * SELF image.
 *
 * The problem is essentially an XDR operation:
 * we have something in a foreign format and need to transform it.
 * It's most like XDR because:
 * 1) the byte order can be wrong
 * 2) the word size can be wrong
 * 3) the size of elements in the stream depends on the value
 *    of other elements in the stream
 * it's not like XDR because:
 * 1) the byte order can be right
 * 2) the word size can be right
 * 3) the struct members are all on a natural alignment
 *
 * Hence, this new approach.  To cover word size issues, we *always*
 * transform the two structs we care about, the file header and
 * program header, into a native struct in the 64 bit format:
 *
 * [32,little] -> [Elf64_Ehdr, Elf64_Phdr]
 * [64,little] -> [Elf64_Ehdr, Elf64_Phdr]
 * [32,big] -> [Elf64_Ehdr, Elf64_Phdr]
 * [64,big] -> [Elf64_Ehdr, Elf64_Phdr]
 * Then we just use those structs, and all the need for inline ntoh* goes away,
 * as well as all the chances for error.
 * This works because all the SELF structs have fields large enough for
 * the largest ELF 64 struct members, and all the Elf64 struct members
 * are at least large enough for all ELF 32 struct members.
 * We end up with one function to do all our ELF parsing, and two functions
 * to transform the headers. For the put case, we also have
 * XDR functions, and hopefully we'll never again spend 5 years with the
 * wrong endian-ness on an output value :-)
 * This should work for all word sizes and endianness we hope to target.
 * I *really* don't want to be here for 128 bit addresses.
 *
 * The parse functions are called with a pointer to an input buffer
 * struct. One might ask: are there enough bytes in the input buffer?
 * We know there need to be at *least* sizeof(Elf32_Ehdr) +
 * sizeof(Elf32_Phdr) bytes. Realistically, there has to be some data
 * too.  If we start to worry, though we have not in the past, we
 * might apply the simple test: the input buffer needs to be at least
 * sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) bytes because, even if it's
 * ELF 32, there's got to be *some* data! This is not theoretically
 * accurate but it is actually good enough in practice. It allows the
 * header transformation code to ignore the possibility of underrun.
 *
 * We also must accomodate different ELF files, and hence formats,
 * in the same cbfs invocation. We might load a 64-bit payload
 * on a 32-bit machine; we might even have a mixed armv7/armv8
 * SOC or even a system with an x86/ARM!
 *
 * A possibly problematic (though unlikely to be so) assumption
 * is that we expect the BIOS to remain in the lowest 32 bits
 * of the physical address space. Since ARMV8 has standardized
 * on that, and x86_64 also has, this seems a safe assumption.
 *
 * To repeat, ELF structs are different sizes because ELF struct
 * members are different sizes, depending on values in the ELF file
 * header. For this we use the functions defined in xdr.c, which
 * consume bytes, convert the endianness, and advance the data pointer
 * in the buffer struct.
 */


static int iself(const void *input)
{
	const Elf32_Ehdr *ehdr = input;
	return !memcmp(ehdr->e_ident, ELFMAG, 4);
}

/* Get the ident array, so we can figure out
 * endian-ness, word size, and in future other useful
 * parameters
 */
static void
elf_eident(struct buffer *input, Elf64_Ehdr *ehdr)
{
	bgets(input, ehdr->e_ident, sizeof(ehdr->e_ident));
}


static int
check_size(const struct buffer *b, size_t offset, size_t size, const char *desc)
{
	if (size == 0)
		return 0;

	if (offset >= buffer_size(b) || (offset + size) > buffer_size(b)) {
		ERROR("The file is not large enough for the '%s'. "
		      "%zu bytes @ offset %zu, input %zu bytes.\n",
		      desc, size, offset, buffer_size(b));
		return -1;
	}
	return 0;
}

static void
elf_ehdr(struct buffer *input, Elf64_Ehdr *ehdr, struct xdr *xdr, int bit64)
{
	ehdr->e_type = xdr->get16(input);
	ehdr->e_machine = xdr->get16(input);
	ehdr->e_version = xdr->get32(input);
	if (bit64){
		ehdr->e_entry = xdr->get64(input);
		ehdr->e_phoff = xdr->get64(input);
		ehdr->e_shoff = xdr->get64(input);
	} else {
		ehdr->e_entry = xdr->get32(input);
		ehdr->e_phoff = xdr->get32(input);
		ehdr->e_shoff = xdr->get32(input);
	}
	ehdr->e_flags = xdr->get32(input);
	ehdr->e_ehsize = xdr->get16(input);
	ehdr->e_phentsize = xdr->get16(input);
	ehdr->e_phnum = xdr->get16(input);
	ehdr->e_shentsize = xdr->get16(input);
	ehdr->e_shnum = xdr->get16(input);
	ehdr->e_shstrndx = xdr->get16(input);
}

static void
elf_phdr(struct buffer *pinput, Elf64_Phdr *phdr,
	 int entsize, struct xdr *xdr, int bit64)
{
	/*
	 * The entsize need not be sizeof(*phdr).
	 * Hence, it is easier to keep a copy of the input,
	 * as the xdr functions may not advance the input
	 * pointer the full entsize; rather than get tricky
	 * we just advance it below.
	 */
	struct buffer input;
	buffer_clone(&input, pinput);
	if (bit64){
		phdr->p_type = xdr->get32(&input);
		phdr->p_flags = xdr->get32(&input);
		phdr->p_offset = xdr->get64(&input);
		phdr->p_vaddr = xdr->get64(&input);
		phdr->p_paddr = xdr->get64(&input);
		phdr->p_filesz = xdr->get64(&input);
		phdr->p_memsz = xdr->get64(&input);
		phdr->p_align = xdr->get64(&input);
	} else {
		phdr->p_type = xdr->get32(&input);
		phdr->p_offset = xdr->get32(&input);
		phdr->p_vaddr = xdr->get32(&input);
		phdr->p_paddr = xdr->get32(&input);
		phdr->p_filesz = xdr->get32(&input);
		phdr->p_memsz = xdr->get32(&input);
		phdr->p_flags = xdr->get32(&input);
		phdr->p_align = xdr->get32(&input);
	}
	buffer_seek(pinput, entsize);
}

static void
elf_shdr(struct buffer *pinput, Elf64_Shdr *shdr,
	 int entsize, struct xdr *xdr, int bit64)
{
	/*
	 * The entsize need not be sizeof(*shdr).
	 * Hence, it is easier to keep a copy of the input,
	 * as the xdr functions may not advance the input
	 * pointer the full entsize; rather than get tricky
	 * we just advance it below.
	 */
	struct buffer input = *pinput;
	if (bit64){
		shdr->sh_name = xdr->get32(&input);
		shdr->sh_type = xdr->get32(&input);
		shdr->sh_flags = xdr->get64(&input);
		shdr->sh_addr = xdr->get64(&input);
		shdr->sh_offset = xdr->get64(&input);
		shdr->sh_size= xdr->get64(&input);
		shdr->sh_link = xdr->get32(&input);
		shdr->sh_info = xdr->get32(&input);
		shdr->sh_addralign = xdr->get64(&input);
		shdr->sh_entsize = xdr->get64(&input);
	} else {
		shdr->sh_name = xdr->get32(&input);
		shdr->sh_type = xdr->get32(&input);
		shdr->sh_flags = xdr->get32(&input);
		shdr->sh_addr = xdr->get32(&input);
		shdr->sh_offset = xdr->get32(&input);
		shdr->sh_size = xdr->get32(&input);
		shdr->sh_link = xdr->get32(&input);
		shdr->sh_info = xdr->get32(&input);
		shdr->sh_addralign = xdr->get32(&input);
		shdr->sh_entsize = xdr->get32(&input);
	}
	buffer_seek(pinput, entsize);
}

static int
phdr_read(const struct buffer *in, struct parsed_elf *pelf,
          struct xdr *xdr, int bit64)
{
	struct buffer b;
	Elf64_Phdr *phdr;
	Elf64_Ehdr *ehdr;
	int i;

	ehdr = &pelf->ehdr;
	/* cons up an input buffer for the headers.
	 * Note that the program headers can be anywhere,
	 * per the ELF spec, You'd be surprised how many ELF
	 * readers miss this little detail.
	 */
	buffer_splice(&b, in, ehdr->e_phoff, ehdr->e_phentsize * ehdr->e_phnum);
	if (check_size(in, ehdr->e_phoff, buffer_size(&b), "program headers"))
		return -1;

	/* gather up all the phdrs.
	 * We do them all at once because there is more
	 * than one loop over all the phdrs.
	 */
	phdr = calloc(ehdr->e_phnum, sizeof(*phdr));
	for (i = 0; i < ehdr->e_phnum; i++) {
		DEBUG("Parsing segment %d\n", i);
		elf_phdr(&b, &phdr[i], ehdr->e_phentsize, xdr, bit64);

		/* Ensure the contents are valid within the elf file. */
		if (check_size(in, phdr[i].p_offset, phdr[i].p_filesz,
	                  "segment contents")) {
			free(phdr);
			return -1;
		}
	}

	pelf->phdr = phdr;

	return 0;
}

static int
shdr_read(const struct buffer *in, struct parsed_elf *pelf,
          struct xdr *xdr, int bit64)
{
	struct buffer b;
	Elf64_Shdr *shdr;
	Elf64_Ehdr *ehdr;
	int i;

	ehdr = &pelf->ehdr;

	/* cons up an input buffer for the section headers.
	 * Note that the section headers can be anywhere,
	 * per the ELF spec, You'd be surprised how many ELF
	 * readers miss this little detail.
	 */
	buffer_splice(&b, in, ehdr->e_shoff, ehdr->e_shentsize * ehdr->e_shnum);
	if (check_size(in, ehdr->e_shoff, buffer_size(&b), "section headers"))
		return -1;

	/* gather up all the shdrs. */
	shdr = calloc(ehdr->e_shnum, sizeof(*shdr));
	for (i = 0; i < ehdr->e_shnum; i++) {
		DEBUG("Parsing section %d\n", i);
		elf_shdr(&b, &shdr[i], ehdr->e_shentsize, xdr, bit64);
	}

	pelf->shdr = shdr;

	return 0;
}

static int
reloc_read(const struct buffer *in, struct parsed_elf *pelf,
           struct xdr *xdr, int bit64)
{
	struct buffer b;
	Elf64_Word i;
	Elf64_Ehdr *ehdr;

	ehdr = &pelf->ehdr;
	pelf->relocs = calloc(ehdr->e_shnum, sizeof(Elf64_Rela *));

	/* Allocate array for each section that contains relocation entries. */
	for (i = 0; i < ehdr->e_shnum; i++) {
		Elf64_Shdr *shdr;
		Elf64_Rela *rela;
		Elf64_Xword j;
		Elf64_Xword nrelocs;
		int is_rela;

		shdr = &pelf->shdr[i];

		/* Only process REL and RELA sections. */
		if (shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA)
			continue;

		DEBUG("Checking relocation section %u\n", i);

		/* Ensure the section that relocations apply is a valid. */
		if (shdr->sh_info >= ehdr->e_shnum ||
		    shdr->sh_info == SHN_UNDEF) {
			ERROR("Relocations apply to an invalid section: %u\n",
			      shdr[i].sh_info);
			return -1;
		}

		is_rela = shdr->sh_type == SHT_RELA;

		/* Determine the number relocations in this section. */
		nrelocs = shdr->sh_size / shdr->sh_entsize;

		pelf->relocs[i] = calloc(nrelocs, sizeof(Elf64_Rela));

		buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size);
		if (check_size(in, shdr->sh_offset, buffer_size(&b),
		               "relocation section")) {
			ERROR("Relocation section %u failed.\n", i);
			return -1;
		}

		rela = pelf->relocs[i];
		for (j = 0; j < nrelocs; j++) {
			if (bit64) {
				rela->r_offset = xdr->get64(&b);
				rela->r_info = xdr->get64(&b);
				if (is_rela)
					rela->r_addend = xdr->get64(&b);
			} else {
				uint32_t r_info;

				rela->r_offset = xdr->get32(&b);
				r_info = xdr->get32(&b);
				rela->r_info = ELF64_R_INFO(ELF32_R_SYM(r_info),
				                          ELF32_R_TYPE(r_info));
				if (is_rela)
					rela->r_addend = xdr->get32(&b);
			}
			rela++;
		}
	}

	return 0;
}

static int strtab_read(const struct buffer *in, struct parsed_elf *pelf)
{
	Elf64_Ehdr *ehdr;
	Elf64_Word i;

	ehdr = &pelf->ehdr;

	if (ehdr->e_shstrndx >= ehdr->e_shnum) {
		ERROR("Section header string table index out of range: %d\n",
		      ehdr->e_shstrndx);
		return -1;
	}

	/* For each section of type SHT_STRTAB create a symtab buffer. */
	pelf->strtabs = calloc(ehdr->e_shnum, sizeof(struct buffer *));

	for (i = 0; i < ehdr->e_shnum; i++) {
		struct buffer *b;
		Elf64_Shdr *shdr = &pelf->shdr[i];

		if (shdr->sh_type != SHT_STRTAB)
			continue;

		b = calloc(1, sizeof(*b));
		buffer_splice(b, in, shdr->sh_offset, shdr->sh_size);
		if (check_size(in, shdr->sh_offset, buffer_size(b), "strtab")) {
			ERROR("STRTAB section not within bounds: %d\n", i);
			free(b);
			return -1;
		}
		pelf->strtabs[i] = b;
	}

	return 0;
}

static int
symtab_read(const struct buffer *in, struct parsed_elf *pelf,
            struct xdr *xdr, int bit64)
{
	Elf64_Ehdr *ehdr;
	Elf64_Shdr *shdr;
	Elf64_Half shnum;
	Elf64_Xword i;
	Elf64_Xword nsyms;
	Elf64_Sym *sym;
	struct buffer b;

	ehdr = &pelf->ehdr;

	shdr = NULL;
	for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
		if (pelf->shdr[shnum].sh_type != SHT_SYMTAB)
			continue;

		if (shdr != NULL) {
			ERROR("Multiple symbol sections found. %u and %u\n",
			      (unsigned int)(shdr - pelf->shdr), shnum);
			return -1;
		}

		shdr = &pelf->shdr[shnum];
	}

	if (shdr == NULL) {
		ERROR("No symbol table found.\n");
		return -1;
	}

	buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size);
	if (check_size(in, shdr->sh_offset, buffer_size(&b), "symtab"))
		return -1;

	nsyms = shdr->sh_size / shdr->sh_entsize;

	pelf->syms = calloc(nsyms, sizeof(Elf64_Sym));

	for (i = 0; i < nsyms; i++) {
		sym = &pelf->syms[i];

		if (bit64) {
			sym->st_name = xdr->get32(&b);
			sym->st_info = xdr->get8(&b);
			sym->st_other = xdr->get8(&b);
			sym->st_shndx = xdr->get16(&b);
			sym->st_value = xdr->get64(&b);
			sym->st_size = xdr->get64(&b);
		} else {
			sym->st_name = xdr->get32(&b);
			sym->st_value = xdr->get32(&b);
			sym->st_size = xdr->get32(&b);
			sym->st_info = xdr->get8(&b);
			sym->st_other = xdr->get8(&b);
			sym->st_shndx = xdr->get16(&b);
		}
	}

	return 0;
}

int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags)
{
	struct xdr *xdr = &xdr_le;
	int bit64 = 0;
	struct buffer input;
	Elf64_Ehdr *ehdr;

	/* Zero out the parsed elf structure. */
	memset(pelf, 0, sizeof(*pelf));

	if (!iself(buffer_get(pinput))) {
		DEBUG("The stage file is not in ELF format!\n");
		return -1;
	}

	buffer_clone(&input, pinput);
	ehdr = &pelf->ehdr;
	elf_eident(&input, ehdr);
	bit64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
	/* Assume LE unless we are sure otherwise.
	 * We're not going to take on the task of
	 * fully validating the ELF file. That way
	 * lies madness.
	 */
	if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
		xdr = &xdr_be;

	elf_ehdr(&input, ehdr, xdr, bit64);

	/* Relocation processing requires section header parsing. */
	if (flags & ELF_PARSE_RELOC)
		flags |= ELF_PARSE_SHDR;

	/* String table processing requires section header parsing. */
	if (flags & ELF_PARSE_STRTAB)
		flags |= ELF_PARSE_SHDR;

	/* Symbole table processing requires section header parsing. */
	if (flags & ELF_PARSE_SYMTAB)
		flags |= ELF_PARSE_SHDR;

	if ((flags & ELF_PARSE_PHDR) && phdr_read(pinput, pelf, xdr, bit64))
		goto fail;

	if ((flags & ELF_PARSE_SHDR) && shdr_read(pinput, pelf, xdr, bit64))
		goto fail;

	if ((flags & ELF_PARSE_RELOC) && reloc_read(pinput, pelf, xdr, bit64))
		goto fail;

	if ((flags & ELF_PARSE_STRTAB) && strtab_read(pinput, pelf))
		goto fail;

	if ((flags & ELF_PARSE_SYMTAB) && symtab_read(pinput, pelf, xdr, bit64))
		goto fail;

	return 0;

fail:
	parsed_elf_destroy(pelf);
	return -1;
}

void parsed_elf_destroy(struct parsed_elf *pelf)
{
	Elf64_Half i;

	free(pelf->phdr);
	free(pelf->shdr);
	if (pelf->relocs != NULL) {
		for (i = 0; i < pelf->ehdr.e_shnum; i++)
			free(pelf->relocs[i]);
	}
	free(pelf->relocs);

	if (pelf->strtabs != NULL) {
		for (i = 0; i < pelf->ehdr.e_shnum; i++)
			free(pelf->strtabs[i]);
	}
	free(pelf->strtabs);
	free(pelf->syms);
}

/* Get the headers from the buffer.
 * Return -1 in the event of an error.
 * The section headers are optional; if NULL
 * is passed in for pshdr they won't be parsed.
 * We don't (yet) make payload parsing optional
 * because we've never seen a use case.
 */
int
elf_headers(const struct buffer *pinput,
	    Elf64_Ehdr *ehdr,
	    Elf64_Phdr **pphdr,
	    Elf64_Shdr **pshdr)
{
	struct parsed_elf pelf;
	int flags;

	flags = ELF_PARSE_PHDR;

	if (pshdr != NULL)
		flags |= ELF_PARSE_SHDR;

	if (parse_elf(pinput, &pelf, flags))
		return -1;

	/* Copy out the parsed elf header. */
	memcpy(ehdr, &pelf.ehdr, sizeof(*ehdr));

	*pphdr = calloc(ehdr->e_phnum, sizeof(Elf64_Phdr));
	memcpy(*pphdr, pelf.phdr, ehdr->e_phnum * sizeof(Elf64_Phdr));

	if (pshdr != NULL) {
		*pshdr = calloc(ehdr->e_shnum, sizeof(Elf64_Shdr));
		memcpy(*pshdr, pelf.shdr, ehdr->e_shnum * sizeof(Elf64_Shdr));
	}

	parsed_elf_destroy(&pelf);

	return 0;
}

/* ELF Writing  Support
 *
 * The ELF file is written according to the following layout:
 * +------------------+
 * |    ELF Header    |
 * +------------------+
 * | Section  Headers |
 * +------------------+
 * | Program  Headers |
 * +------------------+
 * |   String table   |
 * +------------------+ <- 4KiB Aligned
 * |     Code/Data    |
 * +------------------+
 */

void elf_init_eheader(Elf64_Ehdr *ehdr, int machine, int nbits, int endian)
{
	memset(ehdr, 0, sizeof(*ehdr));
	ehdr->e_ident[EI_MAG0] = ELFMAG0;
	ehdr->e_ident[EI_MAG1] = ELFMAG1;
	ehdr->e_ident[EI_MAG2] = ELFMAG2;
	ehdr->e_ident[EI_MAG3] = ELFMAG3;
	ehdr->e_ident[EI_CLASS] = nbits;
	ehdr->e_ident[EI_DATA] = endian;
	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
	ehdr->e_type = ET_EXEC;
	ehdr->e_machine = machine;
	ehdr->e_version = EV_CURRENT;
	if (nbits == ELFCLASS64) {
		ehdr->e_ehsize = sizeof(Elf64_Ehdr);
		ehdr->e_phentsize = sizeof(Elf64_Phdr);
		ehdr->e_shentsize = sizeof(Elf64_Shdr);
	} else {
		ehdr->e_ehsize = sizeof(Elf32_Ehdr);
		ehdr->e_phentsize = sizeof(Elf32_Phdr);
		ehdr->e_shentsize = sizeof(Elf32_Shdr);
	}
}

/* Arbitray maximum number of sections. */
#define MAX_SECTIONS 16
struct elf_writer_section {
	Elf64_Shdr shdr;
	struct buffer content;
	const char *name;
};

struct elf_writer_string_table {
	size_t next_offset;
	size_t max_size;
	char *buffer;
};

struct elf_writer_sym_table {
	size_t max_entries;
	size_t num_entries;
	Elf64_Sym *syms;
};

#define MAX_REL_NAME 32
struct elf_writer_rel {
	size_t num_entries;
	size_t max_entries;
	Elf64_Rel *rels;
	struct elf_writer_section *sec;
	char name[MAX_REL_NAME];
};

struct elf_writer
{
	Elf64_Ehdr ehdr;
	struct xdr *xdr;
	size_t num_secs;
	struct elf_writer_section sections[MAX_SECTIONS];
	struct elf_writer_rel rel_sections[MAX_SECTIONS];
	Elf64_Phdr *phdrs;
	struct elf_writer_section *shstrtab_sec;
	struct elf_writer_section *strtab_sec;
	struct elf_writer_section *symtab_sec;
	struct elf_writer_string_table strtab;
	struct elf_writer_sym_table symtab;
	int bit64;
};

static size_t section_index(struct elf_writer *ew,
					struct elf_writer_section *sec)
{
	return sec - &ew->sections[0];
}

static struct elf_writer_section *last_section(struct elf_writer *ew)
{
	return &ew->sections[ew->num_secs - 1];
}

static void strtab_init(struct elf_writer *ew, size_t size)
{
	struct buffer b;
	Elf64_Shdr shdr;

	/* Start adding strings after the initial NUL entry. */
	ew->strtab.next_offset = 1;
	ew->strtab.max_size = size;
	ew->strtab.buffer = calloc(1, ew->strtab.max_size);

	buffer_init(&b, NULL, ew->strtab.buffer, ew->strtab.max_size);
	memset(&shdr, 0, sizeof(shdr));
	shdr.sh_type = SHT_STRTAB;
	shdr.sh_addralign = 1;
	shdr.sh_size = ew->strtab.max_size;
	elf_writer_add_section(ew, &shdr, &b, ".strtab");
	ew->strtab_sec = last_section(ew);
}

static void symtab_init(struct elf_writer *ew, size_t max_entries)
{
	struct buffer b;
	Elf64_Shdr shdr;

	memset(&shdr, 0, sizeof(shdr));
	shdr.sh_type = SHT_SYMTAB;

	if (ew->bit64) {
		shdr.sh_entsize = sizeof(Elf64_Sym);
		shdr.sh_addralign = sizeof(Elf64_Addr);
	} else {
		shdr.sh_entsize = sizeof(Elf32_Sym);
		shdr.sh_addralign = sizeof(Elf32_Addr);
	}

	shdr.sh_size = shdr.sh_entsize * max_entries;

	ew->symtab.syms = calloc(max_entries, sizeof(Elf64_Sym));
	ew->symtab.num_entries = 1;
	ew->symtab.max_entries = max_entries;

	buffer_init(&b, NULL, ew->symtab.syms, shdr.sh_size);

	elf_writer_add_section(ew, &shdr, &b, ".symtab");
	ew->symtab_sec = last_section(ew);
}

struct elf_writer *elf_writer_init(const Elf64_Ehdr *ehdr)
{
	struct elf_writer *ew;
	Elf64_Shdr shdr;
	struct buffer empty_buffer;

	if (!iself(ehdr))
		return NULL;

	ew = calloc(1, sizeof(*ew));

	memcpy(&ew->ehdr, ehdr, sizeof(ew->ehdr));

	ew->bit64 = ew->ehdr.e_ident[EI_CLASS] == ELFCLASS64;

	/* Set the endinan ops. */
	if (ew->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
		ew->xdr = &xdr_be;
	else
		ew->xdr = &xdr_le;

	/* Reset count and offsets */
	ew->ehdr.e_phoff = 0;
	ew->ehdr.e_shoff = 0;
	ew->ehdr.e_shnum = 0;
	ew->ehdr.e_phnum = 0;

	memset(&empty_buffer, 0, sizeof(empty_buffer));
	memset(&shdr, 0, sizeof(shdr));

	/* Add SHT_NULL section header. */
	shdr.sh_type = SHT_NULL;
	elf_writer_add_section(ew, &shdr, &empty_buffer, NULL);

	/* Add section header string table and maintain reference to it.  */
	shdr.sh_type = SHT_STRTAB;
	elf_writer_add_section(ew, &shdr, &empty_buffer, ".shstrtab");
	ew->shstrtab_sec = last_section(ew);
	ew->ehdr.e_shstrndx = section_index(ew, ew->shstrtab_sec);

	/* Add a small string table and symbol table. */
	strtab_init(ew, 4096);
	symtab_init(ew, 100);

	return ew;
}

/*
 * Clean up any internal state represented by ew. Aftewards the elf_writer
 * is invalid.
 * It is safe to call elf_writer_destroy with ew as NULL. It returns without
 * performing any action.
 */
void elf_writer_destroy(struct elf_writer *ew)
{
	int i;
	if (ew == NULL)
		return;
	if (ew->phdrs != NULL)
		free(ew->phdrs);
	free(ew->strtab.buffer);
	free(ew->symtab.syms);
	for (i = 0; i < MAX_SECTIONS; i++)
		free(ew->rel_sections[i].rels);
	free(ew);
}

/*
 * Add a section to the ELF file. Section type, flags, and memsize are
 * maintained from the passed in Elf64_Shdr. The buffer represents the
 * content of the section while the name is the name of section itself.
 * Returns < 0 on error, 0 on success.
 */
int elf_writer_add_section(struct elf_writer *ew, const Elf64_Shdr *shdr,
                           struct buffer *contents, const char *name)
{
	struct elf_writer_section *newsh;

	if (ew->num_secs == MAX_SECTIONS)
		return -1;

	newsh = &ew->sections[ew->num_secs];
	ew->num_secs++;

	memcpy(&newsh->shdr, shdr, sizeof(newsh->shdr));
	newsh->shdr.sh_offset = 0;

	newsh->name = name;
	if (contents != NULL)
		buffer_clone(&newsh->content, contents);

	return 0;
}

static void ehdr_write(struct elf_writer *ew, struct buffer *m)
{
	int i;

	for (i = 0; i < EI_NIDENT; i++)
		ew->xdr->put8(m, ew->ehdr.e_ident[i]);
	ew->xdr->put16(m, ew->ehdr.e_type);
	ew->xdr->put16(m, ew->ehdr.e_machine);
	ew->xdr->put32(m, ew->ehdr.e_version);
	if (ew->bit64) {
		ew->xdr->put64(m, ew->ehdr.e_entry);
		ew->xdr->put64(m, ew->ehdr.e_phoff);
		ew->xdr->put64(m, ew->ehdr.e_shoff);
	} else {
		ew->xdr->put32(m, ew->ehdr.e_entry);
		ew->xdr->put32(m, ew->ehdr.e_phoff);
		ew->xdr->put32(m, ew->ehdr.e_shoff);
	}
	ew->xdr->put32(m, ew->ehdr.e_flags);
	ew->xdr->put16(m, ew->ehdr.e_ehsize);
	ew->xdr->put16(m, ew->ehdr.e_phentsize);
	ew->xdr->put16(m, ew->ehdr.e_phnum);
	ew->xdr->put16(m, ew->ehdr.e_shentsize);
	ew->xdr->put16(m, ew->ehdr.e_shnum);
	ew->xdr->put16(m, ew->ehdr.e_shstrndx);
}

static void shdr_write(struct elf_writer *ew, size_t n, struct buffer *m)
{
	struct xdr *xdr = ew->xdr;
	int bit64 = ew->bit64;
	struct elf_writer_section *sec = &ew->sections[n];
	Elf64_Shdr *shdr = &sec->shdr;

	xdr->put32(m, shdr->sh_name);
	xdr->put32(m, shdr->sh_type);
	if (bit64) {
		xdr->put64(m, shdr->sh_flags);
		xdr->put64(m, shdr->sh_addr);
		xdr->put64(m, shdr->sh_offset);
		xdr->put64(m, shdr->sh_size);
		xdr->put32(m, shdr->sh_link);
		xdr->put32(m, shdr->sh_info);
		xdr->put64(m, shdr->sh_addralign);
		xdr->put64(m, shdr->sh_entsize);
	} else {
		xdr->put32(m, shdr->sh_flags);
		xdr->put32(m, shdr->sh_addr);
		xdr->put32(m, shdr->sh_offset);
		xdr->put32(m, shdr->sh_size);
		xdr->put32(m, shdr->sh_link);
		xdr->put32(m, shdr->sh_info);
		xdr->put32(m, shdr->sh_addralign);
		xdr->put32(m, shdr->sh_entsize);
	}
}

static void
phdr_write(struct elf_writer *ew, struct buffer *m, Elf64_Phdr *phdr)
{
	if (ew->bit64) {
		ew->xdr->put32(m, phdr->p_type);
		ew->xdr->put32(m, phdr->p_flags);
		ew->xdr->put64(m, phdr->p_offset);
		ew->xdr->put64(m, phdr->p_vaddr);
		ew->xdr->put64(m, phdr->p_paddr);
		ew->xdr->put64(m, phdr->p_filesz);
		ew->xdr->put64(m, phdr->p_memsz);
		ew->xdr->put64(m, phdr->p_align);
	} else {
		ew->xdr->put32(m, phdr->p_type);
		ew->xdr->put32(m, phdr->p_offset);
		ew->xdr->put32(m, phdr->p_vaddr);
		ew->xdr->put32(m, phdr->p_paddr);
		ew->xdr->put32(m, phdr->p_filesz);
		ew->xdr->put32(m, phdr->p_memsz);
		ew->xdr->put32(m, phdr->p_flags);
		ew->xdr->put32(m, phdr->p_align);
	}

}

static int section_consecutive(struct elf_writer *ew, Elf64_Half secidx)
{
	Elf64_Half i;
	struct elf_writer_section *prev_alloc = NULL;

	if (secidx == 0)
		return 0;

	for (i = 0; i < secidx; i++) {
		if (ew->sections[i].shdr.sh_flags & SHF_ALLOC)
			prev_alloc = &ew->sections[i];
	}

	if (prev_alloc == NULL)
		return 0;

	if (prev_alloc->shdr.sh_addr + prev_alloc->shdr.sh_size ==
	    ew->sections[secidx].shdr.sh_addr)
		return 1;

	return 0;
}

static void write_phdrs(struct elf_writer *ew, struct buffer *phdrs)
{
	Elf64_Half i;
	Elf64_Phdr phdr;
	size_t num_written = 0;
	size_t num_needs_write = 0;

	for (i = 0; i < ew->num_secs; i++) {
		struct elf_writer_section *sec = &ew->sections[i];

		if (!(sec->shdr.sh_flags & SHF_ALLOC))
			continue;

		if (!section_consecutive(ew, i)) {
			/* Write out previously set phdr. */
			if (num_needs_write != num_written) {
				phdr_write(ew, phdrs, &phdr);
				num_written++;
			}
			phdr.p_type = PT_LOAD;
			phdr.p_offset = sec->shdr.sh_offset;
			phdr.p_vaddr = sec->shdr.sh_addr;
			phdr.p_paddr = sec->shdr.sh_addr;
			phdr.p_filesz = buffer_size(&sec->content);
			phdr.p_memsz = sec->shdr.sh_size;
			phdr.p_flags = 0;
			if (sec->shdr.sh_flags & SHF_EXECINSTR)
				phdr.p_flags |= PF_X | PF_R;
			if (sec->shdr.sh_flags & SHF_WRITE)
				phdr.p_flags |= PF_W;
			phdr.p_align = sec->shdr.sh_addralign;
			num_needs_write++;

		} else {
			/* Accumulate file size and memsize. The assumption
			 * is that each section is either NOBITS or full
			 * (sh_size == file size). This is standard in that
			 * an ELF section doesn't have a file size component. */
			if (sec->shdr.sh_flags & SHF_EXECINSTR)
				phdr.p_flags |= PF_X | PF_R;
			if (sec->shdr.sh_flags & SHF_WRITE)
				phdr.p_flags |= PF_W;
			phdr.p_filesz += buffer_size(&sec->content);
			phdr.p_memsz += sec->shdr.sh_size;
		}
	}

	/* Write out the last phdr. */
	if (num_needs_write != num_written) {
		phdr_write(ew, phdrs, &phdr);
		num_written++;
	}
	assert(num_written == ew->ehdr.e_phnum);
}

static void fixup_symbol_table(struct elf_writer *ew)
{
	struct elf_writer_section *sec = ew->symtab_sec;

	/* If there is only the NULL section, mark section as inactive. */
	if (ew->symtab.num_entries == 1) {
		sec->shdr.sh_type = SHT_NULL;
		sec->shdr.sh_size = 0;
	} else {
		size_t i;
		struct buffer wr;

		buffer_clone(&wr, &sec->content);
		/* To appease xdr. */
		buffer_set_size(&wr, 0);
		for (i = 0; i < ew->symtab.num_entries; i++) {
			/* Create local copy as were over-writing backing
			 * store of the symbol. */
			Elf64_Sym sym = ew->symtab.syms[i];
			if (ew->bit64) {
				ew->xdr->put32(&wr, sym.st_name);
				ew->xdr->put8(&wr, sym.st_info);
				ew->xdr->put8(&wr, sym.st_other);
				ew->xdr->put16(&wr, sym.st_shndx);
				ew->xdr->put64(&wr, sym.st_value);
				ew->xdr->put64(&wr, sym.st_size);
			} else {
				ew->xdr->put32(&wr, sym.st_name);
				ew->xdr->put32(&wr, sym.st_value);
				ew->xdr->put32(&wr, sym.st_size);
				ew->xdr->put8(&wr, sym.st_info);
				ew->xdr->put8(&wr, sym.st_other);
				ew->xdr->put16(&wr, sym.st_shndx);
			}
		}

		/* Update section size. */
		sec->shdr.sh_size = sec->shdr.sh_entsize;
		sec->shdr.sh_size *= ew->symtab.num_entries;

		/* Fix up sh_link to point to string table. */
		sec->shdr.sh_link = section_index(ew, ew->strtab_sec);
		/* sh_info is supposed to be 1 greater than symbol table
		 * index of last local binding. Just use max symbols. */
		sec->shdr.sh_info = ew->symtab.num_entries;
	}

	buffer_set_size(&sec->content, sec->shdr.sh_size);
}

static void fixup_relocations(struct elf_writer *ew)
{
	int i;
	Elf64_Xword type;

	switch (ew->ehdr.e_machine) {
	case EM_386:
		type = R_386_32;
		break;
	case EM_ARM:
		type = R_ARM_ABS32;
		break;
	case EM_AARCH64:
		type = R_AARCH64_ABS64;
		break;
	case EM_MIPS:
		type = R_MIPS_32;
		break;
	case EM_RISCV:
		type = R_RISCV_32;
		break;
	case EM_PPC64:
		type = R_PPC64_ADDR32;
		break;
	default:
		ERROR("Unable to handle relocations for e_machine %x\n",
			ew->ehdr.e_machine);
		return;
	}

	for (i = 0; i < MAX_SECTIONS; i++) {
		struct elf_writer_rel *rel_sec = &ew->rel_sections[i];
		struct elf_writer_section *sec = rel_sec->sec;
		struct buffer writer;
		size_t j;

		if (sec == NULL)
			continue;

		/* Update section header size as well as content size. */
		buffer_init(&sec->content, sec->content.name, rel_sec->rels,
				rel_sec->num_entries * sec->shdr.sh_entsize);
		sec->shdr.sh_size = buffer_size(&sec->content);
		buffer_clone(&writer, &sec->content);
		/* To make xdr happy. */
		buffer_set_size(&writer, 0);

		for (j = 0; j < ew->rel_sections[i].num_entries; j++) {
			/* Make copy as we're overwriting backing store. */
			Elf64_Rel rel = rel_sec->rels[j];
			rel.r_info = ELF64_R_INFO(ELF64_R_SYM(rel.r_info),
						  ELF64_R_TYPE(type));

			if (ew->bit64) {
				ew->xdr->put64(&writer, rel.r_offset);
				ew->xdr->put64(&writer, rel.r_info);
			} else {
				Elf32_Rel rel32;
				rel32.r_offset = rel.r_offset;
				rel32.r_info =
					ELF32_R_INFO(ELF64_R_SYM(rel.r_info),
						     ELF64_R_TYPE(rel.r_info));
				ew->xdr->put32(&writer, rel32.r_offset);
				ew->xdr->put32(&writer, rel32.r_info);
			}
		}
	}
}

/*
 * Serialize the ELF file to the output buffer. Return < 0 on error,
 * 0 on success.
 */
int elf_writer_serialize(struct elf_writer *ew, struct buffer *out)
{
	Elf64_Half i;
	Elf64_Xword metadata_size;
	Elf64_Xword program_size;
	Elf64_Off shstroffset;
	size_t shstrlen;
	struct buffer metadata;
	struct buffer phdrs;
	struct buffer data;
	struct buffer *strtab;

	INFO("Writing %zu sections.\n", ew->num_secs);

	/* Perform any necessary work for special sections. */
	fixup_symbol_table(ew);
	fixup_relocations(ew);

	/* Determine size of sections to be written. */
	program_size = 0;
	/* Start with 1 byte for first byte of section header string table. */
	shstrlen = 1;
	for (i = 0; i < ew->num_secs; i++) {
		struct elf_writer_section *sec = &ew->sections[i];

		if (sec->shdr.sh_flags & SHF_ALLOC) {
			if (!section_consecutive(ew, i))
				ew->ehdr.e_phnum++;
		}

		program_size += buffer_size(&sec->content);

		/* Keep track of the length sections' names. */
		if (sec->name != NULL) {
			sec->shdr.sh_name = shstrlen;
			shstrlen += strlen(sec->name) + 1;
		}
	}
	ew->ehdr.e_shnum = ew->num_secs;
	metadata_size = 0;
	metadata_size += ew->ehdr.e_ehsize;
	metadata_size += ew->ehdr.e_shnum * ew->ehdr.e_shentsize;
	metadata_size += ew->ehdr.e_phnum * ew->ehdr.e_phentsize;
	shstroffset = metadata_size;
	/* Align up section header string size and metadata size to 4KiB */
	metadata_size = ALIGN(metadata_size + shstrlen, 4096);

	if (buffer_create(out, metadata_size + program_size, "elfout")) {
		ERROR("Could not create output buffer for ELF.\n");
		return -1;
	}

	INFO("Created %zu output buffer for ELF file.\n", buffer_size(out));

	/*
	 * Write out ELF header. Section headers come right after ELF header
	 * followed by the program headers. Buffers need to be created first
	 * to do the writing.
	 */
	ew->ehdr.e_shoff = ew->ehdr.e_ehsize;
	ew->ehdr.e_phoff = ew->ehdr.e_shoff +
	                   ew->ehdr.e_shnum * ew->ehdr.e_shentsize;

	buffer_splice(&metadata, out, 0, metadata_size);
	buffer_splice(&phdrs, out, ew->ehdr.e_phoff,
	              ew->ehdr.e_phnum * ew->ehdr.e_phentsize);
	buffer_splice(&data, out, metadata_size, program_size);
	/* Set up the section header string table contents. */
	strtab = &ew->shstrtab_sec->content;
	buffer_splice(strtab, out, shstroffset, shstrlen);
	ew->shstrtab_sec->shdr.sh_size = shstrlen;

	/* Reset current locations. */
	buffer_set_size(&metadata, 0);
	buffer_set_size(&data, 0);
	buffer_set_size(&phdrs, 0);
	buffer_set_size(strtab, 0);

	/* ELF Header */
	ehdr_write(ew, &metadata);

	/* Write out section headers, section strings, section content, and
	 * program headers. */
	ew->xdr->put8(strtab, 0);
	for (i = 0; i < ew->num_secs; i++) {
		struct elf_writer_section *sec = &ew->sections[i];

		/* Update section offsets. Be sure to not update SHN_UNDEF. */
		if (sec == ew->shstrtab_sec)
			sec->shdr.sh_offset = shstroffset;
		else if (i != SHN_UNDEF)
			sec->shdr.sh_offset = buffer_size(&data) +
			                      metadata_size;

		shdr_write(ew, i, &metadata);

		/* Add section name to string table. */
		if (sec->name != NULL)
			bputs(strtab, sec->name, strlen(sec->name) + 1);

		/* Output section data for all sections but SHN_UNDEF and
		 * section header string table. */
		if (i != SHN_UNDEF && sec != ew->shstrtab_sec)
			bputs(&data, buffer_get(&sec->content),
			      buffer_size(&sec->content));
	}

	write_phdrs(ew, &phdrs);

	return 0;
}

/* Add a string to the string table returning index on success, < 0 on error. */
static int elf_writer_add_string(struct elf_writer *ew, const char *new)
{
	size_t current_offset;
	size_t new_len;

	for (current_offset = 0; current_offset < ew->strtab.next_offset; ) {
		const char *str = ew->strtab.buffer + current_offset;
		size_t len = strlen(str) + 1;

		if (!strcmp(str, new))
			return current_offset;
		current_offset += len;
	}

	new_len = strlen(new) + 1;

	if (current_offset + new_len > ew->strtab.max_size) {
		ERROR("No space for string in .strtab.\n");
		return -1;
	}

	memcpy(ew->strtab.buffer + current_offset, new, new_len);
	ew->strtab.next_offset = current_offset + new_len;

	return current_offset;
}

static int elf_writer_section_index(struct elf_writer *ew, const char *name)
{
	size_t i;

	for (i = 0; i < ew->num_secs; i++) {
		if (ew->sections[i].name == NULL)
			continue;
		if (!strcmp(ew->sections[i].name, name))
			return i;
	}

	ERROR("ELF Section not found: %s\n", name);

	return -1;
}

int elf_writer_add_symbol(struct elf_writer *ew, const char *name,
				const char *section_name,
				Elf64_Addr value, Elf64_Word size,
				int binding, int type)
{
	int i;
	Elf64_Sym sym = {
		.st_value = value,
		.st_size = size,
		.st_info = ELF64_ST_INFO(binding, type),
	};

	if (ew->symtab.max_entries == ew->symtab.num_entries) {
		ERROR("No more symbol entries left.\n");
		return -1;
	}

	i = elf_writer_add_string(ew, name);
	if (i < 0)
		return -1;
	sym.st_name = i;

	i = elf_writer_section_index(ew, section_name);
	if (i < 0)
		return -1;
	sym.st_shndx = i;

	ew->symtab.syms[ew->symtab.num_entries++] = sym;

	return 0;
}

static int elf_sym_index(struct elf_writer *ew, const char *sym)
{
	int j;
	size_t i;
	Elf64_Word st_name;

	/* Determine index of symbol in the string table. */
	j = elf_writer_add_string(ew, sym);
	if (j < 0)
		return -1;

	st_name = j;

	for (i = 0; i < ew->symtab.num_entries; i++)
		if (ew->symtab.syms[i].st_name == st_name)
			return i;

	return -1;
}

static struct elf_writer_rel *rel_section(struct elf_writer *ew,
						const Elf64_Rel *r)
{
	Elf64_Sym *sym;
	struct elf_writer_rel *rel;
	Elf64_Shdr shdr;
	struct buffer b;

	sym = &ew->symtab.syms[ELF64_R_SYM(r->r_info)];

	/* Determine if section has been initialized yet. */
	rel = &ew->rel_sections[sym->st_shndx];
	if (rel->sec != NULL)
		return rel;

	memset(&shdr, 0, sizeof(shdr));
	shdr.sh_type = SHT_REL;
	shdr.sh_link = section_index(ew, ew->symtab_sec);
	shdr.sh_info = sym->st_shndx;

	if (ew->bit64) {
		shdr.sh_addralign = sizeof(Elf64_Addr);
		shdr.sh_entsize = sizeof(Elf64_Rel);
	} else {
		shdr.sh_addralign = sizeof(Elf32_Addr);
		shdr.sh_entsize = sizeof(Elf32_Rel);
	}

	if ((strlen(".rel") + strlen(ew->sections[sym->st_shndx].name) + 1) >
	    MAX_REL_NAME) {
		ERROR("Rel Section name won't fit\n");
		return NULL;
	}

	strcat(rel->name, ".rel");
	strcat(rel->name, ew->sections[sym->st_shndx].name);
	buffer_init(&b, rel->name, NULL, 0);

	elf_writer_add_section(ew, &shdr, &b, rel->name);
	rel->sec = last_section(ew);

	return rel;
}

static int add_rel(struct elf_writer_rel *rel_sec, const Elf64_Rel *rel)
{
	if (rel_sec->num_entries == rel_sec->max_entries) {
		size_t num = rel_sec->max_entries * 2;
		Elf64_Rel *old_rels;

		if (num == 0)
			num = 128;

		old_rels = rel_sec->rels;
		rel_sec->rels = calloc(num, sizeof(Elf64_Rel));

		memcpy(rel_sec->rels, old_rels,
			rel_sec->num_entries * sizeof(Elf64_Rel));
		free(old_rels);

		rel_sec->max_entries = num;
	}

	rel_sec->rels[rel_sec->num_entries] = *rel;
	rel_sec->num_entries++;

	return 0;
}

int elf_writer_add_rel(struct elf_writer *ew, const char *sym, Elf64_Addr addr)
{
	Elf64_Rel rel;
	Elf64_Xword sym_info;
	int sym_index;
	struct elf_writer_rel *rel_sec;

	sym_index = elf_sym_index(ew, sym);

	if (sym_index < 0) {
		ERROR("Unable to locate symbol: %s\n", sym);
		return -1;
	}

	sym_info = sym_index;

	/* The relocation type will get fixed prior to serialization. */
	rel.r_offset = addr;
	rel.r_info = ELF64_R_INFO(sym_info, 0);

	rel_sec = rel_section(ew, &rel);

	if (rel_sec == NULL)
		return -1;

	return add_rel(rel_sec, &rel);
}

int elf_program_file_size(const struct buffer *input, size_t *file_size)
{
	Elf64_Ehdr ehdr;
	Elf64_Phdr *phdr;
	int i;
	size_t loadable_file_size = 0;

	if (elf_headers(input, &ehdr, &phdr, NULL))
		return -1;

	for (i = 0; i < ehdr.e_phnum; i++) {
		if (phdr[i].p_type != PT_LOAD)
			continue;
		loadable_file_size += phdr[i].p_filesz;
	}

	*file_size = loadable_file_size;

	free(phdr);

	return 0;
}
