/*
 *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license 
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may 
 *  be found in the AUTHORS file in the root of the source tree.
 */


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

#include "vpx_config.h"

#if defined(_MSC_VER)
#include <io.h>
#include <share.h>
#include "vpx/vpx_integer.h"
#else
#include <stdint.h>
#include <unistd.h>
#endif

#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>

typedef enum
{
    OUTPUT_FMT_PLAIN,
    OUTPUT_FMT_RVDS,
    OUTPUT_FMT_GAS,
} output_fmt_t;

int log_msg(const char *fmt, ...)
{
    int res;
    va_list ap;
    va_start(ap, fmt);
    res = vfprintf(stderr, fmt, ap);
    va_end(ap);
    return res;
}

#if defined(__GNUC__) && __GNUC__

#if defined(__MACH__)

#include <mach-o/loader.h>
#include <mach-o/nlist.h>

int parse_macho(uint8_t *base_buf, size_t sz)
{
    int i, j;
    struct mach_header header;
    uint8_t *buf = base_buf;
    int base_data_section = 0;

    memcpy(&header, buf, sizeof(struct mach_header));
    buf += sizeof(struct mach_header);

    if (header.magic != MH_MAGIC)
    {
        log_msg("Bad magic number for object file. 0x%x expected, 0x%x found.\n",
                header.magic, MH_MAGIC);
        goto bail;
    }

    if (header.cputype != CPU_TYPE_ARM)
    {
        log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_ARM.\n");
        goto bail;
    }

    if (header.filetype != MH_OBJECT)
    {
        log_msg("Bad filetype for object file. Currently only tested for MH_OBJECT.\n");
        goto bail;
    }

    for (i = 0; i < header.ncmds; i++)
    {
        struct load_command lc;
        struct symtab_command sc;
        struct segment_command seg_c;

        memcpy(&lc, buf, sizeof(struct load_command));

        if (lc.cmd == LC_SEGMENT)
        {
            uint8_t *seg_buf = buf;
            struct section s;

            memcpy(&seg_c, buf, sizeof(struct segment_command));

            seg_buf += sizeof(struct segment_command);

            for (j = 0; j < seg_c.nsects; j++)
            {
                memcpy(&s, seg_buf + (j * sizeof(struct section)), sizeof(struct section));

                // Need to get this offset which is the start of the symbol table
                // before matching the strings up with symbols.
                base_data_section = s.offset;
            }
        }
        else if (lc.cmd == LC_SYMTAB)
        {
            uint8_t *sym_buf = base_buf;
            uint8_t *str_buf = base_buf;

            if (base_data_section != 0)
            {
                memcpy(&sc, buf, sizeof(struct symtab_command));

                if (sc.cmdsize != sizeof(struct symtab_command))
                    log_msg("Can't find symbol table!\n");

                sym_buf += sc.symoff;
                str_buf += sc.stroff;

                for (j = 0; j < sc.nsyms; j++)
                {
                    struct nlist nl;
                    int val;

                    memcpy(&nl, sym_buf + (j * sizeof(struct nlist)), sizeof(struct nlist));

                    val = *((int *)(base_buf + base_data_section + nl.n_value));

                    // Location of string is cacluated each time from the
                    // start of the string buffer.  On darwin the symbols
                    // are prefixed by "_".  On other platforms it is not
                    // so it needs to be removed.  That is the reason for
                    // the +1.
                    printf("%-40s EQU %5d\n", str_buf + nl.n_un.n_strx + 1, val);
                }
            }
        }

        buf += lc.cmdsize;
    }

    return 0;
bail:
    return 1;

}

int main(int argc, char **argv)
{
    int fd;
    char *f;
    struct stat stat_buf;
    uint8_t *file_buf;
    int res;

    if (argc < 2 || argc > 3)
    {
        fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
        fprintf(stderr, "  <obj file>\tMachO format object file to parse\n");
        fprintf(stderr, "Output Formats:\n");
        fprintf(stderr, "  gas  - compatible with GNU assembler\n");
        fprintf(stderr, "  rvds - compatible with armasm\n");
        goto bail;
    }

    f = argv[2];

    if (!((!strcmp(argv[1], "rvds")) || (!strcmp(argv[1], "gas"))))
        f = argv[1];

    fd = open(f, O_RDONLY);

    if (fd < 0)
    {
        perror("Unable to open file");
        goto bail;
    }

    if (fstat(fd, &stat_buf))
    {
        perror("stat");
        goto bail;
    }

    file_buf = malloc(stat_buf.st_size);

    if (!file_buf)
    {
        perror("malloc");
        goto bail;
    }

    if (read(fd, file_buf, stat_buf.st_size) != stat_buf.st_size)
    {
        perror("read");
        goto bail;
    }

    if (close(fd))
    {
        perror("close");
        goto bail;
    }

    res = parse_macho(file_buf, stat_buf.st_size);
    free(file_buf);

    if (!res)
        return EXIT_SUCCESS;

bail:
    return EXIT_FAILURE;
}

