/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.
 */

#include <assert.h>
#include <fcntl.h>
#include <gelf.h>
#include <libelf.h>
#include <sys/types.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
#include <errno.h>

#include <nanohub/nanohub.h>
#include <nanohub/nanoapp.h>
#include <nanohub/appRelocFormat.h>

//This code assumes it is run on a LE CPU with unaligned access abilities. Sorry.

#define FLASH_BASE  0x10000000
#define RAM_BASE    0x80000000

#define FLASH_SIZE  0x10000000  //256MB ought to be enough for everyone
#define RAM_SIZE    0x10000000  //256MB ought to be enough for everyone

//caution: double evaluation
#define IS_IN_RANGE_E(_val, _rstart, _rend) (((_val) >= (_rstart)) && ((_val) < (_rend)))
#define IS_IN_RANGE(_val, _rstart, _rsz)    IS_IN_RANGE_E((_val), (_rstart), ((_rstart) + (_rsz)))
#define IS_IN_RAM(_val)              IS_IN_RANGE(_val, RAM_BASE, RAM_SIZE)
#define IS_IN_FLASH(_val)            IS_IN_RANGE(_val, FLASH_BASE, FLASH_SIZE)


#define NANO_RELOC_TYPE_RAM    0
#define NANO_RELOC_TYPE_FLASH  1
#define NANO_RELOC_LAST        2 //must be <= (RELOC_TYPE_MASK >> RELOC_TYPE_SHIFT)

struct RelocEntry {
    uint32_t where;
    uint32_t info;  //bottom 8 bits is type, top 24 is sym idx
};

#define RELOC_TYPE_ABS_S    2
#define RELOC_TYPE_ABS_D    21
#define RELOC_TYPE_SECT     23


struct SymtabEntry {
    uint32_t a;
    uint32_t addr;
    uint32_t b, c;
};

struct NanoRelocEntry {
    uint32_t ofstInRam;
    uint8_t type;
};

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(ary) (sizeof(ary) / sizeof((ary)[0]))
#endif

#define DBG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
#define ERR(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)

// Prints the given message followed by the most recent libelf error
#define ELF_ERR(fmt, ...) ERR(fmt ": %s\n", ##__VA_ARGS__, elf_errmsg(-1))

struct ElfAppSection {
    void  *data;
    size_t size;
};

struct ElfNanoApp {
    struct ElfAppSection flash;
    struct ElfAppSection data;
    struct ElfAppSection relocs;
    struct ElfAppSection symtab;

    // Not parsed from file, but constructed via genElfNanoRelocs
    struct ElfAppSection packedNanoRelocs;
};

static void fatalUsage(const char *name, const char *msg, const char *arg)
{
    if (msg && arg)
        fprintf(stderr, "Error: %s: %s\n\n", msg, arg);
    else if (msg)
        fprintf(stderr, "Error: %s\n\n", msg);

    fprintf(stderr, "USAGE: %s [-v] [-k <key id>] [-a <app id>] [-r] [-n <layout name>] [-i <layout id>] <input file> [<output file>]\n"
                    "       -v               : be verbose\n"
                    "       -n <layout name> : app, os, key\n"
                    "       -i <layout id>   : 1 (app), 2 (key), 3 (os)\n"
                    "       -f <layout flags>: 16-bit hex value, stored as layout-specific flags\n"
                    "       -c <chre api>    : 16-bit hex value, stored as chre-major + chre-minor\n"
                    "       -a <app ID>      : 64-bit hex number != 0\n"
                    "       -e <app version> : 32-bit hex number\n"
                    "       -k <key ID>      : 64-bit hex number != 0\n"
                    "       -r               : bare (no AOSP header); used only for inner OS image generation\n"
                    "       -s               : treat input as statically linked ELF (app layout only)\n"
                    "       layout ID and layout name control the same parameter, so only one of them needs to be used\n"
                    , name);
    exit(1);
}

