/*
 * Copyright 2015 Mentor Graphics Corporation.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * vdsomunge - Host program which produces a shared object
 * architecturally specified to be usable by both soft- and hard-float
 * programs.
 *
 * The Procedure Call Standard for the ARM Architecture (ARM IHI
 * 0042E) says:
 *
 *	6.4.1 VFP and Base Standard Compatibility
 *
 *	Code compiled for the VFP calling standard is compatible with
 *	the base standard (and vice-versa) if no floating-point or
 *	containerized vector arguments or results are used.
 *
 * And ELF for the ARM Architecture (ARM IHI 0044E) (Table 4-2) says:
 *
 *	If both EF_ARM_ABI_FLOAT_XXXX bits are clear, conformance to the
 *	base procedure-call standard is implied.
 *
 * The VDSO is built with -msoft-float, as with the rest of the ARM
 * kernel, and uses no floating point arguments or results.  The build
 * process will produce a shared object that may or may not have the
 * EF_ARM_ABI_FLOAT_SOFT flag set (it seems to depend on the binutils
 * version; binutils starting with 2.24 appears to set it).  The
 * EF_ARM_ABI_FLOAT_HARD flag should definitely not be set, and this
 * program will error out if it is.
 *
 * If the soft-float flag is set, this program clears it.  That's all
 * it does.
 */

#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define swab16(x) \
	((((x) & 0x00ff) << 8) | \
	 (((x) & 0xff00) >> 8))

#define swab32(x) \
	((((x) & 0x000000ff) << 24) | \
	 (((x) & 0x0000ff00) <<  8) | \
	 (((x) & 0x00ff0000) >>  8) | \
	 (((x) & 0xff000000) >> 24))

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define HOST_ORDER ELFDATA2LSB
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define HOST_ORDER ELFDATA2MSB
#endif

/* Some of the ELF constants we'd like to use were added to <elf.h>
 * relatively recently.
 */
#ifndef EF_ARM_EABI_VER5
#define EF_ARM_EABI_VER5 0x05000000
#endif

#ifndef EF_ARM_ABI_FLOAT_SOFT
#define EF_ARM_ABI_FLOAT_SOFT 0x200
#endif

#ifndef EF_ARM_ABI_FLOAT_HARD
#define EF_ARM_ABI_FLOAT_HARD 0x400
#endif

static int failed;
static const char *argv0;
static const char *outfile;

static void fail(const char *fmt, ...)
{
	va_list ap;

	failed = 1;
	fprintf(stderr, "%s: ", argv0);
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	exit(EXIT_FAILURE);
}

static void cleanup(void)
{
	if (failed && outfile != NULL)
		unlink(outfile);
}

static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
{
	return swap ? swab32(word) : word;
}

static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
{
	return swap ? swab16(half) : half;
}

static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
{
	*dst = swap ? swab32(val) : val;
}

int main(int argc, char **argv)
{
	const Elf32_Ehdr *inhdr;
	bool clear_soft_float;
	const char *infile;
	Elf32_Word e_flags;
	const void *inbuf;
	struct stat stat;
	void *outbuf;
	bool swap;
	int outfd;
	int infd;

	atexit(cleanup);
	argv0 = argv[0];

	if (argc != 3)
		fail("Usage: %s [infile] [outfile]\n", argv[0]);

	infile = argv[1];
	outfile = argv[2];

	infd = open(infile, O_RDONLY);
	if (infd < 0)
		fail("Cannot open %s: %s\n", infile, strerror(errno));

	if (fstat(infd, &stat) != 0)
		fail("Failed stat for %s: %s\n", infile, strerror(errno));

	inbuf = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, infd, 0);
	if (inbuf == MAP_FAILED)
		fail("Failed to map %s: %s\n", infile, strerror(errno));

	close(infd);

	inhdr = inbuf;

	if (memcmp(&inhdr->e_ident, ELFMAG, SELFMAG) != 0)
		fail("Not an ELF file\n");

	if (inhdr->e_ident[EI_CLASS] != ELFCLASS32)
		fail("Unsupported ELF class\n");

	swap = inhdr->e_ident[EI_DATA] != HOST_ORDER;

	if (read_elf_half(inhdr->e_type, swap) != ET_DYN)
		fail("Not a shared object\n");

	if (read_elf_half(inhdr->e_machine, swap) != EM_ARM)
		fail("Unsupported architecture %#x\n", inhdr->e_machine);

	e_flags = read_elf_word(inhdr->e_flags, swap);

	if (EF_ARM_EABI_VERSION(e_flags) != EF_ARM_EABI_VER5) {
		fail("Unsupported EABI version %#x\n",
		     EF_ARM_EABI_VERSION(e_flags));
	}

	if (e_flags & EF_ARM_ABI_FLOAT_HARD)
		fail("Unexpected hard-float flag set in e_flags\n");

	clear_soft_float = !!(e_flags & EF_ARM_ABI_FLOAT_SOFT);

	outfd = open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
	if (outfd < 0)
		fail("Cannot open %s: %s\n", outfile, strerror(errno));

	if (ftruncate(outfd, stat.st_size) != 0)
		fail("Cannot truncate %s: %s\n", outfile, strerror(errno));

	outbuf = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
		      outfd, 0);
	if (outbuf == MAP_FAILED)
		fail("Failed to map %s: %s\n", outfile, strerror(errno));

	close(outfd);

	memcpy(outbuf, inbuf, stat.st_size);

	if (clear_soft_float) {
		Elf32_Ehdr *outhdr;

		outhdr = outbuf;
		e_flags &= ~EF_ARM_ABI_FLOAT_SOFT;
		write_elf_word(e_flags, &outhdr->e_flags, swap);
	}

	if (msync(outbuf, stat.st_size, MS_SYNC) != 0)
		fail("Failed to sync %s: %s\n", outfile, strerror(errno));

	return EXIT_SUCCESS;
}