#else
#include "elf.h"

#define COPY_STRUCT(dst, buf, ofst, sz) do {\
        if(ofst + sizeof((*(dst))) > sz) goto bail;\
        memcpy(dst, buf+ofst, sizeof((*(dst))));\
    } while(0)

#define ENDIAN_ASSIGN(val, memb) do {\
        if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail;}\
        (val) = (memb);\
    } while(0)

#define ENDIAN_ASSIGN_IN_PLACE(memb) do {\
        ENDIAN_ASSIGN(memb, memb);\
    } while(0)

typedef struct
{
    uint8_t     *buf; /* Buffer containing ELF data */
    size_t       sz;  /* Buffer size */
    int          le_data;   /* Data is little-endian */
    Elf32_Ehdr   hdr;
} elf_obj_t;

int parse_elf32_header(elf_obj_t *elf)
{
    int res;
    /* Verify ELF32 header */
    COPY_STRUCT(&elf->hdr, elf->buf, 0, elf->sz);
    res = elf->hdr.e_ident[EI_MAG0] == ELFMAG0;
    res &= elf->hdr.e_ident[EI_MAG1] == ELFMAG1;
    res &= elf->hdr.e_ident[EI_MAG2] == ELFMAG2;
    res &= elf->hdr.e_ident[EI_MAG3] == ELFMAG3;
    res &= elf->hdr.e_ident[EI_CLASS] == ELFCLASS32;
    res &= elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB
           || elf->hdr.e_ident[EI_DATA] == ELFDATA2MSB;

    if (!res) goto bail;

    elf->le_data = elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB;

    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_type);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_machine);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_version);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_entry);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phoff);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shoff);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_flags);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_ehsize);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phentsize);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phnum);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shentsize);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shnum);
    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shstrndx);
    return 0;
bail:
    return 1;
}

int parse_elf32_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr)
{
    if (idx >= elf->hdr.e_shnum)
        goto bail;

    COPY_STRUCT(hdr, elf->buf, elf->hdr.e_shoff + idx * elf->hdr.e_shentsize,
                elf->sz);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_name);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_type);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_flags);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addr);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_offset);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_size);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_link);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_info);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addralign);
    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_entsize);
    return 0;
bail:
    return 1;
}

char *parse_elf32_string_table(elf_obj_t *elf, int s_idx, int idx)
{
    Elf32_Shdr shdr;

    if (parse_elf32_section(elf, s_idx, &shdr))
    {
        log_msg("Failed to parse ELF string table: section %d, index %d\n",
                s_idx, idx);
        return "";
    }

    return (char *)(elf->buf + shdr.sh_offset + idx);
}

int parse_elf32_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym)
{
    COPY_STRUCT(sym, elf->buf, ofst, elf->sz);
    ENDIAN_ASSIGN_IN_PLACE(sym->st_name);
    ENDIAN_ASSIGN_IN_PLACE(sym->st_value);
    ENDIAN_ASSIGN_IN_PLACE(sym->st_size);
    ENDIAN_ASSIGN_IN_PLACE(sym->st_info);
    ENDIAN_ASSIGN_IN_PLACE(sym->st_other);
    ENDIAN_ASSIGN_IN_PLACE(sym->st_shndx);
    return 0;
bail:
    return 1;
}