static uint8_t *packNanoRelocs(struct NanoRelocEntry *nanoRelocs, uint32_t outNumRelocs, uint32_t *finalPackedNanoRelocSz, bool verbose)
{
    uint32_t i, j, k;
    uint8_t *packedNanoRelocs;
    uint32_t packedNanoRelocSz;
    uint32_t lastOutType = 0, origin = 0;

    //sort by type and then offset
    for (i = 0; i < outNumRelocs; i++) {
        struct NanoRelocEntry t;

        for (k = i, j = k + 1; j < outNumRelocs; j++) {
            if (nanoRelocs[j].type > nanoRelocs[k].type)
                continue;
            if ((nanoRelocs[j].type < nanoRelocs[k].type) || (nanoRelocs[j].ofstInRam < nanoRelocs[k].ofstInRam))
                k = j;
        }
        memcpy(&t, nanoRelocs + i, sizeof(struct NanoRelocEntry));
        memcpy(nanoRelocs + i, nanoRelocs + k, sizeof(struct NanoRelocEntry));
        memcpy(nanoRelocs + k, &t, sizeof(struct NanoRelocEntry));

        if (verbose)
            fprintf(stderr, "SortedReloc[%3" PRIu32 "] = {0x%08" PRIX32 ",0x%02" PRIX8 "}\n", i, nanoRelocs[i].ofstInRam, nanoRelocs[i].type);
    }

    //produce output nanorelocs in packed format
    packedNanoRelocs = malloc(outNumRelocs * 6); //definitely big enough
    packedNanoRelocSz = 0;
    for (i = 0; i < outNumRelocs; i++) {
        uint32_t displacement;

        if (lastOutType != nanoRelocs[i].type) {  //output type if ti changed
            if (nanoRelocs[i].type - lastOutType == 1) {
                packedNanoRelocs[packedNanoRelocSz++] = TOKEN_RELOC_TYPE_NEXT;
                if (verbose)
                    fprintf(stderr, "Out: RelocTC (1) // to 0x%02" PRIX8 "\n", nanoRelocs[i].type);
            }
            else {
                packedNanoRelocs[packedNanoRelocSz++] = TOKEN_RELOC_TYPE_CHG;
                packedNanoRelocs[packedNanoRelocSz++] = nanoRelocs[i].type - lastOutType - 1;
                if (verbose)
                    fprintf(stderr, "Out: RelocTC (0x%02" PRIX8 ")  // to 0x%02" PRIX8 "\n", (uint8_t)(nanoRelocs[i].type - lastOutType - 1), nanoRelocs[i].type);
            }
            lastOutType = nanoRelocs[i].type;
            origin = 0;
        }
        displacement = nanoRelocs[i].ofstInRam - origin;
        origin = nanoRelocs[i].ofstInRam + 4;
        if (displacement & 3) {
            fprintf(stderr, "Unaligned relocs are not possible!\n");
            exit(-5);
        }
        displacement /= 4;

        //might be start of a run. look into that
        if (!displacement) {
            for (j = 1; j + i < outNumRelocs && j < MAX_RUN_LEN && nanoRelocs[j + i].type == lastOutType && nanoRelocs[j + i].ofstInRam - nanoRelocs[j + i - 1].ofstInRam == 4; j++);
            if (j >= MIN_RUN_LEN) {
                if (verbose)
                    fprintf(stderr, "Out: Reloc0  x%" PRIX32 "\n", j);
                packedNanoRelocs[packedNanoRelocSz++] = TOKEN_CONSECUTIVE;
                packedNanoRelocs[packedNanoRelocSz++] = j - MIN_RUN_LEN;
                origin = nanoRelocs[j + i - 1].ofstInRam + 4;  //reset origin to last one
                i += j - 1;  //loop will increment anyways, hence +1
                continue;
            }
        }

        //produce output
        if (displacement <= MAX_8_BIT_NUM) {
            if (verbose)
                fprintf(stderr, "Out: Reloc8  0x%02" PRIX32 "\n", displacement);
            packedNanoRelocs[packedNanoRelocSz++] = displacement;
        }
        else if (displacement <= MAX_16_BIT_NUM) {
            if (verbose)
                fprintf(stderr, "Out: Reloc16 0x%06" PRIX32 "\n", displacement);
                        displacement -= MAX_8_BIT_NUM;
            packedNanoRelocs[packedNanoRelocSz++] = TOKEN_16BIT_OFST;
            packedNanoRelocs[packedNanoRelocSz++] = displacement;
            packedNanoRelocs[packedNanoRelocSz++] = displacement >> 8;
        }
        else if (displacement <= MAX_24_BIT_NUM) {
            if (verbose)
                fprintf(stderr, "Out: Reloc24 0x%08" PRIX32 "\n", displacement);
                        displacement -= MAX_16_BIT_NUM;
            packedNanoRelocs[packedNanoRelocSz++] = TOKEN_24BIT_OFST;
            packedNanoRelocs[packedNanoRelocSz++] = displacement;
            packedNanoRelocs[packedNanoRelocSz++] = displacement >> 8;
            packedNanoRelocs[packedNanoRelocSz++] = displacement >> 16;
        }
        else  {
            if (verbose)
                fprintf(stderr, "Out: Reloc32 0x%08" PRIX32 "\n", displacement);
            packedNanoRelocs[packedNanoRelocSz++] = TOKEN_32BIT_OFST;
            packedNanoRelocs[packedNanoRelocSz++] = displacement;
            packedNanoRelocs[packedNanoRelocSz++] = displacement >> 8;
            packedNanoRelocs[packedNanoRelocSz++] = displacement >> 16;
            packedNanoRelocs[packedNanoRelocSz++] = displacement >> 24;
        }
    }

    *finalPackedNanoRelocSz = packedNanoRelocSz;
    return packedNanoRelocs;
}

