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

static void elfN(bswap_ehdr)(ElfN(Ehdr) *ehdr)
{
    bswaps(&ehdr->e_type);            /* Object file type */
    bswaps(&ehdr->e_machine);         /* Architecture */
    bswaps(&ehdr->e_version);         /* Object file version */
    bswaps(&ehdr->e_entry);           /* Entry point virtual address */
    bswaps(&ehdr->e_phoff);           /* Program header table file offset */
    bswaps(&ehdr->e_shoff);           /* Section header table file offset */
    bswaps(&ehdr->e_flags);           /* Processor-specific flags */
    bswaps(&ehdr->e_ehsize);          /* ELF header size in bytes */
    bswaps(&ehdr->e_phentsize);       /* Program header table entry size */
    bswaps(&ehdr->e_phnum);           /* Program header table entry count */
    bswaps(&ehdr->e_shentsize);       /* Section header table entry size */
    bswaps(&ehdr->e_shnum);           /* Section header table entry count */
    bswaps(&ehdr->e_shstrndx);        /* Section header string table index */
}

static void elfN(bswap_phdr)(ElfN(Phdr) *phdr)
{
    bswaps(&phdr->p_type);            /* Segment type */
    bswaps(&phdr->p_flags);           /* Segment flags */
    bswaps(&phdr->p_offset);          /* Segment file offset */
    bswaps(&phdr->p_vaddr);           /* Segment virtual address */
    bswaps(&phdr->p_paddr);           /* Segment physical address */
    bswaps(&phdr->p_filesz);          /* Segment size in file */
    bswaps(&phdr->p_memsz);           /* Segment size in memory */
    bswaps(&phdr->p_align);           /* Segment alignment */
}

static void elfN(bswap_shdr)(ElfN(Shdr) *shdr)
{
    bswaps(&shdr->sh_name);
    bswaps(&shdr->sh_type);
    bswaps(&shdr->sh_flags);
    bswaps(&shdr->sh_addr);
    bswaps(&shdr->sh_offset);
    bswaps(&shdr->sh_size);
    bswaps(&shdr->sh_link);
    bswaps(&shdr->sh_info);
    bswaps(&shdr->sh_addralign);
    bswaps(&shdr->sh_entsize);
}

static void elfN(bswap_sym)(ElfN(Sym) *sym)
{
    bswaps(&sym->st_name);
    bswaps(&sym->st_value);
    bswaps(&sym->st_size);
    bswaps(&sym->st_shndx);
}

static void elfN(bswap_dyn)(ElfN(Dyn) *dyn)
{
    bswaps(&dyn->d_tag);              /* Dynamic type tag */
    bswaps(&dyn->d_un.d_ptr);         /* Dynamic ptr or val, in union */
}

static void elfN(search_symtab)(ElfN(Shdr) *shdr, unsigned sym_idx,
                                void *buf, bool need_bswap)
{
    unsigned str_idx = shdr[sym_idx].sh_link;
    ElfN(Sym) *target_sym = buf + shdr[sym_idx].sh_offset;
    unsigned sym_n = shdr[sym_idx].sh_size / sizeof(*target_sym);
    const char *str = buf + shdr[str_idx].sh_offset;

    for (unsigned i = 0; i < sym_n; ++i) {
        const char *name;
        ElfN(Sym) sym;

        memcpy(&sym, &target_sym[i], sizeof(sym));
        if (need_bswap) {
            elfN(bswap_sym)(&sym);
        }
        name = str + sym.st_name;

        if (sigreturn_sym && strcmp(sigreturn_sym, name) == 0) {
            sigreturn_addr = sym.st_value;
        }
        if (rt_sigreturn_sym && strcmp(rt_sigreturn_sym, name) == 0) {
            rt_sigreturn_addr = sym.st_value;
        }
    }
}

static void elfN(bswap_ps_hdrs)(ElfN(Ehdr) *ehdr)
{
    ElfN(Phdr) *phdr = (void *)ehdr + ehdr->e_phoff;
    ElfN(Shdr) *shdr = (void *)ehdr + ehdr->e_shoff;
    ElfN(Half) i;

    for (i = 0; i < ehdr->e_phnum; ++i) {
        elfN(bswap_phdr)(&phdr[i]);
    }

    for (i = 0; i < ehdr->e_shnum; ++i) {
        elfN(bswap_shdr)(&shdr[i]);
    }
}

