/*
 * Post-process a vdso elf image for inclusion into qemu.
 *
 * Copyright 2023 Linaro, Ltd.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <endian.h>
#include <unistd.h>
#include "elf.h"


#define bswap_(p)  _Generic(*(p), \
                            uint16_t: __builtin_bswap16,       \
                            uint32_t: __builtin_bswap32,       \
                            uint64_t: __builtin_bswap64,       \
                            int16_t: __builtin_bswap16,        \
                            int32_t: __builtin_bswap32,        \
                            int64_t: __builtin_bswap64)
#define bswaps(p) (*(p) = bswap_(p)(*(p)))

static void output_reloc(FILE *outf, void *buf, void *loc)
{
    fprintf(outf, "    0x%08tx,\n", loc - buf);
}

static const char *sigreturn_sym;
static const char *rt_sigreturn_sym;

static unsigned sigreturn_addr;
static unsigned rt_sigreturn_addr;

#define N 32
#define elfN(x)  elf32_##x
#define ElfN(x)  Elf32_##x
#include "gen-vdso-elfn.c.inc"
#undef N
#undef elfN
#undef ElfN

#define N 64
#define elfN(x)  elf64_##x
#define ElfN(x)  Elf64_##x
#include "gen-vdso-elfn.c.inc"
#undef N
#undef elfN
#undef ElfN


int main(int argc, char **argv)
{
    FILE *inf, *outf;
    long total_len;
    const char *prefix = "vdso";
    const char *inf_name;
    const char *outf_name = NULL;
    unsigned char *buf;
    bool need_bswap;

    while (1) {
        int opt = getopt(argc, argv, "o:p:r:s:");
        if (opt < 0) {
            break;
        }
        switch (opt) {
        case 'o':
            outf_name = optarg;
            break;
        case 'p':
            prefix = optarg;
            break;
        case 'r':
            rt_sigreturn_sym = optarg;
            break;
        case 's':
            sigreturn_sym = optarg;
            break;
        default:
        usage:
            fprintf(stderr, "usage: [-p prefix] [-r rt-sigreturn-name] "
                    "[-s sigreturn-name] -o output-file input-file\n");
            return EXIT_FAILURE;
        }
    }

    if (optind >= argc || outf_name == NULL) {
        goto usage;
    }
    inf_name = argv[optind];

    /*
     * Open the input and output files.
     */
    inf = fopen(inf_name, "rb");
    if (inf == NULL) {
        goto perror_inf;
    }
    outf = fopen(outf_name, "w");
    if (outf == NULL) {
        goto perror_outf;
    }

    /*
     * Read the input file into a buffer.
     * We expect the vdso to be small, on the order of one page,
     * therefore we do not expect a partial read.
     */
    fseek(inf, 0, SEEK_END);
    total_len = ftell(inf);
    fseek(inf, 0, SEEK_SET);

    buf = malloc(total_len);
    if (buf == NULL) {
        goto perror_inf;
    }

    errno = 0;
    if (fread(buf, 1, total_len, inf) != total_len) {
        if (errno) {
            goto perror_inf;
        }
        fprintf(stderr, "%s: incomplete read\n", inf_name);
        return EXIT_FAILURE;
    }
    fclose(inf);

    /*
     * Identify which elf flavor we're processing.
     * The first 16 bytes of the file are e_ident.
     */

    if (buf[EI_MAG0] != ELFMAG0 || buf[EI_MAG1] != ELFMAG1 ||
        buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3) {
        fprintf(stderr, "%s: not an elf file\n", inf_name);
        return EXIT_FAILURE;
    }
    switch (buf[EI_DATA]) {
    case ELFDATA2LSB:
        need_bswap = BYTE_ORDER != LITTLE_ENDIAN;
        break;
    case ELFDATA2MSB:
        need_bswap = BYTE_ORDER != BIG_ENDIAN;
        break;
    default:
        fprintf(stderr, "%s: invalid elf EI_DATA (%u)\n",
                inf_name, buf[EI_DATA]);
        return EXIT_FAILURE;
    }

    /*
     * We need to relocate the VDSO image.  The one built into the kernel
     * is built for a fixed address.  The one we built for QEMU is not,
     * since that requires close control of the guest address space.
     *
     * Output relocation addresses as we go.
     */

    fprintf(outf,
            "/* Automatically generated by linux-user/gen-vdso.c. */\n"
            "\n"
            "static const unsigned %s_relocs[] = {\n", prefix);

    switch (buf[EI_CLASS]) {
    case ELFCLASS32:
        elf32_process(outf, buf, total_len, need_bswap);
        break;
    case ELFCLASS64:
        elf64_process(outf, buf, total_len, need_bswap);
        break;
    default:
        fprintf(stderr, "%s: invalid elf EI_CLASS (%u)\n",
                inf_name, buf[EI_CLASS]);
        return EXIT_FAILURE;
    }

    fprintf(outf, "};\n\n");   /* end vdso_relocs. */

    /*
     * Write out the vdso image now, after we made local changes.
     */
    fprintf(outf,
            "static const uint8_t %s_image[] = {",
            prefix);
    for (long i = 0; i < total_len; ++i) {
        if (i % 12 == 0) {
            fputs("\n   ", outf);
        }
        fprintf(outf, " 0x%02x,", buf[i]);
    }
    fprintf(outf, "\n};\n\n");

    fprintf(outf, "static const VdsoImageInfo %s_image_info = {\n", prefix);
    fprintf(outf, "    .image = %s_image,\n", prefix);
    fprintf(outf, "    .relocs = %s_relocs,\n", prefix);
    fprintf(outf, "    .image_size = sizeof(%s_image),\n", prefix);
    fprintf(outf, "    .reloc_count = ARRAY_SIZE(%s_relocs),\n", prefix);
    fprintf(outf, "    .sigreturn_ofs = 0x%x,\n", sigreturn_addr);
    fprintf(outf, "    .rt_sigreturn_ofs = 0x%x,\n", rt_sigreturn_addr);
    fprintf(outf, "};\n");

    /*
     * Everything should have gone well.
     */
    if (fclose(outf)) {
        goto perror_outf;
    }
    return EXIT_SUCCESS;

 perror_inf:
    perror(inf_name);
    return EXIT_FAILURE;

 perror_outf:
    perror(outf_name);
    return EXIT_FAILURE;
}