static int finalizeAndWrite(uint8_t *buf, uint32_t bufUsed, uint32_t bufSz, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t chreApi)
{
    int ret;
    struct AppInfo app;
    struct SectInfo *sect;
    struct BinHdr *bin = (struct BinHdr *) buf;
    struct ImageHeader outHeader = {
        .aosp = (struct nano_app_binary_t) {
            .header_version = 1,
            .magic = NANOAPP_AOSP_MAGIC,
            .app_id = appId,
            .app_version = bin->hdr.appVer,
            .flags       = 0, // encrypted (1), signed (2) (will be set by other tools)
            .chre_api_major = chreApi >> 8,
            .chre_api_minor = chreApi & 0xFF,
        },
        .layout = (struct ImageLayout) {
            .magic = GOOGLE_LAYOUT_MAGIC,
            .version = 1,
            .payload = LAYOUT_APP,
            .flags = layoutFlags | (chreApi ? 0x0010 : 0x0000),
        },
    };
    uint32_t dataOffset = sizeof(outHeader) + sizeof(app);
    uint32_t hdrDiff = dataOffset - sizeof(*bin);
    app.sect = bin->sect;
    app.vec  = bin->vec;

    assertMem(bufUsed + hdrDiff, bufSz);

    memmove(buf + dataOffset, buf + sizeof(*bin), bufUsed - sizeof(*bin));
    bufUsed += hdrDiff;
    memcpy(buf, &outHeader, sizeof(outHeader));
    memcpy(buf + sizeof(outHeader), &app, sizeof(app));
    sect = &app.sect;

    //if we have any bytes to output, show stats
    if (bufUsed) {
        uint32_t codeAndRoDataSz = sect->data_data;
        uint32_t relocsSz = sect->rel_end - sect->rel_start;
        uint32_t gotSz = sect->got_end - sect->data_start;
        uint32_t bssSz = sect->bss_end - sect->bss_start;

        fprintf(stderr,"Final binary size %" PRIu32 " bytes\n", bufUsed);
        fprintf(stderr, "\n");
        fprintf(stderr, "       FW header size (flash):      %6zu bytes\n", FLASH_RELOC_OFFSET);
        fprintf(stderr, "       Code + RO data (flash):      %6" PRIu32 " bytes\n", codeAndRoDataSz);
        fprintf(stderr, "       Relocs (flash):              %6" PRIu32 " bytes\n", relocsSz);
        fprintf(stderr, "       GOT + RW data (flash & RAM): %6" PRIu32 " bytes\n", gotSz);
        fprintf(stderr, "       BSS (RAM):                   %6" PRIu32 " bytes\n", bssSz);
        fprintf(stderr, "\n");
        fprintf(stderr,"Runtime flash use: %" PRIu32 " bytes\n", (uint32_t)(codeAndRoDataSz + relocsSz + gotSz + FLASH_RELOC_OFFSET));
        fprintf(stderr,"Runtime RAM use: %" PRIu32 " bytes\n", gotSz + bssSz);
    }

    ret = fwrite(buf, bufUsed, 1, out) == 1 ? 0 : 2;
    if (ret)
        fprintf(stderr, "Failed to write output file: %s\n", strerror(errno));

    return ret;
}