static void elfN(process)(FILE *outf, void *buf, long len, bool need_bswap)
{
    ElfN(Ehdr) *ehdr = buf;
    ElfN(Phdr) *phdr;
    ElfN(Shdr) *shdr;
    unsigned phnum, shnum;
    unsigned dynamic_ofs = 0;
    unsigned dynamic_addr = 0;
    unsigned symtab_idx = 0;
    unsigned dynsym_idx = 0;
    unsigned first_segsz = 0;
    int errors = 0;

    if (need_bswap) {
        elfN(bswap_ehdr)(buf);
        elfN(bswap_ps_hdrs)(buf);
    }

    phnum = ehdr->e_phnum;
    phdr = buf + ehdr->e_phoff;
    shnum = ehdr->e_shnum;
    shdr = buf + ehdr->e_shoff;
    for (unsigned i = 0; i < shnum; ++i) {
        switch (shdr[i].sh_type) {
        case SHT_SYMTAB:
            symtab_idx = i;
            break;
        case SHT_DYNSYM:
            dynsym_idx = i;
            break;
        }
    }

    /*
     * Validate the VDSO is created as we expect: that PT_PHDR,
     * PT_DYNAMIC, and PT_NOTE located in a writable data segment.
     * PHDR and DYNAMIC require relocation, and NOTE will get the
     * linux version number.
     */
    for (unsigned i = 0; i < phnum; ++i) {
        if (phdr[i].p_type != PT_LOAD) {
            continue;
        }
        if (first_segsz != 0) {
            fprintf(stderr, "Multiple LOAD segments\n");
            errors++;
        }
        if (phdr[i].p_offset != 0) {
            fprintf(stderr, "LOAD segment does not cover EHDR\n");
            errors++;
        }
        if (phdr[i].p_vaddr != 0) {
            fprintf(stderr, "LOAD segment not loaded at address 0\n");
            errors++;
        }
        /*
         * Extend the program header to cover the entire VDSO, so that
         * load_elf_vdso() loads everything, including section headers.
         *
         * Require that there is no .bss, since it would break this
         * approach.
         */
        if (phdr[i].p_filesz != phdr[i].p_memsz) {
            fprintf(stderr, "LOAD segment's filesz and memsz differ\n");
            errors++;
        }
        if (phdr[i].p_filesz > len) {
            fprintf(stderr, "LOAD segment is larger than the whole VDSO\n");
            errors++;
        }
        phdr[i].p_filesz = len;
        phdr[i].p_memsz = len;
        first_segsz = len;
        if (first_segsz < ehdr->e_phoff + phnum * sizeof(*phdr)) {
            fprintf(stderr, "LOAD segment does not cover PHDRs\n");
            errors++;
        }
        if ((phdr[i].p_flags & (PF_R | PF_W)) != (PF_R | PF_W)) {
            fprintf(stderr, "LOAD segment is not read-write\n");
            errors++;
        }
    }
    for (unsigned i = 0; i < phnum; ++i) {
        const char *which;

        switch (phdr[i].p_type) {
        case PT_PHDR:
            which = "PT_PHDR";
            break;
        case PT_NOTE:
            which = "PT_NOTE";
            break;
        case PT_DYNAMIC:
            dynamic_ofs = phdr[i].p_offset;
            dynamic_addr = phdr[i].p_vaddr;
            which = "PT_DYNAMIC";
            break;
        default:
            continue;
        }
        if (first_segsz < phdr[i].p_vaddr + phdr[i].p_filesz) {
            fprintf(stderr, "LOAD segment does not cover %s\n", which);
            errors++;
        }
    }
    if (errors) {
        exit(EXIT_FAILURE);
    }

    /* Relocate the program headers. */
    for (unsigned i = 0; i < phnum; ++i) {
        output_reloc(outf, buf, &phdr[i].p_vaddr);
        output_reloc(outf, buf, &phdr[i].p_paddr);
    }

    /* Relocate the section headers. */
    for (unsigned i = 0; i < shnum; ++i) {
        output_reloc(outf, buf, &shdr[i].sh_addr);
    }

    /* Relocate the DYNAMIC entries. */
    if (dynamic_addr) {
        ElfN(Dyn) *target_dyn = buf + dynamic_ofs;
        __typeof(((ElfN(Dyn) *)target_dyn)->d_tag) tag;

        do {
            ElfN(Dyn) dyn;

            memcpy(&dyn, target_dyn, sizeof(dyn));
            if (need_bswap) {
                elfN(bswap_dyn)(&dyn);
            }
            tag = dyn.d_tag;

            switch (tag) {
            case DT_HASH:
            case DT_SYMTAB:
            case DT_STRTAB:
            case DT_VERDEF:
            case DT_VERSYM:
            case DT_PLTGOT:
            case DT_ADDRRNGLO ... DT_ADDRRNGHI:
                /* These entries store an address in the entry. */
                output_reloc(outf, buf, &target_dyn->d_un.d_val);
                break;

            case DT_NULL:
            case DT_STRSZ:
            case DT_SONAME:
            case DT_DEBUG:
            case DT_FLAGS:
            case DT_FLAGS_1:
            case DT_SYMBOLIC:
            case DT_BIND_NOW:
            case DT_VERDEFNUM:
            case DT_VALRNGLO ... DT_VALRNGHI:
                /* These entries store an integer in the entry. */
                break;

            case DT_SYMENT:
                if (dyn.d_un.d_val != sizeof(ElfN(Sym))) {
                    fprintf(stderr, "VDSO has incorrect dynamic symbol size\n");
                    errors++;
                }
                break;

            case DT_REL:
            case DT_RELSZ:
            case DT_RELA:
            case DT_RELASZ:
                /*
                 * These entries indicate that the VDSO was built incorrectly.
                 * It should not have any real relocations.
                 * ??? The RISC-V toolchain will emit these even when there
                 * are no relocations.  Validate zeros.
                 */
                if (dyn.d_un.d_val != 0) {
                    fprintf(stderr, "VDSO has dynamic relocations\n");
                    errors++;
                }
                break;
            case DT_RELENT:
            case DT_RELAENT:
            case DT_TEXTREL:
                /* These entries store an integer in the entry. */
                /* Should not be required; see above. */
                break;

            case DT_NEEDED:
            case DT_VERNEED:
            case DT_PLTREL:
            case DT_JMPREL:
            case DT_RPATH:
            case DT_RUNPATH:
                fprintf(stderr, "VDSO has external dependencies\n");
                errors++;
                break;

            case PT_LOPROC + 3:
                if (ehdr->e_machine == EM_PPC64) {
                    break;  /* DT_PPC64_OPT: integer bitmask */
                }
                goto do_default;

            default:
            do_default:
                /* This is probably something target specific. */
                fprintf(stderr, "VDSO has unknown DYNAMIC entry (%lx)\n",
                        (unsigned long)tag);
                errors++;
                break;
            }
            target_dyn++;
        } while (tag != DT_NULL);
        if (errors) {
            exit(EXIT_FAILURE);
        }
    }

    /* Relocate the dynamic symbol table. */
    if (dynsym_idx) {
        ElfN(Sym) *target_sym = buf + shdr[dynsym_idx].sh_offset;
        unsigned sym_n = shdr[dynsym_idx].sh_size / sizeof(*target_sym);

        for (unsigned i = 0; i < sym_n; ++i) {
            output_reloc(outf, buf, &target_sym[i].st_value);
        }
    }

    /* Search both dynsym and symtab for the signal return symbols. */
    if (dynsym_idx) {
        elfN(search_symtab)(shdr, dynsym_idx, buf, need_bswap);
    }
    if (symtab_idx) {
        elfN(search_symtab)(shdr, symtab_idx, buf, need_bswap);
    }

    if (need_bswap) {
        elfN(bswap_ps_hdrs)(buf);
        elfN(bswap_ehdr)(buf);
    }
}
