/* This is the Linux kernel elf-loading code, ported into user space */
#include "qemu/osdep.h"
#include <sys/param.h>

#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/shm.h>

#include "qemu.h"
#include "user/tswap-target.h"
#include "user/page-protection.h"
#include "exec/page-protection.h"
#include "exec/mmap-lock.h"
#include "exec/translation-block.h"
#include "exec/tswap.h"
#include "user/guest-base.h"
#include "user-internals.h"
#include "signal-common.h"
#include "loader.h"
#include "user-mmap.h"
#include "disas/disas.h"
#include "qemu/bitops.h"
#include "qemu/path.h"
#include "qemu/queue.h"
#include "qemu/guest-random.h"
#include "qemu/units.h"
#include "qemu/selfmap.h"
#include "qemu/lockable.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "target_elf.h"
#include "target_signal.h"
#include "tcg/debuginfo.h"

#ifdef TARGET_ARM
#include "target/arm/cpu-features.h"
#endif

#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
#endif

#define ELF_OSABI   ELFOSABI_SYSV

/* from personality.h */

/*
 * Flags for bug emulation.
 *
 * These occupy the top three bytes.
 */
enum {
    ADDR_NO_RANDOMIZE = 0x0040000,      /* disable randomization of VA space */
    FDPIC_FUNCPTRS =    0x0080000,      /* userspace function ptrs point to
                                           descriptors (signal handling) */
    MMAP_PAGE_ZERO =    0x0100000,
    ADDR_COMPAT_LAYOUT = 0x0200000,
    READ_IMPLIES_EXEC = 0x0400000,
    ADDR_LIMIT_32BIT =  0x0800000,
    SHORT_INODE =       0x1000000,
    WHOLE_SECONDS =     0x2000000,
    STICKY_TIMEOUTS =   0x4000000,
    ADDR_LIMIT_3GB =    0x8000000,
};

/*
 * Personality types.
 *
 * These go in the low byte.  Avoid using the top bit, it will
 * conflict with error returns.
 */
enum {
    PER_LINUX =         0x0000,
    PER_LINUX_32BIT =   0x0000 | ADDR_LIMIT_32BIT,
    PER_LINUX_FDPIC =   0x0000 | FDPIC_FUNCPTRS,
    PER_SVR4 =          0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
    PER_SVR3 =          0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
    PER_SCOSVR3 =       0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE,
    PER_OSR5 =          0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
    PER_WYSEV386 =      0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
    PER_ISCR4 =         0x0005 | STICKY_TIMEOUTS,
    PER_BSD =           0x0006,
    PER_SUNOS =         0x0006 | STICKY_TIMEOUTS,
    PER_XENIX =         0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
    PER_LINUX32 =       0x0008,
    PER_LINUX32_3GB =   0x0008 | ADDR_LIMIT_3GB,
    PER_IRIX32 =        0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */
    PER_IRIXN32 =       0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */
    PER_IRIX64 =        0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */
    PER_RISCOS =        0x000c,
    PER_SOLARIS =       0x000d | STICKY_TIMEOUTS,
    PER_UW7 =           0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
    PER_OSF4 =          0x000f,                  /* OSF/1 v4 */
    PER_HPUX =          0x0010,
    PER_MASK =          0x00ff,
};

/*
 * Return the base personality without flags.
 */
#define personality(pers)       (pers & PER_MASK)

int info_is_fdpic(struct image_info *info)
{
    return info->personality == PER_LINUX_FDPIC;
}

#if TARGET_BIG_ENDIAN
#define ELF_DATA        ELFDATA2MSB
#else
#define ELF_DATA        ELFDATA2LSB
#endif

#ifdef USE_UID16
typedef abi_ushort      target_uid_t;
typedef abi_ushort      target_gid_t;
#else
typedef abi_uint        target_uid_t;
typedef abi_uint        target_gid_t;
#endif
typedef abi_int         target_pid_t;

#ifndef elf_check_machine
#define elf_check_machine(x) ((x) == ELF_MACHINE)
#endif

#ifndef elf_check_abi
#define elf_check_abi(x) (1)
#endif

#ifndef STACK_GROWS_DOWN
#define STACK_GROWS_DOWN 1
#endif

#ifndef STACK_ALIGNMENT
#define STACK_ALIGNMENT 16
#endif

#ifdef TARGET_ABI32
#undef ELF_CLASS
#define ELF_CLASS ELFCLASS32
#undef bswaptls
#define bswaptls(ptr) bswap32s(ptr)
#endif

#ifndef EXSTACK_DEFAULT
#define EXSTACK_DEFAULT false
#endif

/*
 * Provide fallback definitions that the target may omit.
 * One way or another, we'll get a link error if the setting of
 * HAVE_* doesn't match the implementation.
 */
#ifndef HAVE_ELF_HWCAP
abi_ulong get_elf_hwcap(CPUState *cs) { return 0; }
#endif
#ifndef HAVE_ELF_HWCAP2
abi_ulong get_elf_hwcap2(CPUState *cs) { g_assert_not_reached(); }
#define HAVE_ELF_HWCAP2 0
#endif
#ifndef HAVE_ELF_PLATFORM
const char *get_elf_platform(CPUState *cs) { return NULL; }
#endif
#ifndef HAVE_ELF_BASE_PLATFORM
const char *get_elf_base_platform(CPUState *cs) { return NULL; }
#endif

#ifndef HAVE_ELF_GNU_PROPERTY
bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
                             const uint32_t *data, struct image_info *info,
                             Error **errp)
{
    g_assert_not_reached();
}
#define HAVE_ELF_GNU_PROPERTY 0
#endif

#include "elf.h"

#define DLINFO_ITEMS 16

static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
{
    memcpy(to, from, n);
}

static void bswap_ehdr(struct elfhdr *ehdr)
{
    if (!target_needs_bswap()) {
        return;
    }

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

static void bswap_phdr(struct elf_phdr *phdr, int phnum)
{
    if (!target_needs_bswap()) {
        return;
    }

    for (int i = 0; i < phnum; ++i, ++phdr) {
        bswap32s(&phdr->p_type);        /* Segment type */
        bswap32s(&phdr->p_flags);       /* Segment flags */
        bswaptls(&phdr->p_offset);      /* Segment file offset */
        bswaptls(&phdr->p_vaddr);       /* Segment virtual address */
        bswaptls(&phdr->p_paddr);       /* Segment physical address */
        bswaptls(&phdr->p_filesz);      /* Segment size in file */
        bswaptls(&phdr->p_memsz);       /* Segment size in memory */
        bswaptls(&phdr->p_align);       /* Segment alignment */
    }
}

static void bswap_shdr(struct elf_shdr *shdr, int shnum)
{
    if (!target_needs_bswap()) {
        return;
    }

    for (int i = 0; i < shnum; ++i, ++shdr) {
        bswap32s(&shdr->sh_name);
        bswap32s(&shdr->sh_type);
        bswaptls(&shdr->sh_flags);
        bswaptls(&shdr->sh_addr);
        bswaptls(&shdr->sh_offset);
        bswaptls(&shdr->sh_size);
        bswap32s(&shdr->sh_link);
        bswap32s(&shdr->sh_info);
        bswaptls(&shdr->sh_addralign);
        bswaptls(&shdr->sh_entsize);
    }
}

static void bswap_sym(struct elf_sym *sym)
{
    if (!target_needs_bswap()) {
        return;
    }

    bswap32s(&sym->st_name);
    bswaptls(&sym->st_value);
    bswaptls(&sym->st_size);
    bswap16s(&sym->st_shndx);
}

#ifdef TARGET_MIPS
static void bswap_mips_abiflags(Mips_elf_abiflags_v0 *abiflags)
{
    if (!target_needs_bswap()) {
        return;
    }

    bswap16s(&abiflags->version);
    bswap32s(&abiflags->ases);
    bswap32s(&abiflags->isa_ext);
    bswap32s(&abiflags->flags1);
    bswap32s(&abiflags->flags2);
}
#endif

#ifdef HAVE_ELF_CORE_DUMP
static int elf_core_dump(int, const CPUArchState *);
#endif /* HAVE_ELF_CORE_DUMP */
static void load_symbols(struct elfhdr *hdr, const ImageSource *src,
                         abi_ulong load_bias);

/* Verify the portions of EHDR within E_IDENT for the target.
   This can be performed before bswapping the entire header.  */
static bool elf_check_ident(struct elfhdr *ehdr)
{
    return (ehdr->e_ident[EI_MAG0] == ELFMAG0
            && ehdr->e_ident[EI_MAG1] == ELFMAG1
            && ehdr->e_ident[EI_MAG2] == ELFMAG2
            && ehdr->e_ident[EI_MAG3] == ELFMAG3
            && ehdr->e_ident[EI_CLASS] == ELF_CLASS
            && ehdr->e_ident[EI_DATA] == ELF_DATA
            && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
}

/* Verify the portions of EHDR outside of E_IDENT for the target.
   This has to wait until after bswapping the header.  */
static bool elf_check_ehdr(struct elfhdr *ehdr)
{
    return (elf_check_machine(ehdr->e_machine)
            && elf_check_abi(ehdr->e_flags)
            && ehdr->e_ehsize == sizeof(struct elfhdr)
            && ehdr->e_phentsize == sizeof(struct elf_phdr)
            && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN));
}

/*
 * 'copy_elf_strings()' copies argument/envelope strings from user
 * memory to free pages in kernel mem. These are in a format ready
 * to be put directly into the top of new user memory.
 *
 */
static abi_ulong copy_elf_strings(int argc, char **argv, char *scratch,
                                  abi_ulong p, abi_ulong stack_limit)
{
    char *tmp;
    int len, i;
    abi_ulong top = p;

    if (!p) {
        return 0;       /* bullet-proofing */
    }

    if (STACK_GROWS_DOWN) {
        int offset = ((p - 1) % TARGET_PAGE_SIZE) + 1;
        for (i = argc - 1; i >= 0; --i) {
            tmp = argv[i];
            if (!tmp) {
                fprintf(stderr, "VFS: argc is wrong");
                exit(-1);
            }
            len = strlen(tmp) + 1;
            tmp += len;

            if (len > (p - stack_limit)) {
                return 0;
            }
            while (len) {
                int bytes_to_copy = (len > offset) ? offset : len;
                tmp -= bytes_to_copy;
                p -= bytes_to_copy;
                offset -= bytes_to_copy;
                len -= bytes_to_copy;

                memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);

                if (offset == 0) {
                    memcpy_to_target(p, scratch, top - p);
                    top = p;
                    offset = TARGET_PAGE_SIZE;
                }
            }
        }
        if (p != top) {
            memcpy_to_target(p, scratch + offset, top - p);
        }
    } else {
        int remaining = TARGET_PAGE_SIZE - (p % TARGET_PAGE_SIZE);
        for (i = 0; i < argc; ++i) {
            tmp = argv[i];
            if (!tmp) {
                fprintf(stderr, "VFS: argc is wrong");
                exit(-1);
            }
            len = strlen(tmp) + 1;
            if (len > (stack_limit - p)) {
                return 0;
            }
            while (len) {
                int bytes_to_copy = (len > remaining) ? remaining : len;

                memcpy_fromfs(scratch + (p - top), tmp, bytes_to_copy);

                tmp += bytes_to_copy;
                remaining -= bytes_to_copy;
                p += bytes_to_copy;
                len -= bytes_to_copy;

                if (remaining == 0) {
                    memcpy_to_target(top, scratch, p - top);
                    top = p;
                    remaining = TARGET_PAGE_SIZE;
                }
            }
        }
        if (p != top) {
            memcpy_to_target(top, scratch, p - top);
        }
    }

    return p;
}