static int handleApp(uint8_t **pbuf, uint32_t bufUsed, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t appVer, uint32_t chreApi, bool verbose)
{
    uint32_t i, numRelocs, numSyms, outNumRelocs = 0, packedNanoRelocSz;
    struct NanoRelocEntry *nanoRelocs = NULL;
    struct RelocEntry *relocs;
    struct SymtabEntry *syms;
    uint8_t *packedNanoRelocs;
    uint32_t t;
    struct BinHdr *bin;
    int ret = -1;
    struct SectInfo *sect;
    uint8_t *buf = *pbuf;
    uint32_t bufSz = bufUsed * 3 /2;

    //make buffer 50% bigger than bufUsed in case relocs grow out of hand
    buf = reallocOrDie(buf, bufSz);
    *pbuf = buf;

    //sanity checks
    bin = (struct BinHdr*)buf;
    if (bufUsed < sizeof(*bin)) {
        fprintf(stderr, "File size too small\n");
        goto out;
    }

    if (bin->hdr.magic != NANOAPP_FW_MAGIC) {
        fprintf(stderr, "Magic value is wrong: found %08" PRIX32
                        "; expected %08" PRIX32 "\n",
                        bin->hdr.magic, NANOAPP_FW_MAGIC);
        goto out;
    }

    sect = &bin->sect;
    bin->hdr.appVer = appVer;

    //do some math
    relocs = (struct RelocEntry*)(buf + sect->rel_start - FLASH_BASE);
    syms = (struct SymtabEntry*)(buf + sect->rel_end - FLASH_BASE);
    numRelocs = (sect->rel_end - sect->rel_start) / sizeof(struct RelocEntry);
    numSyms = (bufUsed + FLASH_BASE - sect->rel_end) / sizeof(struct SymtabEntry);

    //sanity
    if (numRelocs * sizeof(struct RelocEntry) + sect->rel_start != sect->rel_end) {
        fprintf(stderr, "Relocs of nonstandard size\n");
        goto out;
    }
    if (numSyms * sizeof(struct SymtabEntry) + sect->rel_end != bufUsed + FLASH_BASE) {
        fprintf(stderr, "Syms of nonstandard size\n");
        goto out;
    }

    //show some info
    fprintf(stderr, "\nRead %" PRIu32 " bytes of binary.\n", bufUsed);

    if (verbose)
        fprintf(stderr, "Found %" PRIu32 " relocs and a %" PRIu32 "-entry symbol table\n", numRelocs, numSyms);

    //handle relocs
    nanoRelocs = malloc(sizeof(struct NanoRelocEntry[numRelocs]));
    if (!nanoRelocs) {
        fprintf(stderr, "Failed to allocate a nano-reloc table\n");
        goto out;
    }

    for (i = 0; i < numRelocs; i++) {
        uint32_t relocType = relocs[i].info & 0xff;
        uint32_t whichSym = relocs[i].info >> 8;
        uint32_t *valThereP;

        if (whichSym >= numSyms) {
            fprintf(stderr, "Reloc %" PRIu32 " references a nonexistent symbol!\n"
                            "INFO:\n"
                            "        Where: 0x%08" PRIX32 "\n"
                            "        type: %" PRIu32 "\n"
                            "        sym: %" PRIu32 "\n",
                i, relocs[i].where, relocs[i].info & 0xff, whichSym);
            goto out;
        }

        if (verbose) {
            const char *seg;

            fprintf(stderr, "Reloc[%3" PRIu32 "]:\n {@0x%08" PRIX32 ", type %3" PRIu32 ", -> sym[%3" PRIu32 "]: {@0x%08" PRIX32 "}, ",
                i, relocs[i].where, relocs[i].info & 0xff, whichSym, syms[whichSym].addr);

            if (IS_IN_RANGE_E(relocs[i].where, sect->bss_start, sect->bss_end))
                seg = ".bss";
            else if (IS_IN_RANGE_E(relocs[i].where, sect->data_start, sect->data_end))
                seg = ".data";
            else if (IS_IN_RANGE_E(relocs[i].where, sect->got_start, sect->got_end))
                seg = ".got";
            else if (IS_IN_RANGE_E(relocs[i].where, FLASH_BASE, FLASH_BASE + sizeof(struct BinHdr)))
                seg = "APPHDR";
            else
                seg = "???";

            fprintf(stderr, "in   %s}\n", seg);
        }
        /* handle relocs inside the header */
        if (IS_IN_FLASH(relocs[i].where) && relocs[i].where - FLASH_BASE < sizeof(struct BinHdr) && relocType == RELOC_TYPE_SECT) {
            /* relocs in header are special - runtime corrects for them */
            if (syms[whichSym].addr) {
                fprintf(stderr, "Weird in-header sect reloc %" PRIu32 " to symbol %" PRIu32 " with nonzero addr 0x%08" PRIX32 "\n",
                        i, whichSym, syms[whichSym].addr);
                goto out;
            }

            valThereP = (uint32_t*)(buf + relocs[i].where - FLASH_BASE);
            if (!IS_IN_FLASH(*valThereP)) {
                fprintf(stderr, "In-header reloc %" PRIu32 " of location 0x%08" PRIX32 " is outside of FLASH!\n"
                                "INFO:\n"
                                "        type: %" PRIu32 "\n"
                                "        sym: %" PRIu32 "\n"
                                "        Sym Addr: 0x%08" PRIX32 "\n",
                                i, relocs[i].where, relocType, whichSym, syms[whichSym].addr);
                goto out;
            }

            // binary header generated by objcopy, .napp header and final FW header in flash are of different size.
            // we subtract binary header offset here, so all the entry points are relative to beginning of "sect".
            // FW will use &sect as a base to call these vectors; no more problems with different header sizes;
            // Assumption: offsets between sect & vec, vec & code are the same in all images (or, in a simpler words, { sect, vec, code }
            // must go together). this is enforced by linker script, and maintained by all tools and FW download code in the OS.
            *valThereP -= FLASH_BASE + BINARY_RELOC_OFFSET;

            if (verbose)
                fprintf(stderr, "  -> Nano reloc skipped for in-header reloc\n");

            continue; /* do not produce an output reloc */
        }

        if (!IS_IN_RAM(relocs[i].where)) {
            fprintf(stderr, "In-header reloc %" PRIu32 " of location 0x%08" PRIX32 " is outside of RAM!\n"
                            "INFO:\n"
                            "        type: %" PRIu32 "\n"
                            "        sym: %" PRIu32 "\n"
                            "        Sym Addr: 0x%08" PRIX32 "\n",
                            i, relocs[i].where, relocType, whichSym, syms[whichSym].addr);
            goto out;
        }

        valThereP = (uint32_t*)(buf + relocs[i].where + sect->data_data - RAM_BASE - FLASH_BASE);

        nanoRelocs[outNumRelocs].ofstInRam = relocs[i].where - RAM_BASE;

        switch (relocType) {
            case RELOC_TYPE_ABS_S:
            case RELOC_TYPE_ABS_D:
                t = *valThereP;

                (*valThereP) += syms[whichSym].addr;

                if (IS_IN_FLASH(syms[whichSym].addr)) {
                    (*valThereP) -= FLASH_BASE + BINARY_RELOC_OFFSET;
                    nanoRelocs[outNumRelocs].type = NANO_RELOC_TYPE_FLASH;
                }
                else if (IS_IN_RAM(syms[whichSym].addr)) {
                    (*valThereP) -= RAM_BASE;
                    nanoRelocs[outNumRelocs].type = NANO_RELOC_TYPE_RAM;
                }
                else {
                    fprintf(stderr, "Weird reloc %" PRIu32 " to symbol %" PRIu32 " in unknown memory space (addr 0x%08" PRIX32 ")\n",
                            i, whichSym, syms[whichSym].addr);
                    goto out;
                }
                if (verbose)
                    fprintf(stderr, "  -> Abs reference fixed up 0x%08" PRIX32 " -> 0x%08" PRIX32 "\n", t, *valThereP);
                break;

            case RELOC_TYPE_SECT:
                if (syms[whichSym].addr) {
                    fprintf(stderr, "Weird sect reloc %" PRIu32 " to symbol %" PRIu32 " with nonzero addr 0x%08" PRIX32 "\n",
                            i, whichSym, syms[whichSym].addr);
                    goto out;
                }

                t = *valThereP;

                if (IS_IN_FLASH(*valThereP)) {
                    nanoRelocs[outNumRelocs].type = NANO_RELOC_TYPE_FLASH;
                    *valThereP -= FLASH_BASE + BINARY_RELOC_OFFSET;
                }
                else if (IS_IN_RAM(*valThereP)) {
                    nanoRelocs[outNumRelocs].type = NANO_RELOC_TYPE_RAM;
                    *valThereP -= RAM_BASE;
                }
                else {
                    fprintf(stderr, "Weird sec reloc %" PRIu32 " to symbol %" PRIu32
                                    " in unknown memory space (addr 0x%08" PRIX32 ")\n",
                                    i, whichSym, *valThereP);
                    goto out;
                }
                if (verbose)
                    fprintf(stderr, "  -> Sect reference fixed up 0x%08" PRIX32 " -> 0x%08" PRIX32 "\n", t, *valThereP);
                break;

            default:
                fprintf(stderr, "Weird reloc %" PRIX32 " type %" PRIX32 " to symbol %" PRIX32 "\n", i, relocType, whichSym);
                goto out;
        }

        if (verbose)
            fprintf(stderr, "  -> Nano reloc calculated as 0x%08" PRIX32 ",0x%02" PRIX8 "\n", nanoRelocs[i].ofstInRam, nanoRelocs[i].type);
        outNumRelocs++;
    }

    packedNanoRelocs = packNanoRelocs(nanoRelocs, outNumRelocs, &packedNanoRelocSz, verbose);

    //overwrite original relocs and symtab with nanorelocs and adjust sizes
    memcpy(relocs, packedNanoRelocs, packedNanoRelocSz);
    bufUsed -= sizeof(struct RelocEntry[numRelocs]);
    bufUsed -= sizeof(struct SymtabEntry[numSyms]);
    bufUsed += packedNanoRelocSz;
    assertMem(bufUsed, bufSz);
    sect->rel_end = sect->rel_start + packedNanoRelocSz;

    //sanity
    if (sect->rel_end - FLASH_BASE != bufUsed) {
        fprintf(stderr, "Relocs end and file end not coincident\n");
        goto out;
    }

    //adjust headers for easy access (RAM)
    if (!IS_IN_RAM(sect->data_start) || !IS_IN_RAM(sect->data_end) || !IS_IN_RAM(sect->bss_start) ||
        !IS_IN_RAM(sect->bss_end) || !IS_IN_RAM(sect->got_start) || !IS_IN_RAM(sect->got_end)) {
        fprintf(stderr, "data, bss, or got not in ram\n");
        goto out;
    }
    sect->data_start -= RAM_BASE;
    sect->data_end -= RAM_BASE;
    sect->bss_start -= RAM_BASE;
    sect->bss_end -= RAM_BASE;
    sect->got_start -= RAM_BASE;
    sect->got_end -= RAM_BASE;

    //adjust headers for easy access (FLASH)
    if (!IS_IN_FLASH(sect->data_data) || !IS_IN_FLASH(sect->rel_start) || !IS_IN_FLASH(sect->rel_end)) {
        fprintf(stderr, "data.data, or rel not in flash\n");
        goto out;
    }
    sect->data_data -= FLASH_BASE + BINARY_RELOC_OFFSET;
    sect->rel_start -= FLASH_BASE + BINARY_RELOC_OFFSET;
    sect->rel_end -= FLASH_BASE + BINARY_RELOC_OFFSET;

    ret = finalizeAndWrite(buf, bufUsed, bufSz, out, layoutFlags, appId, chreApi);
out:
    free(nanoRelocs);
    return ret;
}

