/*
 * Copyright (c) 2010-2014 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file
 * @brief generate offset definition header file
 *
 * genOffsetHeader -i <objectModule> -o <outputHeaderName>
 *
 * This Zephyr development host utility will process an ELF object module that
 * consists of a series of absolute symbols representing the byte offset of a
 * structure member and the size of the structure.  Each absolute symbol will
 * be translated into a C preprocessor '#define' directive.  For example,
 * assuming that the module offsets.o contains the following absolute symbols:
 *
 *   $ nm offsets.o
 *   00000010 A __tNANO_common_isp_OFFSET
 *   00000008 A __tNANO_current_OFFSET
 *   0000000c A __tNANO_nested_OFFSET
 *   00000000 A __tNANO_fiber_OFFSET
 *   00000004 A __tNANO_task_OFFSET
 *
 * ... the following C preprocessor code will be generated:
 *
 *   #define   __tNANO_common_isp_OFFSET  0x10
 *   #define   __tNANO_current_OFFSET     0x8
 *   #define   __tNANO_nested_OFFSET      0xC
 *   #define   __tNANO_fiber_OFFSET       0x0
 *   #define   __tNANO_task_OFFSET        0x4
 */

/* includes */

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "elf.h"
#include <stdlib.h>		/* for malloc()/free()/exit() */
#include <string.h>		/* for strstr() */
#include <getopt.h>
#include <errno.h>

/* defines */

#undef DEBUG

/* the symbol name suffix used to denote structure member offsets */

#define STRUCT_OFF_SUFFIX "_OFFSET"
#define STRUCT_SIZ_SUFFIX "_SIZEOF"

#ifdef DEBUG
#define DBG_PRINT(args...) printf(args)
#else
#define DBG_PRINT(args...)
#endif


/* byte swapping macros */

#define SWAB_Elf32_Half(x)	((x >> 8) | (x << 8))
#define SWAB_Elf32_Word(x)	(((x >> 24) & 0xff) |		\
				((x << 8)  & 0xff0000) |	\
		                ((x >> 8)  & 0xff00) |		\
	                        ((x << 24) & 0xff000000))

#define SWAB_Elf32_Addr	  SWAB_Elf32_Word
#define SWAB_Elf32_Off    SWAB_Elf32_Word
#define SWAB_Elf32_Sword  SWAB_Elf32_Word

#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__WIN32__)
  #define OPEN_FLAGS (O_RDONLY|O_BINARY)
#else
  #define OPEN_FLAGS (O_RDONLY)
#endif

/* locals */

/* global indicating whether ELF structures need to be byte swapped */

static char swabRequired;


/* usage information */

static char usage[] = "usage: %s -i <objectModule> -o <outputHeaderName>\n";


/* output header file preamble */

static char preamble1[] = "\
/* %s - structure member offsets definition header */\n\
\n\
/*\n\
 * Copyright (c) 2010-2014 Wind River Systems, Inc.\n\
 *\n\
 * Licensed under the Apache License, Version 2.0 (the \"License\");\n\
 * you may not use this file except in compliance with the License.\n\
 * You may obtain a copy of the License at\n\
 *\n\
 *     http://www.apache.org/licenses/LICENSE-2.0\n\
 *\n\
 * Unless required by applicable law or agreed to in writing, software\n\
 * distributed under the License is distributed on an \"AS IS\" BASIS,\n\
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\
 * See the License for the specific language governing permissions and\n\
 * limitations under the License.\n\
 */\n\
\n\
/* THIS FILE IS AUTO GENERATED.  PLEASE DO NOT EDIT */\n\
\n\
/*\n\
 * This header file provides macros for the offsets of various structure\n\
 * members.  These offset macros are primarily intended to be used in\n\
 * assembly code.\n\
 */\n\n";

static char preamble2[] = "\
/*\n\
 * Auto-generated header guard.\n\
 */\n\
#ifndef %s\n\
#define %s\n\
 \n\
#ifdef __cplusplus\n\
extern \"C\" {\n\
#endif\n\
\n\
/* defines */\n\n";


/* output header file postscript */

static char postscript[] = "\
\n\
#ifdef __cplusplus\n\
}\n\
#endif\n\
\n\
#endif /* _HGUARD_ */\n";