/* Older linux kernels provide up to MAX_ARG_PAGES (default: 32) of
 * argument/environment space. Newer kernels (>2.6.33) allow more,
 * dependent on stack size, but guarantee at least 32 pages for
 * backwards compatibility.
 */
#define STACK_LOWER_LIMIT (32 * TARGET_PAGE_SIZE)

static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
                                 struct image_info *info)
{
    abi_ulong size, error, guard;
    int prot;

    size = guest_stack_size;
    if (size < STACK_LOWER_LIMIT) {
        size = STACK_LOWER_LIMIT;
    }

    if (STACK_GROWS_DOWN) {
        guard = TARGET_PAGE_SIZE;
        if (guard < qemu_real_host_page_size()) {
            guard = qemu_real_host_page_size();
        }
    } else {
        /* no guard page for hppa target where stack grows upwards. */
        guard = 0;
    }

    prot = PROT_READ | PROT_WRITE;
    if (info->exec_stack) {
        prot |= PROT_EXEC;
    }
    error = target_mmap(0, size + guard, prot,
                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (error == -1) {
        perror("mmap stack");
        exit(-1);
    }

    /* We reserve one extra page at the top of the stack as guard.  */
    if (STACK_GROWS_DOWN) {
        target_mprotect(error, guard, PROT_NONE);
        info->stack_limit = error + guard;
        return info->stack_limit + size - sizeof(void *);
    } else {
        info->stack_limit = error + size;
        return error;
    }
}

/**
 * zero_bss:
 *
 * Map and zero the bss.  We need to explicitly zero any fractional pages
 * after the data section (i.e. bss).  Return false on mapping failure.
 */
static bool zero_bss(abi_ulong start_bss, abi_ulong end_bss,
                     int prot, Error **errp)
{
    abi_ulong align_bss;

    /* We only expect writable bss; the code segment shouldn't need this. */
    if (!(prot & PROT_WRITE)) {
        error_setg(errp, "PT_LOAD with non-writable bss");
        return false;
    }

    align_bss = TARGET_PAGE_ALIGN(start_bss);
    end_bss = TARGET_PAGE_ALIGN(end_bss);

    if (start_bss < align_bss) {
        int flags = page_get_flags(start_bss);

        if (!(flags & PAGE_RWX)) {
            /*
             * The whole address space of the executable was reserved
             * at the start, therefore all pages will be VALID.
             * But assuming there are no PROT_NONE PT_LOAD segments,
             * a PROT_NONE page means no data all bss, and we can
             * simply extend the new anon mapping back to the start
             * of the page of bss.
             */
            align_bss -= TARGET_PAGE_SIZE;
        } else {
            /*
             * The start of the bss shares a page with something.
             * The only thing that we expect is the data section,
             * which would already be marked writable.
             * Overlapping the RX code segment seems malformed.
             */
            if (!(flags & PAGE_WRITE)) {
                error_setg(errp, "PT_LOAD with bss overlapping "
                           "non-writable page");
                return false;
            }

            /* The page is already mapped and writable. */
            memset(g2h_untagged(start_bss), 0, align_bss - start_bss);
        }
    }

    if (align_bss < end_bss &&
        target_mmap(align_bss, end_bss - align_bss, prot,
                    MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
        error_setg_errno(errp, errno, "Error mapping bss");
        return false;
    }
    return true;
}

#if defined(TARGET_ARM)
static int elf_is_fdpic(struct elfhdr *exec)
{
    return exec->e_ident[EI_OSABI] == ELFOSABI_ARM_FDPIC;
}
#elif defined(TARGET_XTENSA)
static int elf_is_fdpic(struct elfhdr *exec)
{
    return exec->e_ident[EI_OSABI] == ELFOSABI_XTENSA_FDPIC;
}
#else
/* Default implementation, always false.  */
static int elf_is_fdpic(struct elfhdr *exec)
{
    return 0;
}
#endif

static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong sp)
{
    uint16_t n;
    struct elf32_fdpic_loadseg *loadsegs = info->loadsegs;

    /* elf32_fdpic_loadseg */
    n = info->nsegs;
    while (n--) {
        sp -= 12;
        put_user_u32(loadsegs[n].addr, sp+0);
        put_user_u32(loadsegs[n].p_vaddr, sp+4);
        put_user_u32(loadsegs[n].p_memsz, sp+8);
    }

    /* elf32_fdpic_loadmap */
    sp -= 4;
    put_user_u16(0, sp+0); /* version */
    put_user_u16(info->nsegs, sp+2); /* nsegs */

    info->personality = PER_LINUX_FDPIC;
    info->loadmap_addr = sp;

    return sp;
}

static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
                                   struct elfhdr *exec,
                                   struct image_info *info,
                                   struct image_info *interp_info,
                                   struct image_info *vdso_info)
{
    abi_ulong sp;
    abi_ulong u_argc, u_argv, u_envp, u_auxv;
    int size;
    int i;
    abi_ulong u_rand_bytes;
    uint8_t k_rand_bytes[16];
    abi_ulong u_platform, u_base_platform;
    const char *k_platform, *k_base_platform;
    const int n = sizeof(elf_addr_t);

    sp = p;

    /* Needs to be before we load the env/argc/... */
    if (elf_is_fdpic(exec)) {
        /* Need 4 byte alignment for these structs */
        sp &= ~3;
        sp = loader_build_fdpic_loadmap(info, sp);
        info->other_info = interp_info;
        if (interp_info) {
            interp_info->other_info = info;
            sp = loader_build_fdpic_loadmap(interp_info, sp);
            info->interpreter_loadmap_addr = interp_info->loadmap_addr;
            info->interpreter_pt_dynamic_addr = interp_info->pt_dynamic_addr;
        } else {
            info->interpreter_loadmap_addr = 0;
            info->interpreter_pt_dynamic_addr = 0;
        }
    }

    u_base_platform = 0;
    k_base_platform = get_elf_base_platform(thread_cpu);
    if (k_base_platform) {
        size_t len = strlen(k_base_platform) + 1;
        if (STACK_GROWS_DOWN) {
            sp -= (len + n - 1) & ~(n - 1);
            u_base_platform = sp;
            /* FIXME - check return value of memcpy_to_target() for failure */
            memcpy_to_target(sp, k_base_platform, len);
        } else {
            memcpy_to_target(sp, k_base_platform, len);
            u_base_platform = sp;
            sp += len + 1;
        }
    }

    u_platform = 0;
    k_platform = get_elf_platform(thread_cpu);
    if (k_platform) {
        size_t len = strlen(k_platform) + 1;
        if (STACK_GROWS_DOWN) {
            sp -= (len + n - 1) & ~(n - 1);
            u_platform = sp;
            /* FIXME - check return value of memcpy_to_target() for failure */
            memcpy_to_target(sp, k_platform, len);
        } else {
            memcpy_to_target(sp, k_platform, len);
            u_platform = sp;
            sp += len + 1;
        }
    }

    /* Provide 16 byte alignment for the PRNG, and basic alignment for
     * the argv and envp pointers.
     */
    if (STACK_GROWS_DOWN) {
        sp = QEMU_ALIGN_DOWN(sp, 16);
    } else {
        sp = QEMU_ALIGN_UP(sp, 16);
    }

    /*
     * Generate 16 random bytes for userspace PRNG seeding.
     */
    qemu_guest_getrandom_nofail(k_rand_bytes, sizeof(k_rand_bytes));
    if (STACK_GROWS_DOWN) {
        sp -= 16;
        u_rand_bytes = sp;
        /* FIXME - check return value of memcpy_to_target() for failure */
        memcpy_to_target(sp, k_rand_bytes, 16);
    } else {
        memcpy_to_target(sp, k_rand_bytes, 16);
        u_rand_bytes = sp;
        sp += 16;
    }

    size = (DLINFO_ITEMS + 1) * 2;
    if (k_base_platform) {
        size += 2;
    }
    if (k_platform) {
        size += 2;
    }
    if (vdso_info) {
        size += 2;
    }
#ifdef DLINFO_ARCH_ITEMS
    size += DLINFO_ARCH_ITEMS * 2;
#endif
    if (HAVE_ELF_HWCAP2) {
        size += 2;
    }
    info->auxv_len = size * n;

    size += envc + argc + 2;
    size += 1;  /* argc itself */
    size *= n;

    /* Allocate space and finalize stack alignment for entry now.  */
    if (STACK_GROWS_DOWN) {
        u_argc = QEMU_ALIGN_DOWN(sp - size, STACK_ALIGNMENT);
        sp = u_argc;
    } else {
        u_argc = sp;
        sp = QEMU_ALIGN_UP(sp + size, STACK_ALIGNMENT);
    }