static void elfExtractSectionPointer(const Elf_Data *data, const char *name, struct ElfNanoApp *app)
{
    // Maps section names to their byte offset in struct ElfNanoApp. Note that
    // this assumes that the linker script puts text/code in the .flash section,
    // RW data in .data, that relocs for .data are included in .rel.data, and
    // the symbol table is emitted in .symtab
    const struct SectionMap {
        const char *name;
        size_t offset;
    } sectionMap[] = {
        {
            .name = ".flash",
            .offset = offsetof(struct ElfNanoApp, flash),
        },
        {
            .name = ".data",
            .offset = offsetof(struct ElfNanoApp, data),
        },
        {
            .name = ".rel.data",
            .offset = offsetof(struct ElfNanoApp, relocs),
        },
        {
            .name = ".symtab",
            .offset = offsetof(struct ElfNanoApp, symtab),
        },
    };
    struct ElfAppSection *appSection;
    uint8_t *appBytes = (uint8_t *) app;

    for (size_t i = 0; i < ARRAY_SIZE(sectionMap); i++) {
        if (strcmp(name, sectionMap[i].name) != 0) {
            continue;
        }
        appSection = (struct ElfAppSection *) &appBytes[sectionMap[i].offset];

        appSection->data = data->d_buf;
        appSection->size = data->d_size;

        DBG("Found section %s with size %zu", name, appSection->size);
        break;
    }
}

// Populates a struct ElfNanoApp with data parsed from the ELF
static bool elfParse(Elf *elf, struct ElfNanoApp *app)
{
    size_t shdrstrndx;
    Elf_Scn *scn = NULL;
    GElf_Shdr shdr;
    char *sectionName;
    Elf_Data *elf_data;

    memset(app, 0, sizeof(*app));
    if (elf_getshdrstrndx(elf, &shdrstrndx) != 0) {
        ELF_ERR("Couldn't get section name string table index");
        return false;
    }

    while ((scn = elf_nextscn(elf, scn)) != NULL) {
        if (gelf_getshdr(scn, &shdr) != &shdr) {
            ELF_ERR("Error getting section header");
            return false;
        }
        sectionName = elf_strptr(elf, shdrstrndx, shdr.sh_name);

        elf_data = elf_getdata(scn, NULL);
        if (!elf_data) {
            ELF_ERR("Error getting data for section %s", sectionName);
            return false;
        }

        elfExtractSectionPointer(elf_data, sectionName, app);
    }

    return true;
}