static Elf32_Ehdr	ehdr;    /* ELF header */
static Elf32_Shdr *	shdr;    /* pointer to array ELF section headers */

/**
 * @brief byte swap the Elf32_Ehdr structure
 *
 * @returns N/A
 */
static void swabElfHdr(Elf32_Ehdr *pHdrToSwab)
{
	if (swabRequired == 0)
	{
		return;  /* do nothing */
	}

	pHdrToSwab->e_type		= SWAB_Elf32_Half(pHdrToSwab->e_type);
	pHdrToSwab->e_machine	= SWAB_Elf32_Half(pHdrToSwab->e_machine);
	pHdrToSwab->e_version	= SWAB_Elf32_Word(pHdrToSwab->e_version);
	pHdrToSwab->e_entry		= SWAB_Elf32_Addr(pHdrToSwab->e_entry);
	pHdrToSwab->e_phoff		= SWAB_Elf32_Off(pHdrToSwab->e_phoff);
	pHdrToSwab->e_shoff		= SWAB_Elf32_Off(pHdrToSwab->e_shoff);
	pHdrToSwab->e_flags		= SWAB_Elf32_Word(pHdrToSwab->e_flags);
	pHdrToSwab->e_ehsize	= SWAB_Elf32_Half(pHdrToSwab->e_ehsize);
	pHdrToSwab->e_phentsize	= SWAB_Elf32_Half(pHdrToSwab->e_phentsize);
	pHdrToSwab->e_phnum		= SWAB_Elf32_Half(pHdrToSwab->e_phnum);
	pHdrToSwab->e_shentsize	= SWAB_Elf32_Half(pHdrToSwab->e_shentsize);
	pHdrToSwab->e_shnum		= SWAB_Elf32_Half(pHdrToSwab->e_shnum);
	pHdrToSwab->e_shstrndx	= SWAB_Elf32_Half(pHdrToSwab->e_shstrndx);
}

/**
 * @brief byte swap the Elf32_Shdr structure
 *
 * @returns N/A
 */
static void swabElfSectionHdr(Elf32_Shdr *pHdrToSwab)
{
	if (swabRequired == 0)
	{
		return;  /* do nothing */
	}

	pHdrToSwab->sh_name		= SWAB_Elf32_Word(pHdrToSwab->sh_name);
	pHdrToSwab->sh_type		= SWAB_Elf32_Word(pHdrToSwab->sh_type);
	pHdrToSwab->sh_flags	= SWAB_Elf32_Word(pHdrToSwab->sh_flags);
	pHdrToSwab->sh_addr		= SWAB_Elf32_Addr(pHdrToSwab->sh_addr);
	pHdrToSwab->sh_offset	= SWAB_Elf32_Off(pHdrToSwab->sh_offset);
	pHdrToSwab->sh_size		= SWAB_Elf32_Word(pHdrToSwab->sh_size);
	pHdrToSwab->sh_link		= SWAB_Elf32_Word(pHdrToSwab->sh_link);
	pHdrToSwab->sh_info		= SWAB_Elf32_Word(pHdrToSwab->sh_info);
	pHdrToSwab->sh_addralign	= SWAB_Elf32_Word(pHdrToSwab->sh_addralign);
	pHdrToSwab->sh_addralign	= SWAB_Elf32_Word(pHdrToSwab->sh_addralign);
}


/**
 *
 * @brief byte swap the Elf32_Sym structure
 *
 * @returns N/A
 */
static void swabElfSym(Elf32_Sym *pHdrToSwab)
{
	if (swabRequired == 0)
	{
		return;  /* do nothing */
	}

	pHdrToSwab->st_name		= SWAB_Elf32_Word(pHdrToSwab->st_name);
	pHdrToSwab->st_value	= SWAB_Elf32_Addr(pHdrToSwab->st_value);
	pHdrToSwab->st_size		= SWAB_Elf32_Word(pHdrToSwab->st_size);
	pHdrToSwab->st_shndx	= SWAB_Elf32_Half(pHdrToSwab->st_shndx);
}

/**
 * @brief load the ELF header
 *
 * @param fd file descriptor of file from which to read
 * @returns 0 on success, -1 on failure
 */