    u_argv = u_argc + n;
    u_envp = u_argv + (argc + 1) * n;
    u_auxv = u_envp + (envc + 1) * n;
    info->saved_auxv = u_auxv;
    info->argc = argc;
    info->envc = envc;
    info->argv = u_argv;
    info->envp = u_envp;

    /* This is correct because Linux defines
     * elf_addr_t as Elf32_Off / Elf64_Off
     */
#define NEW_AUX_ENT(id, val) do {               \
        put_user_ual(id, u_auxv);  u_auxv += n; \
        put_user_ual(val, u_auxv); u_auxv += n; \
    } while(0)

#ifdef ARCH_DLINFO
    /*
     * ARCH_DLINFO must come first so platform specific code can enforce
     * special alignment requirements on the AUXV if necessary (eg. PPC).
     */
    ARCH_DLINFO;
#endif
    /* There must be exactly DLINFO_ITEMS entries here, or the assert
     * on info->auxv_len will trigger.
     */
    NEW_AUX_ENT(AT_PHDR, (abi_ulong)(info->load_addr + exec->e_phoff));
    NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr)));
    NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
    NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
    NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_info ? interp_info->load_addr : 0));
    NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
    NEW_AUX_ENT(AT_ENTRY, info->entry);
    NEW_AUX_ENT(AT_UID, (abi_ulong) getuid());
    NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
    NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
    NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
    NEW_AUX_ENT(AT_HWCAP, get_elf_hwcap(thread_cpu));
    NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
    NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
    NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
    NEW_AUX_ENT(AT_EXECFN, info->file_string);

    if (HAVE_ELF_HWCAP2) {
        NEW_AUX_ENT(AT_HWCAP2, get_elf_hwcap(thread_cpu));
    }
    if (u_base_platform) {
        NEW_AUX_ENT(AT_BASE_PLATFORM, u_base_platform);
    }
    if (u_platform) {
        NEW_AUX_ENT(AT_PLATFORM, u_platform);
    }
    if (vdso_info) {
        NEW_AUX_ENT(AT_SYSINFO_EHDR, vdso_info->load_addr);
    }
    NEW_AUX_ENT (AT_NULL, 0);
#undef NEW_AUX_ENT

    /* Check that our initial calculation of the auxv length matches how much
     * we actually put into it.
     */
    assert(info->auxv_len == u_auxv - info->saved_auxv);

    put_user_ual(argc, u_argc);

    p = info->arg_strings;
    for (i = 0; i < argc; ++i) {
        put_user_ual(p, u_argv);
        u_argv += n;
        p += target_strlen(p) + 1;
    }
    put_user_ual(0, u_argv);

    p = info->env_strings;
    for (i = 0; i < envc; ++i) {
        put_user_ual(p, u_envp);
        u_envp += n;
        p += target_strlen(p) + 1;
    }
    put_user_ual(0, u_envp);

    return sp;
}

#if defined(HI_COMMPAGE)
#define LO_COMMPAGE -1
#elif defined(LO_COMMPAGE)
#define HI_COMMPAGE 0
#else
#define HI_COMMPAGE 0
#define LO_COMMPAGE -1
#ifndef HAVE_GUEST_COMMPAGE
bool init_guest_commpage(void) { return true; }
#endif
#endif

/**
 * pgb_try_mmap:
 * @addr: host start address
 * @addr_last: host last address
 * @keep: do not unmap the probe region
 *
 * Return 1 if [@addr, @addr_last] is not mapped in the host,
 * return 0 if it is not available to map, and -1 on mmap error.
 * If @keep, the region is left mapped on success, otherwise unmapped.
 */
static int pgb_try_mmap(uintptr_t addr, uintptr_t addr_last, bool keep)
{
    size_t size = addr_last - addr + 1;
    void *p = mmap((void *)addr, size, PROT_NONE,
                   MAP_ANONYMOUS | MAP_PRIVATE |
                   MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0);
    int ret;

    if (p == MAP_FAILED) {
        return errno == EEXIST ? 0 : -1;
    }
    ret = p == (void *)addr;
    if (!keep || !ret) {
        munmap(p, size);
    }
    return ret;
}

/**
 * pgb_try_mmap_skip_brk(uintptr_t addr, uintptr_t size, uintptr_t brk)
 * @addr: host address
 * @addr_last: host last address
 * @brk: host brk
 *
 * Like pgb_try_mmap, but additionally reserve some memory following brk.
 */
static int pgb_try_mmap_skip_brk(uintptr_t addr, uintptr_t addr_last,
                                 uintptr_t brk, bool keep)
{
    uintptr_t brk_last = brk + 16 * MiB - 1;

    /* Do not map anything close to the host brk. */
    if (addr <= brk_last && brk <= addr_last) {
        return 0;
    }
    return pgb_try_mmap(addr, addr_last, keep);
}

/**
 * pgb_try_mmap_set:
 * @ga: set of guest addrs
 * @base: guest_base
 * @brk: host brk
 *
 * Return true if all @ga can be mapped by the host at @base.
 * On success, retain the mapping at index 0 for reserved_va.
 */

typedef struct PGBAddrs {
    uintptr_t bounds[3][2]; /* start/last pairs */
    int nbounds;
} PGBAddrs;

static bool pgb_try_mmap_set(const PGBAddrs *ga, uintptr_t base, uintptr_t brk)
{
    for (int i = ga->nbounds - 1; i >= 0; --i) {
        if (pgb_try_mmap_skip_brk(ga->bounds[i][0] + base,
                                  ga->bounds[i][1] + base,
                                  brk, i == 0 && reserved_va) <= 0) {
            return false;
        }
    }
    return true;
}

/**
 * pgb_addr_set:
 * @ga: output set of guest addrs
 * @guest_loaddr: guest image low address
 * @guest_loaddr: guest image high address
 * @identity: create for identity mapping
 *
 * Fill in @ga with the image, COMMPAGE and NULL page.
 */
static bool pgb_addr_set(PGBAddrs *ga, abi_ulong guest_loaddr,
                         abi_ulong guest_hiaddr, bool try_identity)
{
    int n;

    /*
     * With a low commpage, or a guest mapped very low,
     * we may not be able to use the identity map.
     */
    if (try_identity) {
        if (LO_COMMPAGE != -1 && LO_COMMPAGE < mmap_min_addr) {
            return false;
        }
        if (guest_loaddr != 0 && guest_loaddr < mmap_min_addr) {
            return false;
        }
    }

    memset(ga, 0, sizeof(*ga));
    n = 0;

    if (reserved_va) {
        ga->bounds[n][0] = try_identity ? mmap_min_addr : 0;
        ga->bounds[n][1] = reserved_va;
        n++;
        /* LO_COMMPAGE and NULL handled by reserving from 0. */
    } else {
        /* Add any LO_COMMPAGE or NULL page. */
        if (LO_COMMPAGE != -1) {
            ga->bounds[n][0] = 0;
            ga->bounds[n][1] = LO_COMMPAGE + TARGET_PAGE_SIZE - 1;
            n++;
        } else if (!try_identity) {
            ga->bounds[n][0] = 0;
            ga->bounds[n][1] = TARGET_PAGE_SIZE - 1;
            n++;
        }

        /* Add the guest image for ET_EXEC. */
        if (guest_loaddr) {
            ga->bounds[n][0] = guest_loaddr;
            ga->bounds[n][1] = guest_hiaddr;
            n++;
        }
    }

    /*
     * Temporarily disable
     *   "comparison is always false due to limited range of data type"
     * due to comparison between unsigned and (possible) 0.
     */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"

    /* Add any HI_COMMPAGE not covered by reserved_va. */
    if (reserved_va < HI_COMMPAGE) {
        ga->bounds[n][0] = HI_COMMPAGE & qemu_real_host_page_mask();
        ga->bounds[n][1] = HI_COMMPAGE + TARGET_PAGE_SIZE - 1;
        n++;
    }

#pragma GCC diagnostic pop

    ga->nbounds = n;
    return true;
}

static void pgb_fail_in_use(const char *image_name)
{
    error_report("%s: requires virtual address space that is in use "
                 "(omit the -B option or choose a different value)",
                 image_name);
    exit(EXIT_FAILURE);
}

static void pgb_fixed(const char *image_name, uintptr_t guest_loaddr,
                      uintptr_t guest_hiaddr, uintptr_t align)
{
    PGBAddrs ga;
    uintptr_t brk = (uintptr_t)sbrk(0);

    if (!QEMU_IS_ALIGNED(guest_base, align)) {
        fprintf(stderr, "Requested guest base %p does not satisfy "
                "host minimum alignment (0x%" PRIxPTR ")\n",
                (void *)guest_base, align);
        exit(EXIT_FAILURE);
    }

    if (!pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, !guest_base)
        || !pgb_try_mmap_set(&ga, guest_base, brk)) {
        pgb_fail_in_use(image_name);
    }
}

/**
 * pgb_find_fallback:
 *
 * This is a fallback method for finding holes in the host address space
 * if we don't have the benefit of being able to access /proc/self/map.
 * It can potentially take a very long time as we can only dumbly iterate
 * up the host address space seeing if the allocation would work.
 */
static uintptr_t pgb_find_fallback(const PGBAddrs *ga, uintptr_t align,
                                   uintptr_t brk)
{
    /* TODO: come up with a better estimate of how much to skip. */
    uintptr_t skip = sizeof(uintptr_t) == 4 ? MiB : GiB;

    for (uintptr_t base = skip; ; base += skip) {
        base = ROUND_UP(base, align);
        if (pgb_try_mmap_set(ga, base, brk)) {
            return base;
        }
        if (base >= -skip) {
            return -1;
        }
    }
}

static uintptr_t pgb_try_itree(const PGBAddrs *ga, uintptr_t base,
                               IntervalTreeRoot *root)
{
    for (int i = ga->nbounds - 1; i >= 0; --i) {
        uintptr_t s = base + ga->bounds[i][0];
        uintptr_t l = base + ga->bounds[i][1];
        IntervalTreeNode *n;

        if (l < s) {
            /* Wraparound. Skip to advance S to mmap_min_addr. */
            return mmap_min_addr - s;
        }

        n = interval_tree_iter_first(root, s, l);
        if (n != NULL) {
            /* Conflict.  Skip to advance S to LAST + 1. */
            return n->last - s + 1;
        }
    }
    return 0;  /* success */
}