static bool loadNanoappElfFile(const char *fileName, struct ElfNanoApp *app)
{
    int fd;
    Elf *elf;

    if (elf_version(EV_CURRENT) == EV_NONE) {
        ELF_ERR("Failed to initialize ELF library");
        return false;
    }

    fd = open(fileName, O_RDONLY, 0);
    if (fd < 0) {
        ERR("Failed to open file %s for reading: %s", fileName, strerror(errno));
        return false;
    }

    elf = elf_begin(fd, ELF_C_READ, NULL);
    if (elf == NULL) {
        ELF_ERR("Failed to open ELF");
        return false;
    }

    if (!elfParse(elf, app)) {
        ERR("Failed to parse ELF file");
        return false;
    }

    return true;
}

// Subtracts the fixed memory region offset from an absolute address and returns
// the associated NANO_RELOC_* value, or NANO_RELOC_LAST if the address is not
// in the expected range.
// Not strictly tied to ELF usage, but handled slightly differently.
static uint8_t fixupAddrElf(uint32_t *addr)
{
    uint8_t type;

    // TODO: this assumes that the host running this tool has the same
    // endianness as the image file/target processor
    if (IS_IN_FLASH(*addr)) {
        DBG("Fixup addr 0x%08" PRIX32 " (flash) --> 0x%08" PRIX32, *addr,
            (uint32_t) (*addr - (FLASH_BASE + BINARY_RELOC_OFFSET)));
        *addr -= FLASH_BASE + BINARY_RELOC_OFFSET;
        type = NANO_RELOC_TYPE_FLASH;
    } else if (IS_IN_RAM(*addr)) {
        DBG("Fixup addr 0x%08" PRIX32 " (ram)   --> 0x%08" PRIX32, *addr,
            *addr - RAM_BASE);
        *addr -= RAM_BASE;
        type = NANO_RELOC_TYPE_RAM;
    } else {
        DBG("Error: invalid address 0x%08" PRIX32, *addr);
        type = NANO_RELOC_LAST;
    }

    return type;
}

// Fixup addresses in the header to be relative. Not strictly tied to the ELF
// format, but used only in that program flow in the current implementation.
static bool fixupHeaderElf(const struct ElfNanoApp *app)
{
    struct BinHdr *hdr = (struct BinHdr *) app->flash.data;

    DBG("Appyling fixups to header");
    if (fixupAddrElf(&hdr->sect.data_start) != NANO_RELOC_TYPE_RAM ||
        fixupAddrElf(&hdr->sect.data_end)   != NANO_RELOC_TYPE_RAM ||
        fixupAddrElf(&hdr->sect.bss_start)  != NANO_RELOC_TYPE_RAM ||
        fixupAddrElf(&hdr->sect.bss_end)    != NANO_RELOC_TYPE_RAM ||
        fixupAddrElf(&hdr->sect.got_start)  != NANO_RELOC_TYPE_RAM ||
        fixupAddrElf(&hdr->sect.got_end)    != NANO_RELOC_TYPE_RAM) {
        ERR(".data, .bss, or .got not in RAM address space!");
        return false;
    }

    if (fixupAddrElf(&hdr->sect.rel_start) != NANO_RELOC_TYPE_FLASH ||
        fixupAddrElf(&hdr->sect.rel_end)   != NANO_RELOC_TYPE_FLASH ||
        fixupAddrElf(&hdr->sect.data_data) != NANO_RELOC_TYPE_FLASH) {
        ERR(".data loadaddr, or .relocs not in flash address space!");
        return false;
    }

    if (fixupAddrElf(&hdr->vec.init)   != NANO_RELOC_TYPE_FLASH ||
        fixupAddrElf(&hdr->vec.end)    != NANO_RELOC_TYPE_FLASH ||
        fixupAddrElf(&hdr->vec.handle) != NANO_RELOC_TYPE_FLASH) {
        ERR("Entry point(s) not in flash address space!");
        return false;
    }

    return true;
}