static int ehdrLoad(int fd)
{
	unsigned  ix = 0x12345678;  /* used to auto-detect endian-ness */
	size_t    nBytes;           /* number of bytes read from file */

	if (lseek(fd, 0, SEEK_SET) == -1) {
		fprintf(stderr, "Unable to seek\n");
		return -1;
	}

	nBytes = read(fd, &ehdr, sizeof(ehdr));
	if (nBytes != sizeof(ehdr))
	{
		fprintf(stderr, "Failed to read ELF header\n");
		return -1;
	}

	/* perform some rudimentary ELF file validation */

	if (strncmp((char *)ehdr.e_ident, ELFMAG, 4) != 0)
	{
		fprintf(stderr, "Input object module not ELF format\n");
		return -1;
	}

	/* 64-bit ELF module not supported (for now) */

	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
	{
		fprintf(stderr, "ELF64 class not supported\n");
		return -1;
	}

	/*
	 * Dynamically determine the endianess of the host (in the absence of
	 * a compile time macro ala _BYTE_ORDER).  The ELF structures will require
	 * byte swapping if the host and target have different byte ordering.
	 */

	if (((*(char*)&ix == 0x78) && (ehdr.e_ident[EI_DATA] == ELFDATA2MSB)) ||
			((*(char*)&ix == 0x12) && (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)))
	{
		swabRequired = 1;
		DBG_PRINT("Swab required\n");
	}

	swabElfHdr(&ehdr);   /* swap bytes (if required) */

	/* debugging: dump some important ELF header fields */

	DBG_PRINT("Elf header Magic = %s\n", ehdr.e_ident);
	DBG_PRINT("Elf header e_type = %d\n", ehdr.e_type);
	DBG_PRINT("Elf header e_shstrndx = %d\n", ehdr.e_shstrndx);
	DBG_PRINT("Elf header e_shnum = %d\n", ehdr.e_shnum);

	return 0;
}

/**
 * @brief load the section headers
 * @param fd file descriptor of file from which to read
 *
 * @returns 0 on success, -1 on failure
 */
static int shdrsLoad(int fd)
{
	size_t    nBytes;    /* number of bytes read from file */
	unsigned  ix;        /* loop index */

	shdr = malloc(ehdr.e_shnum * sizeof(Elf32_Shdr));
	if (shdr == NULL)
	{
		fprintf(stderr, "No memory for section headers!\n");
		return -1;
	}

	/* Seek to the start of the table of section headers */
	if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1) {
		fprintf(stderr, "Unable to seek\n");
		return -1;
	}

	for (ix = 0; ix < ehdr.e_shnum; ix++)
	{
		nBytes = read(fd, &shdr[ix], sizeof(Elf32_Shdr));
		if (nBytes != sizeof(Elf32_Shdr))
		{
			fprintf(stderr, "Unable to read entire section header (#%d)\n",
					ix);
			return -1;
		}

		swabElfSectionHdr(&shdr[ix]);   /* swap bytes (if required) */
	}

	return 0;
}

/**
 *
 * symTblFind - search the section headers for the symbol table
 *
 * This routine searches the section headers for the symbol table.  There is
 * expected to be only one symbol table in the section headers.
 *
 * @param pSymTblOffset ptr to symbol table offset
 * @param pSymTblSize ptr to symbol table size
 * @returns 0 if found, -1 if not
 */
static int symTblFind(unsigned *pSymTblOffset, unsigned *pSymTblSize)
{
	unsigned  ix;    /* loop index */

	for (ix = 0; ix < ehdr.e_shnum; ++ix)
	{
		if (shdr[ix].sh_type == SHT_SYMTAB)
		{
			*pSymTblOffset = shdr[ix].sh_offset;
			*pSymTblSize   = shdr[ix].sh_size;

			return 0;
		}
	}

	fprintf(stderr, "Object module missing symbol table!\n");

	return -1;
}