static uintptr_t pgb_find_itree(const PGBAddrs *ga, IntervalTreeRoot *root,
                                uintptr_t align, uintptr_t brk)
{
    uintptr_t last = sizeof(uintptr_t) == 4 ? MiB : GiB;
    uintptr_t base, skip;

    while (true) {
        base = ROUND_UP(last, align);
        if (base < last) {
            return -1;
        }

        skip = pgb_try_itree(ga, base, root);
        if (skip == 0) {
            break;
        }

        last = base + skip;
        if (last < base) {
            return -1;
        }
    }

    /*
     * We've chosen 'base' based on holes in the interval tree,
     * but we don't yet know if it is a valid host address.
     * Because it is the first matching hole, if the host addresses
     * are invalid we know there are no further matches.
     */
    return pgb_try_mmap_set(ga, base, brk) ? base : -1;
}

static void pgb_dynamic(const char *image_name, uintptr_t guest_loaddr,
                        uintptr_t guest_hiaddr, uintptr_t align)
{
    IntervalTreeRoot *root;
    uintptr_t brk, ret;
    PGBAddrs ga;

    /* Try the identity map first. */
    if (pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, true)) {
        brk = (uintptr_t)sbrk(0);
        if (pgb_try_mmap_set(&ga, 0, brk)) {
            guest_base = 0;
            return;
        }
    }

    /*
     * Rebuild the address set for non-identity map.
     * This differs in the mapping of the guest NULL page.
     */
    pgb_addr_set(&ga, guest_loaddr, guest_hiaddr, false);

    root = read_self_maps();

    /* Read brk after we've read the maps, which will malloc. */
    brk = (uintptr_t)sbrk(0);

    if (!root) {
        ret = pgb_find_fallback(&ga, align, brk);
    } else {
        /*
         * Reserve the area close to the host brk.
         * This will be freed with the rest of the tree.
         */
        IntervalTreeNode *b = g_new0(IntervalTreeNode, 1);
        b->start = brk;
        b->last = brk + 16 * MiB - 1;
        interval_tree_insert(b, root);

        ret = pgb_find_itree(&ga, root, align, brk);
        free_self_maps(root);
    }

    if (ret == -1) {
        int w = TARGET_LONG_BITS / 4;

        error_report("%s: Unable to find a guest_base to satisfy all "
                     "guest address mapping requirements", image_name);

        for (int i = 0; i < ga.nbounds; ++i) {
            error_printf("  %0*" PRIx64 "-%0*" PRIx64 "\n",
                         w, (uint64_t)ga.bounds[i][0],
                         w, (uint64_t)ga.bounds[i][1]);
        }
        exit(EXIT_FAILURE);
    }
    guest_base = ret;
}

void probe_guest_base(const char *image_name, abi_ulong guest_loaddr,
                      abi_ulong guest_hiaddr)
{
    /* In order to use host shmat, we must be able to honor SHMLBA.  */
    uintptr_t align = MAX(SHMLBA, TARGET_PAGE_SIZE);

    /* Sanity check the guest binary. */
    if (reserved_va) {
        if (guest_hiaddr > reserved_va) {
            error_report("%s: requires more than reserved virtual "
                         "address space (0x%" PRIx64 " > 0x%lx)",
                         image_name, (uint64_t)guest_hiaddr, reserved_va);
            exit(EXIT_FAILURE);
        }
    } else {
        if (guest_hiaddr != (uintptr_t)guest_hiaddr) {
            error_report("%s: requires more virtual address space "
                         "than the host can provide (0x%" PRIx64 ")",
                         image_name, (uint64_t)guest_hiaddr + 1);
            exit(EXIT_FAILURE);
        }
    }

    if (have_guest_base) {
        pgb_fixed(image_name, guest_loaddr, guest_hiaddr, align);
    } else {
        pgb_dynamic(image_name, guest_loaddr, guest_hiaddr, align);
    }

    /* Reserve and initialize the commpage. */
    if (!init_guest_commpage()) {
        /* We have already probed for the commpage being free. */
        g_assert_not_reached();
    }

    assert(QEMU_IS_ALIGNED(guest_base, align));
    qemu_log_mask(CPU_LOG_PAGE, "Locating guest address space "
                  "@ 0x%" PRIx64 "\n", (uint64_t)guest_base);
}

enum {
    /* The string "GNU\0" as a magic number. */
    GNU0_MAGIC = const_le32('G' | 'N' << 8 | 'U' << 16),
    NOTE_DATA_SZ = 1 * KiB,
    NOTE_NAME_SZ = 4,
    ELF_GNU_PROPERTY_ALIGN = ELF_CLASS == ELFCLASS32 ? 4 : 8,
};

/*
 * Process a single gnu_property entry.
 * Return false for error.
 */
static bool parse_elf_property(const uint32_t *data, int *off, int datasz,
                               struct image_info *info, bool have_prev_type,
                               uint32_t *prev_type, Error **errp)
{
    uint32_t pr_type, pr_datasz, step;

    if (*off > datasz || !QEMU_IS_ALIGNED(*off, ELF_GNU_PROPERTY_ALIGN)) {
        goto error_data;
    }
    datasz -= *off;
    data += *off / sizeof(uint32_t);

    if (datasz < 2 * sizeof(uint32_t)) {
        goto error_data;
    }
    pr_type = data[0];
    pr_datasz = data[1];
    data += 2;
    datasz -= 2 * sizeof(uint32_t);
    step = ROUND_UP(pr_datasz, ELF_GNU_PROPERTY_ALIGN);
    if (step > datasz) {
        goto error_data;
    }

    /* Properties are supposed to be unique and sorted on pr_type. */
    if (have_prev_type && pr_type <= *prev_type) {
        if (pr_type == *prev_type) {
            error_setg(errp, "Duplicate property in PT_GNU_PROPERTY");
        } else {
            error_setg(errp, "Unsorted property in PT_GNU_PROPERTY");
        }
        return false;
    }
    *prev_type = pr_type;

    if (!arch_parse_elf_property(pr_type, pr_datasz, data, info, errp)) {
        return false;
    }

    *off += 2 * sizeof(uint32_t) + step;
    return true;

 error_data:
    error_setg(errp, "Ill-formed property in PT_GNU_PROPERTY");
    return false;
}

/* Process NT_GNU_PROPERTY_TYPE_0. */
static bool parse_elf_properties(const ImageSource *src,
                                 struct image_info *info,
                                 const struct elf_phdr *phdr,
                                 Error **errp)
{
    union {
        struct elf_note nhdr;
        uint32_t data[NOTE_DATA_SZ / sizeof(uint32_t)];
    } note;

    int n, off, datasz;
    bool have_prev_type;
    uint32_t prev_type;

    /* Unless the arch requires properties, ignore them. */
    if (!HAVE_ELF_GNU_PROPERTY) {
        return true;
    }

    /* If the properties are crazy large, that's too bad. */
    n = phdr->p_filesz;
    if (n > sizeof(note)) {
        error_setg(errp, "PT_GNU_PROPERTY too large");
        return false;
    }
    if (n < sizeof(note.nhdr)) {
        error_setg(errp, "PT_GNU_PROPERTY too small");
        return false;
    }

    if (!imgsrc_read(&note, phdr->p_offset, n, src, errp)) {
        return false;
    }

    /*
     * The contents of a valid PT_GNU_PROPERTY is a sequence of uint32_t.
     * Swap most of them now, beyond the header and namesz.
     */
    if (target_needs_bswap()) {
        for (int i = 4; i < n / 4; i++) {
            bswap32s(note.data + i);
        }
    }

    /*
     * Note that nhdr is 3 words, and that the "name" described by namesz
     * immediately follows nhdr and is thus at the 4th word.  Further, all
     * of the inputs to the kernel's round_up are multiples of 4.
     */
    if (tswap32(note.nhdr.n_type) != NT_GNU_PROPERTY_TYPE_0 ||
        tswap32(note.nhdr.n_namesz) != NOTE_NAME_SZ ||
        note.data[3] != GNU0_MAGIC) {
        error_setg(errp, "Invalid note in PT_GNU_PROPERTY");
        return false;
    }
    off = sizeof(note.nhdr) + NOTE_NAME_SZ;

    datasz = tswap32(note.nhdr.n_descsz) + off;
    if (datasz > n) {
        error_setg(errp, "Invalid note size in PT_GNU_PROPERTY");
        return false;
    }

    have_prev_type = false;
    prev_type = 0;
    while (1) {
        if (off == datasz) {
            return true;  /* end, exit ok */
        }
        if (!parse_elf_property(note.data, &off, datasz, info,
                                have_prev_type, &prev_type, errp)) {
            return false;
        }
        have_prev_type = true;
    }
}

/**
 * load_elf_image: Load an ELF image into the address space.
 * @image_name: the filename of the image, to use in error messages.
 * @src: the ImageSource from which to read.
 * @info: info collected from the loaded image.
 * @ehdr: the ELF header, not yet bswapped.
 * @pinterp_name: record any PT_INTERP string found.
 *
 * On return: @info values will be filled in, as necessary or available.
 */