// Fixup addresses in .data, .init_array/.fini_array, and .got, and generates
// packed array of nano reloc entries. The app header must have already been
// fixed up.
static bool genElfNanoRelocs(struct ElfNanoApp *app, bool verbose)
{
    const struct BinHdr *hdr = (const struct BinHdr *) app->flash.data;
    const struct SectInfo *sect = &hdr->sect;
    bool success = false;

    size_t numDataRelocs = app->relocs.size / sizeof(Elf32_Rel);
    size_t gotCount = (sect->got_end - sect->got_start) / sizeof(uint32_t);
    size_t numInitFuncs  = (sect->bss_start - sect->data_end) / sizeof(uint32_t);

    size_t totalRelocCount = (numDataRelocs + numInitFuncs + gotCount);
    struct NanoRelocEntry *nanoRelocs = malloc(
        totalRelocCount * sizeof(struct NanoRelocEntry));
    if (!nanoRelocs) {
        ERR("Couldn't allocate memory for nano relocs! Needed %zu bytes",
            totalRelocCount * sizeof(struct NanoRelocEntry));
        return false;
    }

    uint8_t *data = app->data.data;
    const Elf32_Rel *relocs = (const Elf32_Rel *) app->relocs.data;
    const Elf32_Sym *syms   = (const Elf32_Sym *) app->symtab.data;
    size_t numRelocs = 0;

    DBG("Parsing relocs for .data (%zu):", numDataRelocs);
    for (size_t i = 0; i < numDataRelocs; i++) {
        uint32_t type = ELF32_R_TYPE(relocs[i].r_info);
        uint32_t sym = ELF32_R_SYM(relocs[i].r_info);

        DBG(" [%3zu] 0x%08" PRIx32 " type %2" PRIu32 " symIdx %3" PRIu32
            " --> 0x%08" PRIx32, i, relocs[i].r_offset, type, sym,
            syms[sym].st_value);
        // Note that R_ARM_TARGET1 is used for .init_array/.fini_array support,
        // and can be interpreted either as ABS32 or REL32, depending on the
        // runtime; we expect it to be ABS32.
        if (type == R_ARM_ABS32 || type == R_ARM_TARGET1) {
            if (!IS_IN_RAM(relocs[i].r_offset)) {
                ERR("Reloc for .data not in RAM address range!");
                goto out;
            }
            uint32_t offset = relocs[i].r_offset - RAM_BASE;
            uint32_t *addr = (uint32_t *) &data[offset];

            nanoRelocs[numRelocs].type = fixupAddrElf(addr);
            nanoRelocs[numRelocs].ofstInRam = offset;
            numRelocs++;
        } else {
            // TODO: Assuming that the ELF only contains absolute addresses in
            // the .data section; may need to handle other relocation types in
            // the future
            ERR("Error: Unexpected reloc type %" PRIu32 " at index %zu",
                type, i);
            goto out;
        }
    }

    DBG("Updating GOT entries (%zu):", gotCount);
    for (uint32_t offset = sect->got_start; offset < sect->got_end;
            offset += sizeof(uint32_t)) {
        uint32_t *addr = (uint32_t *) &data[offset];
        // Skip values that are set to 0, these seem to be padding (?)
        if (*addr) {
            nanoRelocs[numRelocs].type = fixupAddrElf(addr);
            nanoRelocs[numRelocs].ofstInRam = offset;
            numRelocs++;
        }
    }

    uint32_t packedNanoRelocSz = 0;
    app->packedNanoRelocs.data = packNanoRelocs(
        nanoRelocs, numRelocs, &packedNanoRelocSz, verbose);
    app->packedNanoRelocs.size = packedNanoRelocSz;
    success = true;
out:
    free(nanoRelocs);
    return success;
}

static int handleAppStatic(const char *fileName, FILE *out, uint32_t layoutFlags, uint64_t appId, uint32_t appVer, uint32_t chreApi, bool verbose)
{
    struct ElfNanoApp app;

    if (!loadNanoappElfFile(fileName, &app)
            || !fixupHeaderElf(&app)
            || !genElfNanoRelocs(&app, verbose)) {
        exit(2);
    }

    // Construct a single contiguous buffer, with extra room to fit the
    // ImageHeader that will be prepended by finalizeAndWrite(). Note that this
    // will allocate a bit more space than is needed, because some of the data
    // from BinHdr will get discarded.
    // TODO: this should be refactored to just write the binary components in
    // order rather than allocating a big buffer, and moving data around
    size_t bufSize = app.flash.size + app.data.size + app.packedNanoRelocs.size
        + sizeof(struct ImageHeader);
    uint8_t *buf = malloc(bufSize);
    if (!buf) {
        ERR("Failed to allocate %zu bytes for final app", bufSize);
        exit(2);
    }

    size_t offset = 0;
    memcpy(buf, app.flash.data, app.flash.size);
    offset += app.flash.size;
    memcpy(&buf[offset], app.data.data, app.data.size);
    offset += app.data.size;
    memcpy(&buf[offset], app.packedNanoRelocs.data, app.packedNanoRelocs.size);
    offset += app.packedNanoRelocs.size;

    // Update rel_end in the header to reflect the packed reloc size
    struct BinHdr *hdr = (struct BinHdr *) buf;
    hdr->sect.rel_end = hdr->sect.rel_start + app.packedNanoRelocs.size;
    hdr->hdr.appVer = appVer;

    return finalizeAndWrite(buf, offset, bufSize, out, layoutFlags, appId, chreApi);
    // TODO: should free all memory we allocated... just letting the OS handle
    // it for now
}

static int handleKey(uint8_t **pbuf, uint32_t bufUsed, FILE *out, uint32_t layoutFlags, uint64_t appId, uint64_t keyId)
{
    uint8_t *buf = *pbuf;
    struct KeyInfo ki = { .data = keyId };
    bool good = true;

    struct ImageHeader outHeader = {
        .aosp = (struct nano_app_binary_t) {
            .header_version = 1,
            .magic = NANOAPP_AOSP_MAGIC,
            .app_id = appId,
        },
        .layout = (struct ImageLayout) {
            .magic = GOOGLE_LAYOUT_MAGIC,
            .version = 1,
            .payload = LAYOUT_KEY,
            .flags = layoutFlags,
        },
    };

    good = good && fwrite(&outHeader, sizeof(outHeader), 1, out) == 1;
    good = good && fwrite(&ki, sizeof(ki), 1, out) ==  1;
    good = good && fwrite(buf, bufUsed, 1, out) == 1;

    return good ? 0 : 2;
}