/**
 *
 * @brief search the section headers for the string table
 *
 * This routine searches the section headers for the string table associated
 * with the symbol names.
 *
 * Typically, there are two string tables defined in the section headers.  These
 * are ".shstrtbl" and ".strtbl" for section header names and symbol names
 * respectively.  It has been observed with the DIAB compiler (but not with
 * either the GCC nor ICC compilers) that the two tables may be mashed together
 * into one.  Consequently, the following algorithm is used to select the
 * appropriate string table.
 *
 * 1. Assume that the first found string table is valid.
 * 2. If another string table is found, use that only if its section header
 *    index does not match the index for ".shstrtbl" stored in the ELF header.
 *
 * @param pStrTblIx ptr to string table's index
 * @returns 0 if found, -1 if not
 */
static int strTblFind(unsigned *pStrTblIx)
{
	unsigned  strTblIx = 0xffffffff;
	unsigned  ix;

	for (ix = 0; ix < ehdr.e_shnum; ++ix)
	{
		if (shdr[ix].sh_type == SHT_STRTAB)
		{
			if ((strTblIx == 0xffffffff) ||
					(ix != ehdr.e_shstrndx))
			{
				strTblIx = ix;
			}
		}
	}

	if (strTblIx == 0xffffffff)
	{
		fprintf(stderr, "Object module missing string table!\n");
		return -1;
	}

	*pStrTblIx = strTblIx;

	return 0;
}

/**
 * @brief load the string table
 *
 * @param fd file descriptor of file from which to read
 * @param strTblIx string table's index
 * @param ppStringTable ptr to ptr to string table
 * @returns 0 on success, -1 on failure
 */
static int strTblLoad(int fd, unsigned strTblIx, char **ppStringTable)
{
	char *  pTable;
	int     nBytes;

	DBG_PRINT("Allocating %d bytes for string table\n",
			shdr[strTblIx].sh_size);

	pTable = malloc(shdr[strTblIx].sh_size);
	if (pTable == NULL)
	{
		fprintf(stderr, "No memory for string table!");
		return -1;
	}

	if (lseek(fd, shdr[strTblIx].sh_offset, SEEK_SET) == -1) {
		free(pTable);
		fprintf(stderr, "Unable to seek\n");
		return -1;
	}

	nBytes = read(fd, pTable, shdr[strTblIx].sh_size);
	if (nBytes != shdr[strTblIx].sh_size)
	{
		free(pTable);
		fprintf(stderr, "Unable to read entire string table!\n");
		return -1;
	}

	*ppStringTable = pTable;

	return 0;
}

/**
 *
 * @brief dump the header preamble to the header file
 *
 * @param fd file pointer to which to write
 * @parama filename name of the output file
 * @returns N/A
 */
static void headerPreambleDump(FILE *fp, char *filename)
{
	unsigned hash = 5381;      /* hash value */
	size_t   ix;               /* loop counter */
	char     fileNameHash[20]; /* '_HGUARD_' + 8 character hash + '\0' */

	/* dump header file preamble1[] */

	fprintf(fp, preamble1, filename, filename, filename);

	/*
	 * Dump header file preamble2[]. Hash file name into something that
	 * is small enough to be a C macro name and does not have invalid
	 * characters for a macro name to use as a header guard. The result
	 * of the hash should be unique enough for our purposes.
	 */

	for (ix = 0; ix < sizeof(filename); ++ix)
	{
		hash = (hash * 33) + (unsigned int) filename[ix];
	}

	sprintf(fileNameHash, "_HGUARD_%08x", hash);
	fprintf(fp, preamble2, fileNameHash, fileNameHash);
}

/**
 * @brief dump the absolute symbols to the header file
 *
 * @param fd file descriptor of file from which to read
 * @param fp file pointer to which to write
 * @param symTblOffset symbol table offset
 * @param symTblSize size of the symbol table
 * @param pStringTable ptr to the string table
 * @returns N/A
 */