int parse_elf32(uint8_t *buf, size_t sz, output_fmt_t mode)
{
    elf_obj_t  elf;
    Elf32_Shdr shdr;
    unsigned int ofst;
    int         i;
    Elf32_Off strtab_off;   /* save String Table offset for later use */

    memset(&elf, 0, sizeof(elf));
    elf.buf = buf;
    elf.sz = sz;

    /* Parse Header */
    if (parse_elf32_header(&elf))
    {
        log_msg("Parse error: File does not appear to be valid ELF32\n");
        return 1;
    }

    for (i = 0; i < elf.hdr.e_shnum; i++)
    {
        parse_elf32_section(&elf, i, &shdr);

        if (shdr.sh_type == SHT_STRTAB)
        {
            char strtsb_name[128];

            strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));

            if (!(strcmp(strtsb_name, ".shstrtab")))
            {
                log_msg("found section: %s\n", strtsb_name);
                strtab_off = shdr.sh_offset;
                break;
            }
        }
    }

    /* Parse all Symbol Tables */
    for (i = 0; i < elf.hdr.e_shnum; i++)
    {

        parse_elf32_section(&elf, i, &shdr);

        if (shdr.sh_type == SHT_SYMTAB)
        {
            for (ofst = shdr.sh_offset;
                 ofst < shdr.sh_offset + shdr.sh_size;
                 ofst += shdr.sh_entsize)
            {
                Elf32_Sym sym;

                parse_elf32_symbol(&elf, ofst, &sym);

                /* For all OBJECTS (data objects), extract the value from the
                 * proper data segment.
                 */
                if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
                    log_msg("found data object %s\n",
                            parse_elf32_string_table(&elf,
                                                     shdr.sh_link,
                                                     sym.st_name));

                if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
                    && sym.st_size == 4)
                {
                    Elf32_Shdr dhdr;
                    int32_t      val;
                    char section_name[128];

                    parse_elf32_section(&elf, sym.st_shndx, &dhdr);

                    /* For explanition - refer to _MSC_VER version of code */
                    strcpy(section_name, (char *)(elf.buf + strtab_off + dhdr.sh_name));
                    log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type);

                    if (!(strcmp(section_name, ".bss")))
                    {
                        val = 0;
                    }
                    else
                    {
                        memcpy(&val,
                               elf.buf + dhdr.sh_offset + sym.st_value,
                               sizeof(val));
                    }

                    if (!elf.le_data)
                    {
                        log_msg("Big Endian data not supported yet!\n");
                        goto bail;
                    }\

                    switch (mode)
                    {
                    case OUTPUT_FMT_RVDS:
                        printf("%-40s EQU %5d\n",
                               parse_elf32_string_table(&elf,
                                                        shdr.sh_link,
                                                        sym.st_name),
                               val);
                        break;
                    case OUTPUT_FMT_GAS:
                        printf(".equ %-40s, %5d\n",
                               parse_elf32_string_table(&elf,
                                                        shdr.sh_link,
                                                        sym.st_name),
                               val);
                        break;
                    default:
                        printf("%s = %d\n",
                               parse_elf32_string_table(&elf,
                                                        shdr.sh_link,
                                                        sym.st_name),
                               val);
                    }
                }
            }
        }
    }

    if (mode == OUTPUT_FMT_RVDS)
        printf("    END\n");

    return 0;
bail:
    log_msg("Parse error: File does not appear to be valid ELF32\n");
    return 1;
}

int main(int argc, char **argv)
{
    int fd;
    output_fmt_t mode;
    char *f;
    struct stat stat_buf;
    uint8_t *file_buf;
    int res;

    if (argc < 2 || argc > 3)
    {
        fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
        fprintf(stderr, "  <obj file>\tELF format object file to parse\n");
        fprintf(stderr, "Output Formats:\n");
        fprintf(stderr, "  gas  - compatible with GNU assembler\n");
        fprintf(stderr, "  rvds - compatible with armasm\n");
        goto bail;
    }

    f = argv[2];

    if (!strcmp(argv[1], "rvds"))
        mode = OUTPUT_FMT_RVDS;
    else if (!strcmp(argv[1], "gas"))
        mode = OUTPUT_FMT_GAS;
    else
        f = argv[1];


    fd = open(f, O_RDONLY);

    if (fd < 0)
    {
        perror("Unable to open file");
        goto bail;
    }

    if (fstat(fd, &stat_buf))
    {
        perror("stat");
        goto bail;
    }

    file_buf = malloc(stat_buf.st_size);

    if (!file_buf)
    {
        perror("malloc");
        goto bail;
    }

    if (read(fd, file_buf, stat_buf.st_size) != stat_buf.st_size)
    {
        perror("read");
        goto bail;
    }

    if (close(fd))
    {
        perror("close");
        goto bail;
    }

    res = parse_elf32(file_buf, stat_buf.st_size, mode);
    //res = parse_coff(file_buf, stat_buf.st_size);
    free(file_buf);

    if (!res)
        return EXIT_SUCCESS;

bail:
    return EXIT_FAILURE;
}
#endif
#endif


#if defined(_MSC_VER)
/*  See "Microsoft Portable Executable and Common Object File Format Specification"
    for reference.
*/
#define get_le32(x) ((*(x)) | (*(x+1)) << 8 |(*(x+2)) << 16 | (*(x+3)) << 24 )
#define get_le16(x) ((*(x)) | (*(x+1)) << 8)

