/*
 * 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 accommodate 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_X86_64:
		type =  R_AMD64_64;
		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;
}