static int handleOs(uint8_t **pbuf, uint32_t bufUsed, FILE *out, uint32_t layoutFlags, bool bare)
{
    uint8_t *buf = *pbuf;
    bool good;

    struct OsUpdateHdr os = {
        .magic = OS_UPDT_MAGIC,
        .marker = OS_UPDT_MARKER_INPROGRESS,
        .size = bufUsed
    };

    struct ImageHeader outHeader = {
        .aosp = (struct nano_app_binary_t) {
            .header_version = 1,
            .magic = NANOAPP_AOSP_MAGIC,
        },
        .layout = (struct ImageLayout) {
            .magic = GOOGLE_LAYOUT_MAGIC,
            .version = 1,
            .payload = LAYOUT_OS,
            .flags = layoutFlags,
        },
    };

    if (!bare)
        good = fwrite(&outHeader, sizeof(outHeader), 1, out) == 1;
    else
        good = fwrite(&os, sizeof(os), 1, out) == 1;
    good = good && fwrite(buf, bufUsed, 1, out) == 1;

    return good ? 0 : 2;
}

int main(int argc, char **argv)
{
    uint32_t bufUsed = 0;
    bool verbose = false;
    uint8_t *buf = NULL;
    uint64_t appId = 0;
    uint64_t keyId = 0;
    uint32_t appVer = 0;
    uint32_t chreApi = 0;
    uint32_t layoutId = 0;
    uint32_t layoutFlags = 0;
    int ret = -1;
    uint32_t *u32Arg = NULL;
    uint64_t *u64Arg = NULL;
    const char **strArg = NULL;
    const char *appName = argv[0];
    int posArgCnt = 0;
    const char *posArg[2] = { NULL };
    FILE *out = NULL;
    const char *layoutName = "app";
    const char *prev = NULL;
    bool bareData = false;
    bool staticElf = false;

    for (int i = 1; i < argc; i++) {
        char *end = NULL;
        if (argv[i][0] == '-') {
            prev = argv[i];
            if (!strcmp(argv[i], "-v"))
                verbose = true;
            else if (!strcmp(argv[i], "-r"))
                bareData = true;
            else if (!strcmp(argv[i], "-s"))
                staticElf = true;
            else if (!strcmp(argv[i], "-a"))
                u64Arg = &appId;
            else if (!strcmp(argv[i], "-c"))
                u32Arg = &chreApi;
            else if (!strcmp(argv[i], "-e"))
                u32Arg = &appVer;
            else if (!strcmp(argv[i], "-k"))
                u64Arg = &keyId;
            else if (!strcmp(argv[i], "-n"))
                strArg = &layoutName;
            else if (!strcmp(argv[i], "-i"))
                u32Arg = &layoutId;
            else if (!strcmp(argv[i], "-f"))
                u32Arg = &layoutFlags;
            else
                fatalUsage(appName, "unknown argument", argv[i]);
        } else {
            if (u64Arg) {
                uint64_t tmp = strtoull(argv[i], &end, 16);
                if (*end == '\0')
                    *u64Arg = tmp;
                u64Arg = NULL;
            } else if (u32Arg) {
                uint32_t tmp = strtoul(argv[i], &end, 16);
                if (*end == '\0')
                    *u32Arg = tmp;
                u32Arg = NULL;
            } else if (strArg) {
                    *strArg = argv[i];
                strArg = NULL;
            } else {
                if (posArgCnt < 2)
                    posArg[posArgCnt++] = argv[i];
                else
                    fatalUsage(appName, "too many positional arguments", argv[i]);
            }
            prev = NULL;
        }
    }
    if (prev)
        fatalUsage(appName, "missing argument after", prev);

    if (!posArgCnt)
        fatalUsage(appName, "missing input file name", NULL);

    if (!layoutId) {
        if (strcmp(layoutName, "app") == 0)
            layoutId = LAYOUT_APP;
        else if (strcmp(layoutName, "os") == 0)
            layoutId = LAYOUT_OS;
        else if (strcmp(layoutName, "key") == 0)
            layoutId = LAYOUT_KEY;
        else
            fatalUsage(appName, "Invalid layout name", layoutName);
    }

    if (staticElf && layoutId != LAYOUT_APP)
        fatalUsage(appName, "Only app layout is supported for static option", NULL);

    if (layoutId == LAYOUT_APP && !appId)
        fatalUsage(appName, "App layout requires app ID", NULL);
    if (layoutId == LAYOUT_KEY && !keyId)
        fatalUsage(appName, "Key layout requires key ID", NULL);
    if (layoutId == LAYOUT_OS && (keyId || appId))
        fatalUsage(appName, "OS layout does not need any ID", NULL);

    if (!staticElf) {
        buf = loadFile(posArg[0], &bufUsed);
        fprintf(stderr, "Read %" PRIu32 " bytes\n", bufUsed);
    }

    if (!posArg[1])
        out = stdout;
    else
        out = fopen(posArg[1], "w");
    if (!out)
        fatalUsage(appName, "failed to create/open output file", posArg[1]);

    switch(layoutId) {
    case LAYOUT_APP:
        if (staticElf) {
            ret = handleAppStatic(posArg[0], out, layoutFlags, appId, appVer, chreApi, verbose);
        } else {
            ret = handleApp(&buf, bufUsed, out, layoutFlags, appId, appVer, chreApi, verbose);
        }
        break;
    case LAYOUT_KEY:
        ret = handleKey(&buf, bufUsed, out, layoutFlags, appId, keyId);
        break;
    case LAYOUT_OS:
        ret = handleOs(&buf, bufUsed, out, layoutFlags, bareData);
        break;
    }

    free(buf);
    fclose(out);
    return ret;
}