int parse_coff(unsigned __int8 *buf, size_t sz)
{
    unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr;
    unsigned int sectionrawdata_ptr;
    unsigned int i;
    unsigned __int8 *ptr;
    unsigned __int32 symoffset;
    FILE *fp;

    char **sectionlist;  //this array holds all section names in their correct order.
    //it is used to check if the symbol is in .bss or .data section.

    nsections = get_le16(buf + 2);
    symtab_ptr = get_le32(buf + 8);
    symtab_sz = get_le32(buf + 12);
    strtab_ptr = symtab_ptr + symtab_sz * 18;

    if (nsections > 96)
        goto bail;

    sectionlist = malloc(nsections * sizeof * sectionlist);

    //log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections);

    /*
    The size of optional header is always zero for an obj file. So, the section header
    follows the file header immediately.
    */

    ptr = buf + 20;     //section header

    for (i = 0; i < nsections; i++)
    {
        char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
        strncpy(sectionname, ptr, 8);
        //log_msg("COFF: Parsing section %s\n",sectionname);

        sectionlist[i] = malloc(strlen(sectionname) + 1);
        strcpy(sectionlist[i], sectionname);

        if (!strcmp(sectionname, ".data")) sectionrawdata_ptr = get_le32(ptr + 20);

        ptr += 40;
    }

    //log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
    //log_msg("COFF: raw data pointer ofset for section .data is %u\n", sectionrawdata_ptr);

    fp = fopen("vpx_asm_offsets.asm", "w");

    if (fp == NULL)
    {
        perror("open file");
        goto bail;
    }

    /*  The compiler puts the data with non-zero offset in .data section, but puts the data with
        zero offset in .bss section. So, if the data in in .bss section, set offset=0.
        Note from Wiki: In an object module compiled from C, the bss section contains
        the local variables (but not functions) that were declared with the static keyword,
        except for those with non-zero initial values. (In C, static variables are initialized
        to zero by default.) It also contains the non-local (both extern and static) variables
        that are also initialized to zero (either explicitly or by default).
        */
    //move to symbol table
    /* COFF symbol table:
        offset      field
        0           Name(*)
        8           Value
        12          SectionNumber
        14          Type
        16          StorageClass
        17          NumberOfAuxSymbols
        */
    ptr = buf + symtab_ptr;

    for (i = 0; i < symtab_sz; i++)
    {
        __int16 section = get_le16(ptr + 12); //section number

        if (section > 0 && ptr[16] == 2)
        {
            //if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) {

            if (get_le32(ptr))
            {
                char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
                strncpy(name, ptr, 8);
                //log_msg("COFF: Parsing symbol %s\n",name);
                fprintf(fp, "%-40s EQU ", name);
            }
            else
            {
                //log_msg("COFF: Parsing symbol %s\n",
                //        buf + strtab_ptr + get_le32(ptr+4));
                fprintf(fp, "%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4));
            }

            if (!(strcmp(sectionlist[section-1], ".bss")))
            {
                symoffset = 0;
            }
            else
            {
                symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8));
            }

            //log_msg("      Section: %d\n",section);
            //log_msg("      Class:   %d\n",ptr[16]);
            //log_msg("      Address: %u\n",get_le32(ptr+8));
            //log_msg("      Offset: %u\n", symoffset);

            fprintf(fp, "%5d\n", symoffset);
        }

        ptr += 18;
    }

    fprintf(fp, "    END\n");
    fclose(fp);

    for (i = 0; i < nsections; i++)
    {
        free(sectionlist[i]);
    }

    free(sectionlist);

    return 0;
bail:

    for (i = 0; i < nsections; i++)
    {
        free(sectionlist[i]);
    }

    free(sectionlist);

    return 1;
}

int main(int argc, char **argv)
{
    int fd;
    output_fmt_t mode;
    const char *f;
    struct _stat stat_buf;
    unsigned __int8 *file_buf;
    int res;

    if (argc < 2 || argc > 3)
    {
        fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
        fprintf(stderr, "  <obj file>\tELF format object file to parse\n");
        fprintf(stderr, "Output Formats:\n");
        fprintf(stderr, "  gas  - compatible with GNU assembler\n");
        fprintf(stderr, "  rvds - compatible with armasm\n");
        goto bail;
    }

    f = argv[2];

    if (!strcmp(argv[1], "rvds"))
        mode = OUTPUT_FMT_RVDS;
    else if (!strcmp(argv[1], "gas"))
        mode = OUTPUT_FMT_GAS;
    else
        f = argv[1];

    if (_sopen_s(&fd, f, _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE))
    {
        perror("Unable to open file");
        goto bail;
    }

    if (_fstat(fd, &stat_buf))
    {
        perror("stat");
        goto bail;
    }

    file_buf = malloc(stat_buf.st_size);

    if (!file_buf)
    {
        perror("malloc");
        goto bail;
    }

    if (_read(fd, file_buf, stat_buf.st_size) != stat_buf.st_size)
    {
        perror("read");
        goto bail;
    }

    if (_close(fd))
    {
        perror("close");
        goto bail;
    }

    res = parse_coff(file_buf, stat_buf.st_size);

    free(file_buf);

    if (!res)
        return EXIT_SUCCESS;

bail:
    return EXIT_FAILURE;
}
#endif