static void load_elf_image(const char *image_name, const ImageSource *src,
                           struct image_info *info, struct elfhdr *ehdr,
                           char **pinterp_name)
{
    g_autofree struct elf_phdr *phdr = NULL;
    abi_ulong load_addr, load_bias, loaddr, hiaddr, error, align;
    size_t reserve_size, align_size;
    int i, prot_exec;
    Error *err = NULL;

    /*
     * First of all, some simple consistency checks.
     * Note that we rely on the bswapped ehdr staying in bprm_buf,
     * for later use by load_elf_binary and create_elf_tables.
     */
    if (!imgsrc_read(ehdr, 0, sizeof(*ehdr), src, &err)) {
        goto exit_errmsg;
    }
    if (!elf_check_ident(ehdr)) {
        error_setg(&err, "Invalid ELF image for this architecture");
        goto exit_errmsg;
    }
    bswap_ehdr(ehdr);
    if (!elf_check_ehdr(ehdr)) {
        error_setg(&err, "Invalid ELF image for this architecture");
        goto exit_errmsg;
    }

    phdr = imgsrc_read_alloc(ehdr->e_phoff,
                             ehdr->e_phnum * sizeof(struct elf_phdr),
                             src, &err);
    if (phdr == NULL) {
        goto exit_errmsg;
    }
    bswap_phdr(phdr, ehdr->e_phnum);

    info->nsegs = 0;
    info->pt_dynamic_addr = 0;

    mmap_lock();

    /*
     * Find the maximum size of the image and allocate an appropriate
     * amount of memory to handle that.  Locate the interpreter, if any.
     */
    loaddr = -1, hiaddr = 0;
    align = 0;
    info->exec_stack = EXSTACK_DEFAULT;
    for (i = 0; i < ehdr->e_phnum; ++i) {
        struct elf_phdr *eppnt = phdr + i;
        if (eppnt->p_type == PT_LOAD) {
            abi_ulong a = eppnt->p_vaddr & TARGET_PAGE_MASK;
            if (a < loaddr) {
                loaddr = a;
            }
            a = eppnt->p_vaddr + eppnt->p_memsz - 1;
            if (a > hiaddr) {
                hiaddr = a;
            }
            ++info->nsegs;
            align |= eppnt->p_align;
        } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
            g_autofree char *interp_name = NULL;

            if (*pinterp_name) {
                error_setg(&err, "Multiple PT_INTERP entries");
                goto exit_errmsg;
            }

            interp_name = imgsrc_read_alloc(eppnt->p_offset, eppnt->p_filesz,
                                            src, &err);
            if (interp_name == NULL) {
                goto exit_errmsg;
            }
            if (interp_name[eppnt->p_filesz - 1] != 0) {
                error_setg(&err, "Invalid PT_INTERP entry");
                goto exit_errmsg;
            }
            *pinterp_name = g_steal_pointer(&interp_name);
        } else if (eppnt->p_type == PT_GNU_PROPERTY) {
            if (!parse_elf_properties(src, info, eppnt, &err)) {
                goto exit_errmsg;
            }
        } else if (eppnt->p_type == PT_GNU_STACK) {
            info->exec_stack = eppnt->p_flags & PF_X;
        }
    }

    load_addr = loaddr;

    align = pow2ceil(align);

    if (pinterp_name != NULL) {
        if (ehdr->e_type == ET_EXEC) {
            /*
             * Make sure that the low address does not conflict with
             * MMAP_MIN_ADDR or the QEMU application itself.
             */
            probe_guest_base(image_name, loaddr, hiaddr);
        } else {
            /*
             * The binary is dynamic, but we still need to
             * select guest_base.  In this case we pass a size.
             */
            probe_guest_base(image_name, 0, hiaddr - loaddr);

            /*
             * Avoid collision with the loader by providing a different
             * default load address.
             */
            load_addr += elf_et_dyn_base;

            /*
             * TODO: Better support for mmap alignment is desirable.
             * Since we do not have complete control over the guest
             * address space, we prefer the kernel to choose some address
             * rather than force the use of LOAD_ADDR via MAP_FIXED.
             */
            if (align) {
                load_addr &= -align;
            }
        }
    }

    /*
     * Reserve address space for all of this.
     *
     * In the case of ET_EXEC, we supply MAP_FIXED_NOREPLACE so that we get
     * exactly the address range that is required.  Without reserved_va,
     * the guest address space is not isolated.  We have attempted to avoid
     * conflict with the host program itself via probe_guest_base, but using
     * MAP_FIXED_NOREPLACE instead of MAP_FIXED provides an extra check.
     *
     * Otherwise this is ET_DYN, and we are searching for a location
     * that can hold the memory space required.  If the image is
     * pre-linked, LOAD_ADDR will be non-zero, and the kernel should
     * honor that address if it happens to be free.
     *
     * In both cases, we will overwrite pages in this range with mappings
     * from the executable.
     */
    reserve_size = (size_t)hiaddr - loaddr + 1;
    align_size = reserve_size;

    if (ehdr->e_type != ET_EXEC && align > qemu_real_host_page_size()) {
        align_size += align - 1;
    }

    load_addr = target_mmap(load_addr, align_size, PROT_NONE,
                            MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
                            (ehdr->e_type == ET_EXEC ? MAP_FIXED_NOREPLACE : 0),
                            -1, 0);
    if (load_addr == -1) {
        goto exit_mmap;
    }

    if (align_size != reserve_size) {
        abi_ulong align_addr = ROUND_UP(load_addr, align);
        abi_ulong align_end = TARGET_PAGE_ALIGN(align_addr + reserve_size);
        abi_ulong load_end = TARGET_PAGE_ALIGN(load_addr + align_size);

        if (align_addr != load_addr) {
            target_munmap(load_addr, align_addr - load_addr);
        }
        if (align_end != load_end) {
            target_munmap(align_end, load_end - align_end);
        }
        load_addr = align_addr;
    }

    load_bias = load_addr - loaddr;

    if (elf_is_fdpic(ehdr)) {
        struct elf32_fdpic_loadseg *loadsegs = info->loadsegs =
            g_malloc(sizeof(*loadsegs) * info->nsegs);

        for (i = 0; i < ehdr->e_phnum; ++i) {
            switch (phdr[i].p_type) {
            case PT_DYNAMIC:
                info->pt_dynamic_addr = phdr[i].p_vaddr + load_bias;
                break;
            case PT_LOAD:
                loadsegs->addr = phdr[i].p_vaddr + load_bias;
                loadsegs->p_vaddr = phdr[i].p_vaddr;
                loadsegs->p_memsz = phdr[i].p_memsz;
                ++loadsegs;
                break;
            }
        }
    }

    info->load_bias = load_bias;
    info->code_offset = load_bias;
    info->data_offset = load_bias;
    info->load_addr = load_addr;
    info->entry = ehdr->e_entry + load_bias;
    info->start_code = -1;
    info->end_code = 0;
    info->start_data = -1;
    info->end_data = 0;
    /* Usual start for brk is after all sections of the main executable. */
    info->brk = TARGET_PAGE_ALIGN(hiaddr + load_bias);
    info->elf_flags = ehdr->e_flags;

    prot_exec = PROT_EXEC;
#ifdef TARGET_AARCH64
    /*
     * If the BTI feature is present, this indicates that the executable
     * pages of the startup binary should be mapped with PROT_BTI, so that
     * branch targets are enforced.
     *
     * The startup binary is either the interpreter or the static executable.
     * The interpreter is responsible for all pages of a dynamic executable.
     *
     * Elf notes are backward compatible to older cpus.
     * Do not enable BTI unless it is supported.
     */
    if ((info->note_flags & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
        && (pinterp_name == NULL || *pinterp_name == 0)
        && cpu_isar_feature(aa64_bti, ARM_CPU(thread_cpu))) {
        prot_exec |= TARGET_PROT_BTI;
    }
#endif

    for (i = 0; i < ehdr->e_phnum; i++) {
        struct elf_phdr *eppnt = phdr + i;
        if (eppnt->p_type == PT_LOAD) {
            abi_ulong vaddr, vaddr_po, vaddr_ps, vaddr_ef, vaddr_em;
            int elf_prot = 0;

            if (eppnt->p_flags & PF_R) {
                elf_prot |= PROT_READ;
            }
            if (eppnt->p_flags & PF_W) {
                elf_prot |= PROT_WRITE;
            }
            if (eppnt->p_flags & PF_X) {
                elf_prot |= prot_exec;
            }

            vaddr = load_bias + eppnt->p_vaddr;
            vaddr_po = vaddr & ~TARGET_PAGE_MASK;
            vaddr_ps = vaddr & TARGET_PAGE_MASK;

            vaddr_ef = vaddr + eppnt->p_filesz;
            vaddr_em = vaddr + eppnt->p_memsz;

            /*
             * Some segments may be completely empty, with a non-zero p_memsz
             * but no backing file segment.
             */
            if (eppnt->p_filesz != 0) {
                error = imgsrc_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po,
                                    elf_prot, MAP_PRIVATE | MAP_FIXED,
                                    src, eppnt->p_offset - vaddr_po);
                if (error == -1) {
                    goto exit_mmap;
                }
            }

            /* If the load segment requests extra zeros (e.g. bss), map it. */
            if (vaddr_ef < vaddr_em &&
                !zero_bss(vaddr_ef, vaddr_em, elf_prot, &err)) {
                goto exit_errmsg;
            }

            /* Find the full program boundaries.  */
            if (elf_prot & PROT_EXEC) {
                if (vaddr < info->start_code) {
                    info->start_code = vaddr;
                }
                if (vaddr_ef > info->end_code) {
                    info->end_code = vaddr_ef;
                }
            }
            if (elf_prot & PROT_WRITE) {
                if (vaddr < info->start_data) {
                    info->start_data = vaddr;
                }
                if (vaddr_ef > info->end_data) {
                    info->end_data = vaddr_ef;
                }
            }
#ifdef TARGET_MIPS
        } else if (eppnt->p_type == PT_MIPS_ABIFLAGS) {
            Mips_elf_abiflags_v0 abiflags;

            if (!imgsrc_read(&abiflags, eppnt->p_offset, sizeof(abiflags),
                             src, &err)) {
                goto exit_errmsg;
            }
            bswap_mips_abiflags(&abiflags);
            info->fp_abi = abiflags.fp_abi;
#endif
        }
    }

    if (info->end_data == 0) {
        info->start_data = info->end_code;
        info->end_data = info->end_code;
    }

    if (qemu_log_enabled()) {
        load_symbols(ehdr, src, load_bias);
    }

    debuginfo_report_elf(image_name, src->fd, load_bias);

    mmap_unlock();

    close(src->fd);
    return;

 exit_mmap:
    error_setg_errno(&err, errno, "Error mapping file");
    goto exit_errmsg;
 exit_errmsg:
    error_reportf_err(err, "%s: ", image_name);
    exit(-1);
}

static void load_elf_interp(const char *filename, struct image_info *info,
                            char bprm_buf[BPRM_BUF_SIZE])
{
    struct elfhdr ehdr;
    ImageSource src;
    int fd, retval;
    Error *err = NULL;

    fd = open(path(filename), O_RDONLY);
    if (fd < 0) {
        error_setg_file_open(&err, errno, filename);
        error_report_err(err);
        exit(-1);
    }

    retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
    if (retval < 0) {
        error_setg_errno(&err, errno, "Error reading file header");
        error_reportf_err(err, "%s: ", filename);
        exit(-1);
    }

    src.fd = fd;
    src.cache = bprm_buf;
    src.cache_size = retval;

    load_elf_image(filename, &src, info, &ehdr, NULL);
}