static void headerAbsoluteSymbolsDump(int fd, FILE *fp, Elf32_Off symTblOffset,
		Elf32_Word symTblSize, char *pStringTable)
{
	Elf32_Sym  aSym;     /* absolute symbol */
	unsigned   ix;       /* loop counter */
	unsigned   numSyms;  /* number of symbols in the symbol table */
	size_t	   nBytes;

	/* context the symbol table: pick out absolute syms */

	numSyms = symTblSize / sizeof(Elf32_Sym);
	if (lseek(fd, symTblOffset, SEEK_SET) == -1) {
		fprintf(stderr, "Unable to seek\n");
		return;
	}

	for (ix = 0; ix < numSyms; ++ix)
	{
		/* read in a single symbol structure */
		nBytes = read(fd, &aSym, sizeof(Elf32_Sym));

		if (nBytes) {
			swabElfSym(&aSym);    /* swap bytes (if required) */
		}

		/*
		 * Only generate definitions for global absolute symbols
		 * of the form *_OFFSET
		 */

		if ((aSym.st_shndx == SHN_ABS) &&
				(ELF_ST_BIND(aSym.st_info) == STB_GLOBAL))
		{
			if ((strstr(&pStringTable[aSym.st_name],
							STRUCT_OFF_SUFFIX) != NULL) ||
					(strstr(&pStringTable[aSym.st_name],
						 STRUCT_SIZ_SUFFIX) != NULL))
			{
				fprintf(fp, "#define\t%s\t0x%X\n",
						&pStringTable[aSym.st_name], aSym.st_value);
			}
		}
	}
}

/**
 *
 * @brief dump the header postscript to the header file
 * @param fp file pointer to which to write
 * @returns N/A
 */
static void headerPostscriptDump(FILE *fp)
{
	fputs(postscript, fp);
}

/**
 * @brief entry point for the genOffsetHeader utility
 *
 * usage: $ genOffsetHeader -i <objectModule> -o <outputHeaderName>
 *
 * @returns 0 on success, 1 on failure
 */
int main(int argc, char *argv[])
{
	Elf32_Off	symTblOffset = 0;
	Elf32_Word	symTblSize;		/* in bytes */
	char *	pStringTable = NULL;
	char *	inFileName = NULL;
	char *	outFileName = NULL;
	int		option;
	int		inFd = -1;
	FILE *	outFile = NULL;
	unsigned    strTblIx;

	/* argument parsing */

	if (argc != 5)
	{
		fprintf(stderr, usage, argv[0]);
		goto errorReturn;
	}

	while ((option = getopt(argc, argv, "i:o:")) != -1)
	{
		switch (option)
		{
			case 'i':
				inFileName = optarg;
				break;
			case 'o':
				outFileName = optarg;
				break;
			default:
				fprintf(stderr, usage, argv[0]);
				goto errorReturn;
		}
	}

	/* open input object ELF module and output header file */

	inFd = open(inFileName, OPEN_FLAGS);

	if (inFd == -1)
	{
		fprintf(stderr, "Cannot open input object module");
		goto errorReturn;
	}

	outFile = fopen(outFileName, "w");

	if (outFile == NULL)
	{
		fprintf(stderr, "Cannot open output header file");
		goto errorReturn;
	}

	/*
	 * In the following order, attempt to ...
	 *  1. Load the ELF header
	 *  2. Load the section headers
	 *  3. Find the symbol table
	 *  4. Find the string table
	 *  5. Load the string table
	 * Bail if any of those steps fail.
	 */

	if ((ehdrLoad(inFd) != 0) ||
			(shdrsLoad(inFd) != 0) ||
			(symTblFind(&symTblOffset, &symTblSize) != 0) ||
			(strTblFind(&strTblIx) != 0) ||
			(strTblLoad(inFd, strTblIx, &pStringTable) != 0))
	{
		goto errorReturn;
	}


	/*
	 * Dump the following to the header file ...
	 *  1. Header file preamble
	 *  2. Absolute symbols
	 *  3. Header file postscript
	 */

	headerPreambleDump(outFile, outFileName);
	headerAbsoluteSymbolsDump(inFd, outFile,
			symTblOffset, symTblSize, pStringTable);
	headerPostscriptDump(outFile);

	/* done: cleanup */

	close(inFd);
	fclose(outFile);
	free(shdr);
	free(pStringTable);

	return 0;

errorReturn:
	if (inFd != -1)
	{
		close(inFd);
	}

	if (outFile != NULL)
	{
		fclose(outFile);
	}

	if (shdr != NULL)
	{
		free(shdr);
	}

	if (pStringTable != NULL)
	{
		free(pStringTable);
	}

	return 1;
}