#ifndef HAVE_VDSO_IMAGE_INFO
const VdsoImageInfo *get_vdso_image_info(uint32_t elf_flags)
{
#ifdef VDSO_HEADER
#include VDSO_HEADER
    return &vdso_image_info;
#else
    return NULL;
#endif
}
#endif /* HAVE_VDSO_IMAGE_INFO */

static void load_elf_vdso(struct image_info *info, const VdsoImageInfo *vdso)
{
    ImageSource src;
    struct elfhdr ehdr;
    abi_ulong load_bias, load_addr;

    src.fd = -1;
    src.cache = vdso->image;
    src.cache_size = vdso->image_size;

    load_elf_image("<internal-vdso>", &src, info, &ehdr, NULL);
    load_addr = info->load_addr;
    load_bias = info->load_bias;

    /*
     * We need to relocate the VDSO image.  The one built into the kernel
     * is built for a fixed address.  The one built for QEMU is not, since
     * that requires close control of the guest address space.
     * We pre-processed the image to locate all of the addresses that need
     * to be updated.
     */
    for (unsigned i = 0, n = vdso->reloc_count; i < n; i++) {
        abi_ulong *addr = g2h_untagged(load_addr + vdso->relocs[i]);
        *addr = tswapal(tswapal(*addr) + load_bias);
    }

    /* Install signal trampolines, if present. */
    if (vdso->sigreturn_ofs) {
        default_sigreturn = load_addr + vdso->sigreturn_ofs;
    }
    if (vdso->rt_sigreturn_ofs) {
        default_rt_sigreturn = load_addr + vdso->rt_sigreturn_ofs;
    }

    /* Remove write from VDSO segment. */
    target_mprotect(info->start_data, info->end_data - info->start_data,
                    PROT_READ | PROT_EXEC);
}

static int symfind(const void *s0, const void *s1)
{
    struct elf_sym *sym = (struct elf_sym *)s1;
    __typeof(sym->st_value) addr = *(uint64_t *)s0;
    int result = 0;

    if (addr < sym->st_value) {
        result = -1;
    } else if (addr >= sym->st_value + sym->st_size) {
        result = 1;
    }
    return result;
}

static const char *lookup_symbolxx(struct syminfo *s, uint64_t orig_addr)
{
#if ELF_CLASS == ELFCLASS32
    struct elf_sym *syms = s->disas_symtab.elf32;
#else
    struct elf_sym *syms = s->disas_symtab.elf64;
#endif

    // binary search
    struct elf_sym *sym;

    sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind);
    if (sym != NULL) {
        return s->disas_strtab + sym->st_name;
    }

    return "";
}

/* FIXME: This should use elf_ops.h.inc  */
static int symcmp(const void *s0, const void *s1)
{
    struct elf_sym *sym0 = (struct elf_sym *)s0;
    struct elf_sym *sym1 = (struct elf_sym *)s1;
    return (sym0->st_value < sym1->st_value)
        ? -1
        : ((sym0->st_value > sym1->st_value) ? 1 : 0);
}

/* Best attempt to load symbols from this ELF object. */
static void load_symbols(struct elfhdr *hdr, const ImageSource *src,
                         abi_ulong load_bias)
{
    int i, shnum, nsyms, sym_idx = 0, str_idx = 0;
    g_autofree struct elf_shdr *shdr = NULL;
    char *strings = NULL;
    struct elf_sym *syms = NULL;
    struct elf_sym *new_syms;
    uint64_t segsz;

    shnum = hdr->e_shnum;
    shdr = imgsrc_read_alloc(hdr->e_shoff, shnum * sizeof(struct elf_shdr),
                             src, NULL);
    if (shdr == NULL) {
        return;
    }

    bswap_shdr(shdr, shnum);
    for (i = 0; i < shnum; ++i) {
        if (shdr[i].sh_type == SHT_SYMTAB) {
            sym_idx = i;
            str_idx = shdr[i].sh_link;
            goto found;
        }
    }

    /* There will be no symbol table if the file was stripped.  */
    return;

 found:
    /* Now know where the strtab and symtab are.  Snarf them.  */

    segsz = shdr[str_idx].sh_size;
    strings = g_try_malloc(segsz);
    if (!strings) {
        goto give_up;
    }
    if (!imgsrc_read(strings, shdr[str_idx].sh_offset, segsz, src, NULL)) {
        goto give_up;
    }

    segsz = shdr[sym_idx].sh_size;
    if (segsz / sizeof(struct elf_sym) > INT_MAX) {
        /*
         * Implausibly large symbol table: give up rather than ploughing
         * on with the number of symbols calculation overflowing.
         */
        goto give_up;
    }
    nsyms = segsz / sizeof(struct elf_sym);
    syms = g_try_malloc(segsz);
    if (!syms) {
        goto give_up;
    }
    if (!imgsrc_read(syms, shdr[sym_idx].sh_offset, segsz, src, NULL)) {
        goto give_up;
    }

    for (i = 0; i < nsyms; ) {
        bswap_sym(syms + i);
        /* Throw away entries which we do not need.  */
        if (syms[i].st_shndx == SHN_UNDEF
            || syms[i].st_shndx >= SHN_LORESERVE
            || ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
            if (i < --nsyms) {
                syms[i] = syms[nsyms];
            }
        } else {
#if defined(TARGET_ARM) || defined (TARGET_MIPS)
            /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
            syms[i].st_value &= ~(target_ulong)1;
#endif
            syms[i].st_value += load_bias;
            i++;
        }
    }

    /* No "useful" symbol.  */
    if (nsyms == 0) {
        goto give_up;
    }

    /*
     * Attempt to free the storage associated with the local symbols
     * that we threw away.  Whether or not this has any effect on the
     * memory allocation depends on the malloc implementation and how
     * many symbols we managed to discard.
     */
    new_syms = g_try_renew(struct elf_sym, syms, nsyms);
    if (new_syms == NULL) {
        goto give_up;
    }
    syms = new_syms;

    qsort(syms, nsyms, sizeof(*syms), symcmp);

    {
        struct syminfo *s = g_new(struct syminfo, 1);

        s->disas_strtab = strings;
        s->disas_num_syms = nsyms;
#if ELF_CLASS == ELFCLASS32
        s->disas_symtab.elf32 = syms;
#else
        s->disas_symtab.elf64 = syms;
#endif
        s->lookup_symbol = lookup_symbolxx;
        s->next = syminfos;
        syminfos = s;
    }
    return;

 give_up:
    g_free(strings);
    g_free(syms);
}

uint32_t get_elf_eflags(int fd)
{
    struct elfhdr ehdr;
    off_t offset;
    int ret;

    /* Read ELF header */
    offset = lseek(fd, 0, SEEK_SET);
    if (offset == (off_t) -1) {
        return 0;
    }
    ret = read(fd, &ehdr, sizeof(ehdr));
    if (ret < sizeof(ehdr)) {
        return 0;
    }
    offset = lseek(fd, offset, SEEK_SET);
    if (offset == (off_t) -1) {
        return 0;
    }

    /* Check ELF signature */
    if (!elf_check_ident(&ehdr)) {
        return 0;
    }

    /* check header */
    bswap_ehdr(&ehdr);
    if (!elf_check_ehdr(&ehdr)) {
        return 0;
    }

    /* return architecture id */
    return ehdr.e_flags;
}

int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
{
    /*
     * We need a copy of the elf header for passing to create_elf_tables.
     * We will have overwritten the original when we re-use bprm->buf
     * while loading the interpreter.  Allocate the storage for this now
     * and let elf_load_image do any swapping that may be required.
     */
    struct elfhdr ehdr;
    struct image_info interp_info, vdso_info;
    char *elf_interpreter = NULL;
    char *scratch;

    memset(&interp_info, 0, sizeof(interp_info));
#ifdef TARGET_MIPS
    interp_info.fp_abi = MIPS_ABI_FP_UNKNOWN;
#endif

    load_elf_image(bprm->filename, &bprm->src, info, &ehdr, &elf_interpreter);

    /* Do this so that we can load the interpreter, if need be.  We will
       change some of these later */
    bprm->p = setup_arg_pages(bprm, info);

    scratch = g_new0(char, TARGET_PAGE_SIZE);
    if (STACK_GROWS_DOWN) {
        bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
                                   bprm->p, info->stack_limit);
        info->file_string = bprm->p;
        bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch,
                                   bprm->p, info->stack_limit);
        info->env_strings = bprm->p;
        bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch,
                                   bprm->p, info->stack_limit);
        info->arg_strings = bprm->p;
    } else {
        info->arg_strings = bprm->p;
        bprm->p = copy_elf_strings(bprm->argc, bprm->argv, scratch,
                                   bprm->p, info->stack_limit);
        info->env_strings = bprm->p;
        bprm->p = copy_elf_strings(bprm->envc, bprm->envp, scratch,
                                   bprm->p, info->stack_limit);
        info->file_string = bprm->p;
        bprm->p = copy_elf_strings(1, &bprm->filename, scratch,
                                   bprm->p, info->stack_limit);
    }

    g_free(scratch);

    if (!bprm->p) {
        fprintf(stderr, "%s: %s\n", bprm->filename, strerror(E2BIG));
        exit(-1);
    }

    if (elf_interpreter) {
        load_elf_interp(elf_interpreter, &interp_info, bprm->buf);

        /*
         * While unusual because of ELF_ET_DYN_BASE, if we are unlucky
         * with the mappings the interpreter can be loaded above but
         * near the main executable, which can leave very little room
         * for the heap.
         * If the current brk has less than 16MB, use the end of the
         * interpreter.
         */
        if (interp_info.brk > info->brk &&
            interp_info.load_bias - info->brk < 16 * MiB)  {
            info->brk = interp_info.brk;
        }

        /* If the program interpreter is one of these two, then assume
           an iBCS2 image.  Otherwise assume a native linux image.  */

        if (strcmp(elf_interpreter, "/usr/lib/libc.so.1") == 0
            || strcmp(elf_interpreter, "/usr/lib/ld.so.1") == 0) {
            info->personality = PER_SVR4;

            /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
               and some applications "depend" upon this behavior.  Since
               we do not have the power to recompile these, we emulate
               the SVr4 behavior.  Sigh.  */
            target_mmap(0, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC,
                        MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS,
                        -1, 0);
        }
#ifdef TARGET_MIPS
        info->interp_fp_abi = interp_info.fp_abi;
#endif
    }

    /*
     * Load a vdso if available, which will amongst other things contain the
     * signal trampolines.  Otherwise, allocate a separate page for them.
     */
    const VdsoImageInfo *vdso = get_vdso_image_info(info->elf_flags);
    if (vdso) {
        load_elf_vdso(&vdso_info, vdso);
        info->vdso = vdso_info.load_bias;
    } else if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) {
        abi_long tramp_page = target_mmap(0, TARGET_PAGE_SIZE,
                                          PROT_READ | PROT_WRITE,
                                          MAP_PRIVATE | MAP_ANON, -1, 0);
        if (tramp_page == -1) {
            return -errno;
        }

        setup_sigtramp(tramp_page);
        target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC);
    }

    bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &ehdr, info,
                                elf_interpreter ? &interp_info : NULL,
                                vdso ? &vdso_info : NULL);
    info->start_stack = bprm->p;

    /* If we have an interpreter, set that as the program's entry point.
       Copy the load_bias as well, to help PPC64 interpret the entry
       point as a function descriptor.  Do this after creating elf tables
       so that we copy the original program entry point into the AUXV.  */
    if (elf_interpreter) {
        info->load_bias = interp_info.load_bias;
        info->entry = interp_info.entry;
        g_free(elf_interpreter);
    }

#ifdef HAVE_ELF_CORE_DUMP
    bprm->core_dump = &elf_core_dump;
#endif

    return 0;
}

#ifdef HAVE_ELF_CORE_DUMP

/*
 * Definitions to generate Intel SVR4-like core files.
 * These mostly have the same names as the SVR4 types with "target_elf_"
 * tacked on the front to prevent clashes with linux definitions,
 * and the typedef forms have been avoided.  This is mostly like
 * the SVR4 structure, but more Linuxy, with things that Linux does
 * not support and which gdb doesn't really use excluded.
 *
 * Fields we don't dump (their contents is zero) in linux-user qemu
 * are marked with XXX.
 *
 * Core dump code is copied from linux kernel (fs/binfmt_elf.c).
 *
 * Porting ELF coredump for target is (quite) simple process.  First you
 * define HAVE_ELF_CORE_DUMP in target ELF code (where init_thread() for
 * the target resides):
 *
 * #define HAVE_ELF_CORE_DUMP
 *
 * Next you define type of register set used for dumping:
 * typedef struct target_elf_gregset_t { ... } target_elf_gregset_t;
 *
 * Last step is to implement target specific function that copies registers
 * from given cpu into just specified register set.  Prototype is:
 *
 * void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUArchState *env);
 *
 * Parameters:
 *     regs - copy register values into here (allocated and zeroed by caller)
 *     env - copy registers from here
 *
 * Example for ARM target is provided in this file.
 */

struct target_elf_siginfo {
    abi_int    si_signo; /* signal number */
    abi_int    si_code;  /* extra code */
    abi_int    si_errno; /* errno */
};

struct target_elf_prstatus {
    struct target_elf_siginfo pr_info;      /* Info associated with signal */
    abi_short          pr_cursig;    /* Current signal */
    abi_ulong          pr_sigpend;   /* XXX */
    abi_ulong          pr_sighold;   /* XXX */
    target_pid_t       pr_pid;
    target_pid_t       pr_ppid;
    target_pid_t       pr_pgrp;
    target_pid_t       pr_sid;
    struct target_timeval pr_utime;  /* XXX User time */
    struct target_timeval pr_stime;  /* XXX System time */
    struct target_timeval pr_cutime; /* XXX Cumulative user time */
    struct target_timeval pr_cstime; /* XXX Cumulative system time */
    target_elf_gregset_t      pr_reg;       /* GP registers */
    abi_int            pr_fpvalid;   /* XXX */
};

#define ELF_PRARGSZ     (80) /* Number of chars for args */

struct target_elf_prpsinfo {
    char         pr_state;       /* numeric process state */
    char         pr_sname;       /* char for pr_state */
    char         pr_zomb;        /* zombie */
    char         pr_nice;        /* nice val */
    abi_ulong    pr_flag;        /* flags */
    target_uid_t pr_uid;
    target_gid_t pr_gid;
    target_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
    /* Lots missing */
    char    pr_fname[16] QEMU_NONSTRING; /* filename of executable */
    char    pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};

static void bswap_prstatus(struct target_elf_prstatus *prstatus)
{
    if (!target_needs_bswap()) {
        return;
    }

    prstatus->pr_info.si_signo = tswap32(prstatus->pr_info.si_signo);
    prstatus->pr_info.si_code = tswap32(prstatus->pr_info.si_code);
    prstatus->pr_info.si_errno = tswap32(prstatus->pr_info.si_errno);
    prstatus->pr_cursig = tswap16(prstatus->pr_cursig);
    prstatus->pr_sigpend = tswapal(prstatus->pr_sigpend);
    prstatus->pr_sighold = tswapal(prstatus->pr_sighold);
    prstatus->pr_pid = tswap32(prstatus->pr_pid);
    prstatus->pr_ppid = tswap32(prstatus->pr_ppid);
    prstatus->pr_pgrp = tswap32(prstatus->pr_pgrp);
    prstatus->pr_sid = tswap32(prstatus->pr_sid);
    /* cpu times are not filled, so we skip them */
    /* regs should be in correct format already */
    prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid);
}

static void bswap_psinfo(struct target_elf_prpsinfo *psinfo)
{
    if (!target_needs_bswap()) {
        return;
    }

    psinfo->pr_flag = tswapal(psinfo->pr_flag);
    psinfo->pr_uid = tswap16(psinfo->pr_uid);
    psinfo->pr_gid = tswap16(psinfo->pr_gid);
    psinfo->pr_pid = tswap32(psinfo->pr_pid);
    psinfo->pr_ppid = tswap32(psinfo->pr_ppid);
    psinfo->pr_pgrp = tswap32(psinfo->pr_pgrp);
    psinfo->pr_sid = tswap32(psinfo->pr_sid);
}

static void bswap_note(struct elf_note *en)
{
    if (!target_needs_bswap()) {
        return;
    }

    bswap32s(&en->n_namesz);
    bswap32s(&en->n_descsz);
    bswap32s(&en->n_type);
}

/*
 * Calculate file (dump) size of given memory region.
 */
static size_t vma_dump_size(vaddr start, vaddr end, int flags)
{
    /* The area must be readable. */
    if (!(flags & PAGE_READ)) {
        return 0;
    }

    /*
     * Usually we don't dump executable pages as they contain
     * non-writable code that debugger can read directly from
     * target library etc. If there is no elf header, we dump it.
     */
    if (!(flags & PAGE_WRITE_ORG) &&
        (flags & PAGE_EXEC) &&
        memcmp(g2h_untagged(start), ELFMAG, SELFMAG) == 0) {
        return 0;
    }

    return end - start;
}

static size_t size_note(const char *name, size_t datasz)
{
    size_t namesz = strlen(name) + 1;

    namesz = ROUND_UP(namesz, 4);
    datasz = ROUND_UP(datasz, 4);

    return sizeof(struct elf_note) + namesz + datasz;
}

static void *fill_note(void **pptr, int type, const char *name, size_t datasz)
{
    void *ptr = *pptr;
    struct elf_note *n = ptr;
    size_t namesz = strlen(name) + 1;

    n->n_namesz = namesz;
    n->n_descsz = datasz;
    n->n_type = type;
    bswap_note(n);

    ptr += sizeof(*n);
    memcpy(ptr, name, namesz);

    namesz = ROUND_UP(namesz, 4);
    datasz = ROUND_UP(datasz, 4);

    *pptr = ptr + namesz + datasz;
    return ptr + namesz;
}

static void fill_elf_header(struct elfhdr *elf, int segs, uint16_t machine,
                            uint32_t flags)
{
    memcpy(elf->e_ident, ELFMAG, SELFMAG);

    elf->e_ident[EI_CLASS] = ELF_CLASS;
    elf->e_ident[EI_DATA] = ELF_DATA;
    elf->e_ident[EI_VERSION] = EV_CURRENT;
    elf->e_ident[EI_OSABI] = ELF_OSABI;

    elf->e_type = ET_CORE;
    elf->e_machine = machine;
    elf->e_version = EV_CURRENT;
    elf->e_phoff = sizeof(struct elfhdr);
    elf->e_flags = flags;
    elf->e_ehsize = sizeof(struct elfhdr);
    elf->e_phentsize = sizeof(struct elf_phdr);
    elf->e_phnum = segs;

    bswap_ehdr(elf);
}

static void fill_elf_note_phdr(struct elf_phdr *phdr, size_t sz, off_t offset)
{
    phdr->p_type = PT_NOTE;
    phdr->p_offset = offset;
    phdr->p_filesz = sz;

    bswap_phdr(phdr, 1);
}

static void fill_prstatus_note(void *data, CPUState *cpu, int signr)
{
    /*
     * Because note memory is only aligned to 4, and target_elf_prstatus
     * may well have higher alignment requirements, fill locally and
     * memcpy to the destination afterward.
     */
    struct target_elf_prstatus prstatus = {
        .pr_info.si_signo = signr,
        .pr_cursig = signr,
        .pr_pid = get_task_state(cpu)->ts_tid,
        .pr_ppid = getppid(),
        .pr_pgrp = getpgrp(),
        .pr_sid = getsid(0),
    };

    elf_core_copy_regs(&prstatus.pr_reg, cpu_env(cpu));
    bswap_prstatus(&prstatus);
    memcpy(data, &prstatus, sizeof(prstatus));
}

static void fill_prpsinfo_note(void *data, const TaskState *ts)
{
    /*
     * Because note memory is only aligned to 4, and target_elf_prpsinfo
     * may well have higher alignment requirements, fill locally and
     * memcpy to the destination afterward.
     */
    struct target_elf_prpsinfo psinfo = {
        .pr_pid = getpid(),
        .pr_ppid = getppid(),
        .pr_pgrp = getpgrp(),
        .pr_sid = getsid(0),
        .pr_uid = getuid(),
        .pr_gid = getgid(),
    };
    char *base_filename;
    size_t len;

    len = ts->info->env_strings - ts->info->arg_strings;
    len = MIN(len, ELF_PRARGSZ);
    memcpy(&psinfo.pr_psargs, g2h_untagged(ts->info->arg_strings), len);
    for (size_t i = 0; i < len; i++) {
        if (psinfo.pr_psargs[i] == 0) {
            psinfo.pr_psargs[i] = ' ';
        }
    }

    base_filename = g_path_get_basename(ts->bprm->filename);
    /*
     * Using strncpy here is fine: at max-length,
     * this field is not NUL-terminated.
     */
    strncpy(psinfo.pr_fname, base_filename, sizeof(psinfo.pr_fname));
    g_free(base_filename);

    bswap_psinfo(&psinfo);
    memcpy(data, &psinfo, sizeof(psinfo));
}

static void fill_auxv_note(void *data, const TaskState *ts)
{
    memcpy(data, g2h_untagged(ts->info->saved_auxv), ts->info->auxv_len);
}

/*
 * Constructs name of coredump file.  We have following convention
 * for the name:
 *     qemu_<basename-of-target-binary>_<date>-<time>_<pid>.core
 *
 * Returns the filename
 */
static char *core_dump_filename(const TaskState *ts)
{
    g_autoptr(GDateTime) now = g_date_time_new_now_local();
    g_autofree char *nowstr = g_date_time_format(now, "%Y%m%d-%H%M%S");
    g_autofree char *base_filename = g_path_get_basename(ts->bprm->filename);

    return g_strdup_printf("qemu_%s_%s_%d.core",
                           base_filename, nowstr, (int)getpid());
}

static int dump_write(int fd, const void *ptr, size_t size)
{
    const char *bufp = (const char *)ptr;
    ssize_t bytes_written, bytes_left;

    bytes_written = 0;
    bytes_left = size;

    /*
     * In normal conditions, single write(2) should do but
     * in case of socket etc. this mechanism is more portable.
     */
    do {
        bytes_written = write(fd, bufp, bytes_left);
        if (bytes_written < 0) {
            if (errno == EINTR)
                continue;
            return (-1);
        } else if (bytes_written == 0) { /* eof */
            return (-1);
        }
        bufp += bytes_written;
        bytes_left -= bytes_written;
    } while (bytes_left > 0);

    return (0);
}

static int wmr_page_unprotect_regions(void *opaque, vaddr start,
                                      vaddr end, int flags)
{
    if ((flags & (PAGE_WRITE | PAGE_WRITE_ORG)) == PAGE_WRITE_ORG) {
        size_t step = MAX(TARGET_PAGE_SIZE, qemu_real_host_page_size());

        while (1) {
            page_unprotect(NULL, start, 0);
            if (end - start <= step) {
                break;
            }
            start += step;
        }
    }
    return 0;
}

typedef struct {
    unsigned count;
    size_t size;
} CountAndSizeRegions;

static int wmr_count_and_size_regions(void *opaque, vaddr start,
                                      vaddr end, int flags)
{
    CountAndSizeRegions *css = opaque;

    css->count++;
    css->size += vma_dump_size(start, end, flags);
    return 0;
}

typedef struct {
    struct elf_phdr *phdr;
    off_t offset;
} FillRegionPhdr;

static int wmr_fill_region_phdr(void *opaque, vaddr start,
                                vaddr end, int flags)
{
    FillRegionPhdr *d = opaque;
    struct elf_phdr *phdr = d->phdr;

    phdr->p_type = PT_LOAD;
    phdr->p_vaddr = start;
    phdr->p_paddr = 0;
    phdr->p_filesz = vma_dump_size(start, end, flags);
    phdr->p_offset = d->offset;
    d->offset += phdr->p_filesz;
    phdr->p_memsz = end - start;
    phdr->p_flags = (flags & PAGE_READ ? PF_R : 0)
                  | (flags & PAGE_WRITE_ORG ? PF_W : 0)
                  | (flags & PAGE_EXEC ? PF_X : 0);
    phdr->p_align = TARGET_PAGE_SIZE;

    bswap_phdr(phdr, 1);
    d->phdr = phdr + 1;
    return 0;
}

static int wmr_write_region(void *opaque, vaddr start,
                            vaddr end, int flags)
{
    int fd = *(int *)opaque;
    size_t size = vma_dump_size(start, end, flags);

    if (!size) {
        return 0;
    }
    return dump_write(fd, g2h_untagged(start), size);
}

/*
 * Write out ELF coredump.
 *
 * See documentation of ELF object file format in:
 * http://www.caldera.com/developers/devspecs/gabi41.pdf
 *
 * Coredump format in linux is following:
 *
 * 0   +----------------------+         \
 *     | ELF header           | ET_CORE  |
 *     +----------------------+          |
 *     | ELF program headers  |          |--- headers
 *     | - NOTE section       |          |
 *     | - PT_LOAD sections   |          |
 *     +----------------------+         /
 *     | NOTEs:               |
 *     | - NT_PRSTATUS        |
 *     | - NT_PRSINFO         |
 *     | - NT_AUXV            |
 *     +----------------------+ <-- aligned to target page
 *     | Process memory dump  |
 *     :                      :
 *     .                      .
 *     :                      :
 *     |                      |
 *     +----------------------+
 *
 * NT_PRSTATUS -> struct elf_prstatus (per thread)
 * NT_PRSINFO  -> struct elf_prpsinfo
 * NT_AUXV is array of { type, value } pairs (see fill_auxv_note()).
 *
 * Format follows System V format as close as possible.  Current
 * version limitations are as follows:
 *     - no floating point registers are dumped
 *
 * Function returns 0 in case of success, negative errno otherwise.
 *
 * TODO: make this work also during runtime: it should be
 * possible to force coredump from running process and then
 * continue processing.  For example qemu could set up SIGUSR2
 * handler (provided that target process haven't registered
 * handler for that) that does the dump when signal is received.
 */
static int elf_core_dump(int signr, const CPUArchState *env)
{
    const CPUState *cpu = env_cpu_const(env);
    const TaskState *ts = (const TaskState *)get_task_state((CPUState *)cpu);
    struct rlimit dumpsize;
    CountAndSizeRegions css;
    off_t offset, note_offset, data_offset;
    size_t note_size;
    int cpus, ret;
    int fd = -1;
    CPUState *cpu_iter;

    if (prctl(PR_GET_DUMPABLE) == 0) {
        return 0;
    }

    if (getrlimit(RLIMIT_CORE, &dumpsize) < 0 || dumpsize.rlim_cur == 0) {
        return 0;
    }

    cpu_list_lock();
    mmap_lock();

    /* By unprotecting, we merge vmas that might be split. */
    walk_memory_regions(NULL, wmr_page_unprotect_regions);

    /*
     * Walk through target process memory mappings and
     * set up structure containing this information.
     */
    memset(&css, 0, sizeof(css));
    walk_memory_regions(&css, wmr_count_and_size_regions);

    cpus = 0;
    CPU_FOREACH(cpu_iter) {
        cpus++;
    }

    offset = sizeof(struct elfhdr);
    offset += (css.count + 1) * sizeof(struct elf_phdr);
    note_offset = offset;

    offset += size_note("CORE", ts->info->auxv_len);
    offset += size_note("CORE", sizeof(struct target_elf_prpsinfo));
    offset += size_note("CORE", sizeof(struct target_elf_prstatus)) * cpus;
    note_size = offset - note_offset;
    data_offset = TARGET_PAGE_ALIGN(offset);

    /* Do not dump if the corefile size exceeds the limit. */
    if (dumpsize.rlim_cur != RLIM_INFINITY
        && dumpsize.rlim_cur < data_offset + css.size) {
        errno = 0;
        goto out;
    }

    {
        g_autofree char *corefile = core_dump_filename(ts);
        fd = open(corefile, O_WRONLY | O_CREAT | O_TRUNC,
                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    }
    if (fd < 0) {
        goto out;
    }

    /*
     * There is a fair amount of alignment padding within the notes
     * as well as preceeding the process memory.  Allocate a zeroed
     * block to hold it all.  Write all of the headers directly into
     * this buffer and then write it out as a block.
     */
    {
        g_autofree void *header = g_malloc0(data_offset);
        FillRegionPhdr frp;
        void *hptr, *dptr;

        /* Create elf file header. */
        hptr = header;
        fill_elf_header(hptr, css.count + 1, ELF_MACHINE, 0);
        hptr += sizeof(struct elfhdr);

        /* Create elf program headers. */
        fill_elf_note_phdr(hptr, note_size, note_offset);
        hptr += sizeof(struct elf_phdr);

        frp.phdr = hptr;
        frp.offset = data_offset;
        walk_memory_regions(&frp, wmr_fill_region_phdr);
        hptr = frp.phdr;

        /* Create the notes. */
        dptr = fill_note(&hptr, NT_AUXV, "CORE", ts->info->auxv_len);
        fill_auxv_note(dptr, ts);

        dptr = fill_note(&hptr, NT_PRPSINFO, "CORE",
                         sizeof(struct target_elf_prpsinfo));
        fill_prpsinfo_note(dptr, ts);

        CPU_FOREACH(cpu_iter) {
            dptr = fill_note(&hptr, NT_PRSTATUS, "CORE",
                             sizeof(struct target_elf_prstatus));
            fill_prstatus_note(dptr, cpu_iter, cpu_iter == cpu ? signr : 0);
        }

        if (dump_write(fd, header, data_offset) < 0) {
            goto out;
        }
    }

    /*
     * Finally write process memory into the corefile as well.
     */
    if (walk_memory_regions(&fd, wmr_write_region) < 0) {
        goto out;
    }
    errno = 0;

 out:
    ret = -errno;
    mmap_unlock();
    cpu_list_unlock();
    if (fd >= 0) {
        close(fd);
    }
    return ret;
}
#endif /* HAVE_ELF_CORE_DUMP */
