// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <launchpad/launchpad.h>
#include <launchpad/vmo.h>
#include "elf.h"

#include <assert.h>
#include <ldmsg/ldmsg.h>
#include <lib/elf-psabi/sp.h>
#include <lib/fdio/io.h>
#include <lib/zircon-internal/default_stack_size.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <threads.h>
#include <zircon/assert.h>
#include <zircon/dlfcn.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

enum special_handles {
    HND_LDSVC_LOADER,
    HND_EXEC_VMO,
    HND_SEGMENTS_VMAR,
    HND_SPECIAL_COUNT
};

struct launchpad {
    uint32_t argc;
    uint32_t envc;
    uint32_t namec;
    char* args;
    size_t args_len;
    char* env;
    size_t env_len;
    char* names;
    size_t names_len;

    size_t num_script_args;
    char* script_args;
    size_t script_args_len;

    zx_handle_t* handles;
    uint32_t* handles_info;
    size_t handle_count;
    size_t handle_alloc;

    const char* errmsg;
    zx_status_t error;

    zx_vaddr_t entry;
    zx_vaddr_t base;
    zx_vaddr_t vdso_base;

    size_t stack_size;
    bool set_stack_size;

    zx_handle_t special_handles[HND_SPECIAL_COUNT];
    bool loader_message;

    zx_handle_t reserve_vmar;
    bool fresh_process;
};

// Returned when calloc() fails on create, so callers
// can still call all the various add handles functions
// which will discard the handles, etc, etc.
static launchpad_t invalid_launchpad = {
    .errmsg = "create: could not allocate launchpad_t",
    .error = ZX_ERR_NO_MEMORY,
};

static zx_status_t lp_error(launchpad_t* lp, zx_status_t error, const char* msg) {
    if (lp->error == ZX_OK) {
        lp->error = error;
        lp->errmsg = msg;
    }
    return lp->error;
}

zx_status_t launchpad_get_status(launchpad_t* lp) {
    return lp->error;
}

void launchpad_abort(launchpad_t* lp, zx_status_t error, const char* msg) {
    lp_error(lp, (error < 0) ? error : ZX_ERR_INTERNAL, msg);
}

const char* launchpad_error_message(launchpad_t* lp) {
    return lp->errmsg;
}

#define HND_LOADER_COUNT 3
// We always install the process handle as the first in the message.
#define lp_proc(lp) ((lp)->handles[0])
// We always install the vmar handle as the second in the message.
#define lp_vmar(lp) ((lp)->handles[1])

void launchpad_destroy(launchpad_t* lp) {
    if (lp == &invalid_launchpad)
        return;
    zx_handle_close(lp->reserve_vmar);
    zx_handle_close_many(lp->special_handles, HND_SPECIAL_COUNT);
    zx_handle_close_many(lp->handles, lp->handle_count);
    free(lp->handles);
    free(lp->handles_info);
    free(lp->script_args);
    free(lp->args);
    free(lp->env);
    free(lp->names);
    free(lp);
}

// Create a new launchpad for a given existing process handle and
// its root VMAR handle.  On success, the launchpad takes ownership
// of both handles.
static zx_status_t launchpad_create_with_process(zx_handle_t proc,
                                                 zx_handle_t vmar,
                                                 launchpad_t** result) {
    launchpad_t* lp = calloc(1, sizeof(*lp));
    if (lp == NULL) {
        lp = &invalid_launchpad;
    } else {
        lp->errmsg = "no error";
    }

    if (launchpad_add_handle(lp, proc, PA_PROC_SELF) == ZX_OK) {
        // If the process has an existing vDSO mapping, record it for
        // use by launchpad_start_extra.
        zx_status_t status = zx_object_get_property(
            proc, ZX_PROP_PROCESS_VDSO_BASE_ADDRESS,
            &lp->vdso_base, sizeof(lp->vdso_base));
        if (status != ZX_OK)
            lp_error(lp, status,
                     "create: cannot get ZX_PROP_PROCESS_VDSO_BASE_ADDRESS");
    }
    launchpad_add_handle(lp, vmar, PA_VMAR_ROOT);

    *result = lp;
    return lp->error;
}

// Create a new process and a launchpad that will set it up.
zx_status_t launchpad_create_with_jobs(zx_handle_t creation_job, zx_handle_t transferred_job,
                                       const char* name, launchpad_t** result) {
    uint32_t name_len = strlen(name);

    zx_handle_t proc = ZX_HANDLE_INVALID;
    zx_handle_t vmar = ZX_HANDLE_INVALID;
    zx_status_t status = zx_process_create(creation_job, name, name_len, 0, &proc, &vmar);

    launchpad_t* lp;
    if (launchpad_create_with_process(proc, vmar, &lp) == ZX_OK)
        lp->fresh_process = true;

    if (status < 0)
        lp_error(lp, status, "create: zx_process_create() failed");

    if (transferred_job != ZX_HANDLE_INVALID) {
        launchpad_add_handle(lp, transferred_job, PA_JOB_DEFAULT);
    }

    *result = lp;
    return lp->error;
}

zx_status_t launchpad_create(zx_handle_t job,
                             const char* name, launchpad_t** result) {
    if (job == ZX_HANDLE_INVALID)
        job = zx_job_default();
    zx_handle_t xjob = ZX_HANDLE_INVALID;
    zx_handle_duplicate(job, ZX_RIGHT_SAME_RIGHTS, &xjob);
    return launchpad_create_with_jobs(job, xjob, name, result);
}

zx_handle_t launchpad_get_process_handle(launchpad_t* lp) {
    return lp_proc(lp);
}

zx_handle_t launchpad_get_root_vmar_handle(launchpad_t* lp) {
    return lp_vmar(lp);
}

static zx_status_t build_stringtable(launchpad_t* lp,
                                    int count, const char* const* item,
                                    size_t* total_out, char** out) {
    if (lp->error)
        return lp->error;
    if (count < 0)
        return lp_error(lp, ZX_ERR_INVALID_ARGS, "negative string array count");

    size_t total = 0;
    for (int i = 0; i < count; ++i)
        total += strlen(item[i]) + 1;

    char* buffer = NULL;
    if (total > 0) {
        buffer = malloc(total);
        if (buffer == NULL)
            return lp_error(lp, ZX_ERR_NO_MEMORY, "out of memory for string array");

        char* p = buffer;
        for (int i = 0; i < count; ++i)
            p = stpcpy(p, item[i]) + 1;

        if ((size_t) (p - buffer) != total) {
            // The strings changed in parallel.  Not kosher!
            free(buffer);
            return lp_error(lp, ZX_ERR_INVALID_ARGS, "string array modified during use");
        }
    }

    *total_out = total;
    *out = buffer;
    return ZX_OK;
}

zx_status_t launchpad_set_args(launchpad_t* lp,
                               int argc, const char* const* argv) {
    size_t total;
    char* buffer;
    zx_status_t r = build_stringtable(lp, argc, argv, &total, &buffer);
    if (r < 0)
        return r;

    free(lp->args);
    lp->argc = argc;
    lp->args = buffer;
    lp->args_len = total;
    return ZX_OK;
}

zx_status_t launchpad_set_nametable(launchpad_t* lp,
                                    size_t count, const char* const* names) {
    size_t total;
    char* buffer;
    zx_status_t r = build_stringtable(lp, count, names, &total, &buffer);
    if (r < 0)
        return r;

    free(lp->names);
    lp->namec = count;
    lp->names = buffer;
    lp->names_len = total;
    return ZX_OK;
}

zx_status_t launchpad_set_environ(launchpad_t* lp, const char* const* envp) {
    uint32_t count = 0;
    if (envp != NULL) {
        for (const char* const* ep = envp; *ep != NULL; ++ep) {
            ++count;
        }
    }

    size_t total;
    char* buffer;
    zx_status_t r = build_stringtable(lp, count, envp, &total, &buffer);
    if (r < 0)
        return r;

    free(lp->env);
    lp->envc = count;
    lp->env = buffer;
    lp->env_len = total;
    return ZX_OK;
}

static zx_status_t more_handles(launchpad_t* lp, size_t n) {
    if (lp->error)
        return lp->error;

    if (ZX_CHANNEL_MAX_MSG_HANDLES - lp->handle_count < n)
        return lp_error(lp, ZX_ERR_NO_MEMORY, "too many handles for handle table");

    if (lp->handle_alloc - lp->handle_count < n) {
        size_t alloc = lp->handle_alloc == 0 ? 8 : lp->handle_alloc * 2;
        while (alloc - lp->handle_count < n)
            alloc <<= 1;
        zx_handle_t* handles = realloc(lp->handles,
                                       alloc * sizeof(handles[0]));
        if (handles == NULL)
            return lp_error(lp, ZX_ERR_NO_MEMORY, "out of memory for handle table");
        lp->handles = handles;
        uint32_t* info = realloc(lp->handles_info, alloc * sizeof(info[0]));
        if (info == NULL)
            return lp_error(lp, ZX_ERR_NO_MEMORY, "out of memory for handle table");
        lp->handles_info = info;
        lp->handle_alloc = alloc;
    }
    return ZX_OK;
}

zx_status_t launchpad_add_handle(launchpad_t* lp, zx_handle_t h, uint32_t id) {
    if (h == ZX_HANDLE_INVALID)
        return lp_error(lp, ZX_ERR_BAD_HANDLE, "added invalid handle");
    zx_status_t status = more_handles(lp, 1);
    if (status == ZX_OK) {
        lp->handles[lp->handle_count] = h;
        lp->handles_info[lp->handle_count] = id;
        ++lp->handle_count;
    } else {
        zx_handle_close(h);
    }
    return status;
}

zx_status_t launchpad_add_handles(launchpad_t* lp, size_t n,
                                  const zx_handle_t h[],
                                  const uint32_t id[]) {
    zx_status_t status = more_handles(lp, n);
    if (status == ZX_OK) {
        memcpy(&lp->handles[lp->handle_count], h, n * sizeof(h[0]));
        memcpy(&lp->handles_info[lp->handle_count], id, n * sizeof(id[0]));
        lp->handle_count += n;
        for (size_t i = 0; i < n; i++) {
            if (h[i] == ZX_HANDLE_INVALID) {
                return lp_error(lp, ZX_ERR_BAD_HANDLE, "added invalid handle");
            }
        }
    } else {
        for (size_t i = 0; i < n; i++) {
            zx_handle_close(h[i]);
        }
    }
    return status;
}

static void check_elf_stack_size(launchpad_t* lp, elf_load_info_t* elf) {
    size_t elf_stack_size = elf_load_get_stack_size(elf);
    if (elf_stack_size > 0)
        launchpad_set_stack_size(lp, elf_stack_size);
}

zx_status_t launchpad_elf_load_basic(launchpad_t* lp, zx_handle_t vmo) {
    if (vmo == ZX_HANDLE_INVALID)
        return lp_error(lp, ZX_ERR_INVALID_ARGS, "elf_load: invalid vmo");
    if (lp->error)
        goto done;

    elf_load_info_t* elf;
    zx_status_t status;
    if ((status = elf_load_start(vmo, NULL, 0, &elf)))
        lp_error(lp, status, "elf_load: elf_load_start() failed");
    zx_handle_t segments_vmar;
    if ((status = elf_load_finish(lp_vmar(lp), elf, vmo,
                                  &segments_vmar, &lp->base, &lp->entry)))
        lp_error(lp, status, "elf_load: elf_load_finish() failed");
    check_elf_stack_size(lp, elf);
    elf_load_destroy(elf);

    if (status == ZX_OK) {
        lp->loader_message = false;
        launchpad_add_handle(lp, segments_vmar,
                             PA_HND(PA_VMAR_LOADED, 0));
    }

done:
    zx_handle_close(vmo);
    return lp->error;
}

zx_status_t launchpad_elf_load_extra(launchpad_t* lp, zx_handle_t vmo,
                                     zx_vaddr_t* base, zx_vaddr_t* entry) {
    if (lp->error)
        return lp->error;
    if (vmo == ZX_HANDLE_INVALID)
        return lp_error(lp, ZX_ERR_INVALID_ARGS, "elf_load_extra: invalid vmo");

    elf_load_info_t* elf;
    zx_status_t status;
    if ((status = elf_load_start(vmo, NULL, 0, &elf)))
        lp_error(lp, status, "elf_load_extra: elf_load_start() failed");
    if ((status = elf_load_finish(lp_vmar(lp), elf, vmo, NULL, base, entry)))
        lp_error(lp, status, "elf_load_extra: elf_load_finish() failed");
    elf_load_destroy(elf);

    return lp->error;
}

#define LOADER_SVC_MSG_MAX 1024

static zx_status_t loader_svc_rpc(zx_handle_t loader_svc, uint32_t ordinal,
                                  const void* data, size_t len, zx_handle_t* out) {
    static _Atomic zx_txid_t next_txid;

    ldmsg_req_t req;
    memset(&req.header, 0, sizeof(req.header));
    req.header.ordinal = ordinal;

    size_t req_len;
    zx_status_t status = ldmsg_req_encode(&req, &req_len, data, len);
    if (status != ZX_OK)
        return status;

    req.header.txid = atomic_fetch_add(&next_txid, 1);

    ldmsg_rsp_t rsp;
    memset(&rsp, 0, sizeof(rsp));

    zx_handle_t handle = ZX_HANDLE_INVALID;
    const zx_channel_call_args_t call = {
        .wr_bytes = &req,
        .wr_num_bytes = req_len,
        .rd_bytes = &rsp,
        .rd_num_bytes = sizeof(rsp),
        .rd_handles = &handle,
        .rd_num_handles = 1,
    };
    uint32_t reply_size;
    uint32_t handle_count;
    status = zx_channel_call(loader_svc, 0, ZX_TIME_INFINITE, &call, &reply_size, &handle_count);
    if (status != ZX_OK)
        return status;

    // Check for protocol violations.
    if (reply_size != ldmsg_rsp_get_size(&rsp)) {
    protocol_violation:
        zx_handle_close(handle);
        return ZX_ERR_BAD_STATE;
    }
    if (rsp.header.ordinal != ordinal)
        goto protocol_violation;

    if (rsp.rv != ZX_OK) {
        if (handle != ZX_HANDLE_INVALID)
            goto protocol_violation;
        if (rsp.rv > 0)
            goto protocol_violation;
        *out = ZX_HANDLE_INVALID;
    } else {
        *out = handle_count ? handle : ZX_HANDLE_INVALID;
    }
    return rsp.rv;
}

static zx_status_t setup_loader_svc(launchpad_t* lp) {
    if (lp->special_handles[HND_LDSVC_LOADER] != ZX_HANDLE_INVALID)
        return ZX_OK;

    zx_handle_t loader_svc;
    zx_status_t status = dl_clone_loader_service(&loader_svc);
    if (status < 0)
        return status;

    lp->special_handles[HND_LDSVC_LOADER] = loader_svc;
    return ZX_OK;
}

// Reserve roughly the low half of the address space, so the new
// process can use sanitizers that need to allocate shadow memory there.
// The reservation VMAR is kept around just long enough to make sure all
// the initial allocations (mapping in the initial ELF objects, and
// allocating the initial stack) stay out of this area, and then destroyed.
// The process's own allocations can then use the full address space; if
// it's using a sanitizer, it will set up its shadow memory first thing.
static zx_status_t reserve_low_address_space(launchpad_t* lp) {
    if (lp->reserve_vmar != ZX_HANDLE_INVALID)
        return ZX_OK;

    zx_info_vmar_t info;
    zx_status_t status = zx_object_get_info(lp_vmar(lp), ZX_INFO_VMAR,
                                            &info, sizeof(info), NULL, NULL);
    if (status != ZX_OK) {
        return lp_error(lp, status,
                        "zx_object_get_info failed on child root VMAR handle");
    }

    uintptr_t addr;
    size_t reserve_size =
        (((info.base + info.len) / 2) + PAGE_SIZE - 1) & -PAGE_SIZE;
    status = zx_vmar_allocate(lp_vmar(lp), ZX_VM_SPECIFIC, 0,
                              reserve_size - info.base,
                              &lp->reserve_vmar, &addr);
    if (status != ZX_OK) {
        return lp_error(
            lp, status,
            "zx_vmar_allocate failed for low address space reservation");
    }

    if (addr != info.base) {
        return lp_error(lp, ZX_ERR_BAD_STATE,
                        "zx_vmar_allocate gave wrong address?!?");
    }

    return ZX_OK;
}

// Consumes 'vmo' on success, not on failure.
static zx_status_t handle_interp(launchpad_t* lp, zx_handle_t vmo,
                                 const char* interp, size_t interp_len) {
    zx_status_t status = setup_loader_svc(lp);
    if (status != ZX_OK)
        return status;

    zx_handle_t interp_vmo;
    status = loader_svc_rpc(
        lp->special_handles[HND_LDSVC_LOADER], LDMSG_OP_LOAD_OBJECT,
        interp, interp_len, &interp_vmo);
    if (status != ZX_OK)
        return status;

    if (lp->fresh_process) {
        // A fresh process using PT_INTERP might be loading a libc.so that
        // supports sanitizers, so in that case (the most common case)
        // keep the mappings launchpad makes out of the low address region.
        status = reserve_low_address_space(lp);
        if (status != ZX_OK)
            return status;
    }

    elf_load_info_t* elf;
    zx_handle_t segments_vmar;
    status = elf_load_start(interp_vmo, NULL, 0, &elf);
    if (status == ZX_OK) {
        status = elf_load_finish(lp_vmar(lp), elf, interp_vmo,
                                 &segments_vmar, &lp->base, &lp->entry);
        elf_load_destroy(elf);
    }
    zx_handle_close(interp_vmo);

    if (status == ZX_OK) {
        if (lp->special_handles[HND_EXEC_VMO] != ZX_HANDLE_INVALID)
            zx_handle_close(lp->special_handles[HND_EXEC_VMO]);
        lp->special_handles[HND_EXEC_VMO] = vmo;
        if (lp->special_handles[HND_SEGMENTS_VMAR] != ZX_HANDLE_INVALID)
            zx_handle_close(lp->special_handles[HND_SEGMENTS_VMAR]);
        lp->special_handles[HND_SEGMENTS_VMAR] = segments_vmar;
        lp->loader_message = true;
    }

    return status;
}

static zx_status_t launchpad_elf_load_body(launchpad_t* lp, const char* hdr_buf,
                                           size_t buf_sz, zx_handle_t vmo) {
    elf_load_info_t* elf;
    zx_status_t status;

    if (lp->error)
        goto done;
    if ((status = elf_load_start(vmo, hdr_buf, buf_sz, &elf)) != ZX_OK) {
        lp_error(lp, status, "elf_load: elf_load_start() failed");
    } else {
        char* interp;
        size_t interp_len;
        status = elf_load_get_interp(elf, vmo, &interp, &interp_len);
        if (status != ZX_OK) {
            lp_error(lp, status, "elf_load: get_interp() failed");
        } else {
            if (interp == NULL) {
                zx_handle_t segments_vmar;
                status = elf_load_finish(lp_vmar(lp), elf, vmo, &segments_vmar,
                                         &lp->base, &lp->entry);
                if (status != ZX_OK) {
                    lp_error(lp, status, "elf_load: elf_load_finish() failed");
                } else {
                    // With no PT_INTERP, we obey PT_GNU_STACK.p_memsz for
                    // the stack size setting.  With PT_INTERP, the dynamic
                    // linker is responsible for that.
                    check_elf_stack_size(lp, elf);
                    lp->loader_message = false;
                    launchpad_add_handle(
                        lp, segments_vmar,
                        PA_HND(PA_VMAR_LOADED, 0));
                }
            } else {
                if ((status = handle_interp(lp, vmo, interp, interp_len))) {
                    lp_error(lp, status, "elf_load: handle_interp failed");
                } else {
                    // handle_interp() takes ownership of vmo on success
                    vmo = ZX_HANDLE_INVALID;
                }
                free(interp);
            }
        }
        elf_load_destroy(elf);
    }
done:
    if (vmo)
        zx_handle_close(vmo);
    return lp->error;
}

// Find the starting point of the interpreter and the interpreter
// arguments in a #! script header. Note that the input buffer (line)
// will be modified to add a NULL after the interpreter name.
static zx_status_t parse_interp_spec(char *line, char **interp_start,
                                     size_t *interp_len, char **args_start)
{
    *args_start = NULL;

    // Skip the '#!' prefix
    char* next_char = line + 2;

    // Skip whitespace
    next_char += strspn(next_char, " \t");

    // No interpreter specified
    if (*next_char == '\0')
        return ZX_ERR_NOT_FOUND;

    *interp_start = next_char;

    // Skip the interpreter name
    next_char += strcspn(next_char, " \t");
    *interp_len = next_char - *interp_start;

    if (*next_char == '\0')
        return ZX_OK;

    *next_char++ = '\0';

    // Look for the args
    next_char += strspn(next_char, " \t");

    if (*next_char == '\0')
        return ZX_OK;

    *args_start = next_char;
    return ZX_OK;
}

zx_status_t launchpad_file_load(launchpad_t* lp, zx_handle_t vmo) {
    if (vmo == ZX_HANDLE_INVALID)
        return lp_error(lp, ZX_ERR_INVALID_ARGS, "file_load: invalid vmo");

    if (lp->script_args != NULL) {
        free(lp->script_args);
        lp->script_args = NULL;
    }
    lp->script_args_len = 0;
    lp->num_script_args = 0;

    size_t script_nest_level = 0;

    char first_line[LP_MAX_INTERP_LINE_LEN + 1];
    size_t to_read = sizeof(first_line);
    size_t vmo_size;
    zx_status_t status = zx_vmo_get_size(vmo, &vmo_size);
    if (status != ZX_OK) {
        return lp_error(lp, status, "file_load: zx_vmo_get_size() failed");
    }
    if (to_read > vmo_size) {
        to_read = vmo_size;
    }

    while (1) {
        // Read enough to get the interpreter specification of a script
        status = zx_vmo_read(vmo, first_line, 0, to_read);

        // This is not a script -- load as an ELF file
        if ((status == ZX_OK)
            && (to_read < 2 || first_line[0] != '#' || first_line[1] != '!'))
            break;

        zx_handle_close(vmo);

        if (status != ZX_OK)
            return lp_error(lp, status, "file_load: zx_vmo_read() failed");

        script_nest_level++;

        // No point trying to read an interpreter we're not going to consider
        if (script_nest_level > LP_MAX_SCRIPT_NEST_LEVEL)
            return lp_error(lp, ZX_ERR_NOT_SUPPORTED,
                            "file_load: too many levels of script indirection");

        // Normalize the line so that it is NULL-terminated
        char* newline_pos = memchr(first_line, '\n', to_read);
        if (newline_pos)
            *newline_pos = '\0';
        else if (to_read == sizeof(first_line))
            return lp_error(lp, ZX_ERR_OUT_OF_RANGE,
                            "file_load: first line of script too long");
        else
            first_line[to_read] = '\0';

        char* interp_start;
        size_t interp_len;
        char* args_start;
        status = parse_interp_spec(first_line, &interp_start, &interp_len,
                                   &args_start);
        if (status != ZX_OK)
            return lp_error(lp, status,
                            "file_load: failed to parse interpreter spec");

        size_t args_len = (args_start == NULL) ? 0 : newline_pos - args_start;

        // Add interpreter and args to start of lp->script_args
        size_t new_args_len = interp_len + 1;
        if (args_start != NULL)
            new_args_len += args_len + 1;
        char *new_buf = malloc(new_args_len + lp->script_args_len);
        if (new_buf == NULL)
            return lp_error(lp, ZX_ERR_NO_MEMORY, "file_load: out of memory");

        memcpy(new_buf, interp_start, interp_len + 1);
        lp->num_script_args++;

        if (args_start != NULL) {
            memcpy(&new_buf[interp_len + 1], args_start, args_len + 1);
            lp->num_script_args++;
        }

        if (lp->script_args != NULL) {
            memcpy(&new_buf[new_args_len], lp->script_args,
                   lp->script_args_len);
            free(lp->script_args);
        }

        lp->script_args = new_buf;
        lp->script_args_len += new_args_len;

        // Load the interpreter into memory
        status = setup_loader_svc(lp);
        if (status != ZX_OK)
            return lp_error(lp, status, "file_load: setup_loader_svc() failed");

        status = loader_svc_rpc(lp->special_handles[HND_LDSVC_LOADER],
                             LDMSG_OP_LOAD_SCRIPT_INTERPRETER,
                             interp_start, interp_len, &vmo);
        if (status != ZX_OK)
            return lp_error(lp, status, "file_load: loader_svc_rpc() failed");
    }

    // Finally, load the interpreter itself
    status = launchpad_elf_load_body(lp, first_line, to_read, vmo);

    if (status != ZX_OK)
        lp_error(lp, status, "file_load: failed to load ELF file");

    return status;
}

zx_status_t launchpad_elf_load(launchpad_t* lp, zx_handle_t vmo) {
    if (vmo == ZX_HANDLE_INVALID)
        return lp_error(lp, ZX_ERR_INVALID_ARGS, "elf_load: invalid vmo");

    return launchpad_elf_load_body(lp, NULL, 0, vmo);
}

static zx_handle_t vdso_vmo = ZX_HANDLE_INVALID;
static mtx_t vdso_mutex = MTX_INIT;
static void vdso_lock(void) __TA_ACQUIRE(&vdso_mutex) {
    mtx_lock(&vdso_mutex);
}
static void vdso_unlock(void) __TA_RELEASE(&vdso_mutex) {
    mtx_unlock(&vdso_mutex);
}
static zx_handle_t vdso_get_vmo(void) {
    if (vdso_vmo == ZX_HANDLE_INVALID)
        vdso_vmo = zx_take_startup_handle(PA_HND(PA_VMO_VDSO, 0));
    return vdso_vmo;
}

zx_status_t launchpad_get_vdso_vmo(zx_handle_t* out) {
    vdso_lock();
    zx_status_t status = zx_handle_duplicate(vdso_get_vmo(),
                                             ZX_RIGHT_SAME_RIGHTS, out);
    vdso_unlock();
    return status;
}

zx_handle_t launchpad_set_vdso_vmo(zx_handle_t new_vdso_vmo) {
    vdso_lock();
    zx_handle_t old = vdso_vmo;
    vdso_vmo = new_vdso_vmo;
    vdso_unlock();
    return old;
}

zx_status_t launchpad_add_vdso_vmo(launchpad_t* lp) {
    if (lp->error)
        return lp->error;
    zx_handle_t vdso;
    zx_status_t status;
    if ((status = launchpad_get_vdso_vmo(&vdso)) != ZX_OK)
        return lp_error(lp, status, "add_vdso_vmo: get_vdso_vmo failed");
    // Takes ownership of 'vdso'.
    return launchpad_add_handle(lp, vdso, PA_HND(PA_VMO_VDSO, 0));
}

zx_status_t launchpad_load_vdso(launchpad_t* lp, zx_handle_t vmo) {
    if (vmo != ZX_HANDLE_INVALID)
        return launchpad_elf_load_extra(lp, vmo, &lp->vdso_base, NULL);
    vdso_lock();
    vmo = vdso_get_vmo();
    zx_status_t status = launchpad_elf_load_extra(lp, vmo,
                                                  &lp->vdso_base, NULL);
    vdso_unlock();
    return status;
}

zx_status_t launchpad_get_entry_address(launchpad_t* lp, zx_vaddr_t* entry) {
    if (lp->entry == 0)
        return ZX_ERR_BAD_STATE;
    *entry = lp->entry;
    return ZX_OK;
}

zx_status_t launchpad_get_base_address(launchpad_t* lp, zx_vaddr_t* base) {
    if (lp->base == 0)
        return ZX_ERR_BAD_STATE;
    *base = lp->base;
    return ZX_OK;
}

bool launchpad_send_loader_message(launchpad_t* lp, bool do_send) {
    bool result = lp->loader_message;
    if (!lp->error)
        lp->loader_message = do_send;
    return result;
}

zx_handle_t launchpad_use_loader_service(launchpad_t* lp, zx_handle_t svc) {
    zx_handle_t result = lp->special_handles[HND_LDSVC_LOADER];
    lp->special_handles[HND_LDSVC_LOADER] = svc;
    return result;
}

// Construct a load message. Fill in the header, args, and environment
// fields, and leave space for the handles, which should be filled in
// by the caller.
// TODO(mcgrathr): One day we'll have a gather variant of message_write
// and then we can send this without copying into a temporary buffer.
static zx_status_t build_message(launchpad_t* lp, size_t num_handles,
                                 void** msg_buf, size_t* buf_size,
                                 bool with_names) {

    size_t msg_size = sizeof(zx_proc_args_t);
    static_assert(sizeof(zx_proc_args_t) % sizeof(uint32_t) == 0,
                  "handles misaligned in load message");
    msg_size += sizeof(uint32_t) * num_handles;
    msg_size += lp->script_args_len;
    msg_size += lp->args_len;
    msg_size += lp->env_len;
    msg_size += lp->names_len;
    void* msg = malloc(msg_size);
    if (msg == NULL)
        return ZX_ERR_NO_MEMORY;

    zx_proc_args_t* header = msg;

    memset(header, 0, sizeof(*header));
    header->protocol = ZX_PROCARGS_PROTOCOL;
    header->version = ZX_PROCARGS_VERSION;
    header->handle_info_off = sizeof(*header);

    // Include the argument strings so the dynamic linker can use argv[0]
    // in messages it prints.
    header->args_off = header->handle_info_off +
                       sizeof(uint32_t) * num_handles;
    header->args_num = lp->num_script_args + lp->argc;
    if (header->args_num > 0) {
        uint8_t* script_args_start = (uint8_t*)msg + header->args_off;
        memcpy(script_args_start, lp->script_args, lp->script_args_len);
        uint8_t* args_start = script_args_start + lp->script_args_len;
        memcpy(args_start, lp->args, lp->args_len);
    }
    size_t total_args_len = lp->script_args_len + lp->args_len;

    // Include the environment strings so the dynamic linker can
    // see options like LD_DEBUG or whatnot.
    if (lp->envc > 0) {
        header->environ_off = header->args_off + total_args_len;
        header->environ_num = lp->envc;
        uint8_t* env_start = (uint8_t*)msg + header->environ_off;
        memcpy(env_start, lp->env, lp->env_len);
    }

    if (with_names && (lp->namec > 0)) {
        header->names_off = header->args_off + total_args_len + lp->env_len;
        header->names_num = lp->namec;
        uint8_t* names_start = (uint8_t*)msg + header->names_off;
        memcpy(names_start, lp->names, lp->names_len);
    }

    *msg_buf = msg;
    *buf_size = msg_size;
    return ZX_OK;
}

static zx_status_t send_loader_message(launchpad_t* lp,
                                       zx_handle_t first_thread,
                                       zx_handle_t tochannel) {
    void* msg;
    size_t msg_size;
    size_t num_handles = HND_SPECIAL_COUNT + HND_LOADER_COUNT;

    zx_status_t status = build_message(lp, num_handles, &msg, &msg_size, false);
    if (status != ZX_OK)
        return status;

    zx_proc_args_t* header = msg;
    uint32_t* msg_handle_info;
    msg_handle_info = (uint32_t*) ((uint8_t*)msg + header->handle_info_off);

    // This loop should be completely unrolled.  But using a switch here
    // gives us compiler warnings if we forget to handle any of the special
    // types listed in the enum.
    zx_handle_t handles[HND_SPECIAL_COUNT + HND_LOADER_COUNT];
    size_t nhandles = 0;
    for (enum special_handles i = 0; i <= HND_SPECIAL_COUNT; ++i) {
        uint32_t id = 0; // -Wall
        switch (i) {
        case HND_SPECIAL_COUNT:;
            // Duplicate the handles for the loader so we can send them in the
            // loader message and still have them later.
            zx_handle_t proc;
            status = zx_handle_duplicate(lp_proc(lp), ZX_RIGHT_SAME_RIGHTS, &proc);
            if (status != ZX_OK) {
                free(msg);
                return status;
            }
            zx_handle_t vmar;
            status = zx_handle_duplicate(lp_vmar(lp), ZX_RIGHT_SAME_RIGHTS, &vmar);
            if (status != ZX_OK) {
                zx_handle_close(proc);
                free(msg);
                return status;
            }
            zx_handle_t thread;
            status = zx_handle_duplicate(first_thread, ZX_RIGHT_SAME_RIGHTS, &thread);
            if (status != ZX_OK) {
                zx_handle_close(proc);
                zx_handle_close(vmar);
                free(msg);
                return status;
            }
            handles[nhandles] = proc;
            msg_handle_info[nhandles] = PA_PROC_SELF;
            handles[nhandles + 1] = vmar;
            msg_handle_info[nhandles + 1] = PA_VMAR_ROOT;
            handles[nhandles + 2] = thread;
            msg_handle_info[nhandles + 2] = PA_THREAD_SELF;
            nhandles += HND_LOADER_COUNT;
            continue;

        case HND_LDSVC_LOADER:
            id = PA_LDSVC_LOADER;
            break;

        case HND_EXEC_VMO:
            id = PA_VMO_EXECUTABLE;
            break;

        case HND_SEGMENTS_VMAR:
            id = PA_VMAR_LOADED;
            break;
        }
        if (lp->special_handles[i] != ZX_HANDLE_INVALID) {
            handles[nhandles] = lp->special_handles[i];
            msg_handle_info[nhandles] = id;
            ++nhandles;
        }
    }

    status = zx_channel_write(tochannel, 0, msg, msg_size, handles, nhandles);
    if (status == ZX_OK)
        lp->loader_message = false;

    // message_write consumed all those handles.
    for (enum special_handles i = 0; i < HND_SPECIAL_COUNT; ++i)
        lp->special_handles[i] = ZX_HANDLE_INVALID;

    free(msg);
    return status;
}

size_t launchpad_set_stack_size(launchpad_t* lp, size_t new_size) {
    size_t old_size = lp->stack_size;
    if (new_size >= (SIZE_MAX & -PAGE_SIZE)) {
        // Ridiculously large size won't actually work at allocation time,
        // but at least page rounding won't wrap it around to zero.
        new_size = SIZE_MAX & -PAGE_SIZE;
    } else if (new_size > 0) {
        // Round up to page size.
        new_size = (new_size + PAGE_SIZE - 1) & -PAGE_SIZE;
    }
    if (lp->error == ZX_OK) {
        lp->stack_size = new_size;
        lp->set_stack_size = true;
    }
    return old_size;
}

static zx_status_t prepare_start(launchpad_t* lp, launchpad_start_data_t* result) {
    if (lp->entry == 0)
        return lp_error(lp, ZX_ERR_BAD_STATE, "prepare start bad state");

    zx_status_t status = ZX_OK;
    zx_handle_t to_child = ZX_HANDLE_INVALID;
    zx_handle_t bootstrap = ZX_HANDLE_INVALID;
    zx_handle_t process = ZX_HANDLE_INVALID;
    zx_handle_t root_vmar = ZX_HANDLE_INVALID;
    zx_handle_t thread = ZX_HANDLE_INVALID;
    void *msg = NULL;

    status = zx_channel_create(0, &to_child, &bootstrap);
    if (status != ZX_OK)
        return lp_error(lp, status, "start: cannot create channel");

    const char* thread_name = "initial-thread";
    status = zx_thread_create(lp_proc(lp), thread_name, strlen(thread_name), 0, &thread);
    if (status != ZX_OK) {
        lp_error(lp, status, "cannot create initial thread");
        goto cleanup;
    }

    // Pass the thread handle down to the child.  The handle we pass
    // will be consumed by message_write.  So we need a duplicate to
    // pass to zx_process_start later.
    zx_handle_t thread_copy;
    status = zx_handle_duplicate(thread, ZX_RIGHT_SAME_RIGHTS, &thread_copy);
    if (status != ZX_OK) {
        lp_error(lp, status, "cannot duplicate thread handle");
        goto cleanup;
    }

    status = launchpad_add_handle(lp, thread_copy, PA_THREAD_SELF);
    if (status != ZX_OK) {
        lp_error(lp, status, "cannot add thread self handle");
        goto cleanup;
    }

    bool sent_loader_message = lp->loader_message;
    if (lp->loader_message) {
        status = send_loader_message(lp, thread, to_child);
        if (status != ZX_OK) {
            lp_error(lp, status, "failed to send loader message");
            goto cleanup;
        }
    }

    bool allocate_stack = !lp->set_stack_size || lp->stack_size > 0;

    size_t size;
    if (build_message(lp, lp->handle_count + (allocate_stack ? 1 : 0),
                      &msg, &size, true) != ZX_OK) {
        lp_error(lp, ZX_ERR_NO_MEMORY,
                 "out of memory assembling procargs message");
        goto cleanup;
    }
    zx_proc_args_t* header = msg;
    uint32_t* next_handle = mempcpy((uint8_t*)msg + header->handle_info_off,
                                    lp->handles_info,
                                    lp->handle_count * sizeof(lp->handles_info[0]));
    if (allocate_stack)
        *next_handle = PA_VMO_STACK;

    // Figure out how big an initial thread to allocate.
    char stack_vmo_name[ZX_MAX_NAME_LEN];
    size_t stack_size;
    if (sent_loader_message && !lp->set_stack_size) {
        // The initial stack will be used just for startup work and to
        // contain the bootstrap message.  Make it only as big as needed:
        // the message itself and its array of handles, plus some slop.
        stack_size = size + (lp->handle_count * sizeof(zx_handle_t));

        // This constant is defined by the C library in <limits.h>.  It's
        // tuned to be enough to cover the dynamic linker and C library
        // startup code's stack usage (up until the point it switches to
        // its own stack in __libc_start_main), but leave a little space so
        // for small bootstrap message sizes the stack needs only one page.
        stack_size += PTHREAD_STACK_MIN;
        stack_size = (stack_size + PAGE_SIZE - 1) & -PAGE_SIZE;

        snprintf(stack_vmo_name, sizeof(stack_vmo_name),
                 "stack: msg of %#zx", size);
    } else {
        // Use the requested or default size.
        stack_size =
            lp->set_stack_size ? lp->stack_size : ZIRCON_DEFAULT_STACK_SIZE;
        snprintf(stack_vmo_name, sizeof(stack_vmo_name), "stack: %s %#zx",
                 lp->set_stack_size ? "explicit" : "default", stack_size);

        // Assume the process will read the bootstrap message onto its
        // initial thread's stack.  If it would need more than half its
        // stack just to read the message, consider that an unreasonably
        // large size for the message (presumably arguments and
        // environment strings that are unreasonably large).
        if (stack_size > 0 && size > stack_size / 2) {
            lp_error(lp, ZX_ERR_BUFFER_TOO_SMALL,
                     "procargs message is too large");
            goto cleanup;
        }
    }

    zx_vaddr_t sp = 0;
    if (stack_size > 0) {
        // Allocate the initial thread's stack.
        zx_handle_t stack_vmo;
        zx_status_t status = zx_vmo_create(stack_size, 0, &stack_vmo);
        if (status != ZX_OK) {
            lp_error(lp, status, "cannot create stack vmo");
            goto cleanup;
        }
        zx_object_set_property(stack_vmo, ZX_PROP_NAME,
                               stack_vmo_name, strlen(stack_vmo_name));
        zx_vaddr_t stack_base;
        status = zx_vmar_map(lp_vmar(lp),
                              ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                              0, stack_vmo, 0, stack_size, &stack_base);
        if (status == ZX_OK) {
            ZX_DEBUG_ASSERT(stack_size % PAGE_SIZE == 0);
            sp = compute_initial_stack_pointer(stack_base, stack_size);
            // Pass the stack VMO to the process.  Our protocol with the
            // new process is that we warrant that this is the VMO from
            // which the initial stack is mapped and that we've exactly
            // mapped the entire thing, so vm_object_get_size on this in
            // concert with the initial SP value tells it the exact bounds
            // of its stack.
            //
            // Note this expands the handle list after we've already
            // built the bootstrap message.  We shoved an extra info
            // slot with PA_VMO_STACK into the message, so now this new
            // final handle will correspond to that slot.
            status = launchpad_add_handle(lp, stack_vmo, PA_VMO_STACK);
        }
        if (status != ZX_OK) {
            zx_handle_close(stack_vmo);
            lp_error(lp, status, "cannot map stack vmo");
            goto cleanup;
        }
    }

    if (lp->reserve_vmar != ZX_HANDLE_INVALID) {
        // We're done doing mappings, so clear out the reservation VMAR.
        status = zx_vmar_destroy(lp->reserve_vmar);
        if (status != ZX_OK) {
            lp_error(lp, status, "\
zx_vmar_destroy failed on low address space reservation VMAR");
            goto cleanup;
        }
        status = zx_handle_close(lp->reserve_vmar);
        if (status != ZX_OK) {
            lp_error(lp, status, "\
zx_handle_close failed on low address space reservation VMAR");
            goto cleanup;
        }
        lp->reserve_vmar = ZX_HANDLE_INVALID;
    }

    // The process handle in lp->handles[0] will be consumed by message_write.
    // So we'll need a duplicate to do process operations later.
    status = zx_handle_duplicate(lp_proc(lp), ZX_RIGHT_SAME_RIGHTS, &process);
    if (status != ZX_OK) {
        lp_error(lp, status, "cannot duplicate process handle");
        goto cleanup;
    }

    // The root_vmar handle in lp->handles[0] will be consumed by message_write.
    // So we'll need a duplicate to do process operations later.
    status = zx_handle_duplicate(lp_vmar(lp), ZX_RIGHT_SAME_RIGHTS, &root_vmar);
    if (status != ZX_OK) {
        lp_error(lp, status, "cannot duplicate root vmar handle");
        goto cleanup;
    }

    status = zx_channel_write(to_child, 0, msg, size, lp->handles, lp->handle_count);

    // message_write consumed all the handles.
    for (size_t i = 0; i < lp->handle_count; ++i)
        lp->handles[i] = ZX_HANDLE_INVALID;
    lp->handle_count = 0;

    if (status != ZX_OK) {
        lp_error(lp, status, "failed to write procargs message");
        goto cleanup;
    }

    zx_handle_close(to_child);
    free(msg);

    result->process = process;
    result->root_vmar = root_vmar;
    result->thread = thread;
    result->entry = lp->entry;
    result->stack = sp;
    result->bootstrap = bootstrap;
    result->vdso_base = lp->vdso_base;
    result->base = lp->base;
    return ZX_OK;

cleanup:
    if (to_child != ZX_HANDLE_INVALID)
       zx_handle_close(to_child);
    if (bootstrap != ZX_HANDLE_INVALID)
       zx_handle_close(bootstrap);
    if (process != ZX_HANDLE_INVALID)
       zx_handle_close(process);
    if (root_vmar != ZX_HANDLE_INVALID)
       zx_handle_close(root_vmar);
    if (thread != ZX_HANDLE_INVALID)
       zx_handle_close(thread);
    free(msg);
    return lp->error;
}

// Start the process running.  If the send_loader_message flag is
// set and this succeeds in sending the initial bootstrap message,
// it clears the loader-service handle.  If this succeeds in sending
// the main bootstrap message, it clears the list of handles to
// transfer (after they've been transferred) as well as the process
// handle.
//
// Returns the process handle via |process_out| on success, giving
// ownership to the caller.  On failure, the return value doesn't
// distinguish failure to send the first or second message from
// failure to start the process, so on failure the loader-service
// handle might or might not have been cleared and the handles to
// transfer might or might not have been cleared.
static zx_status_t launchpad_start(launchpad_t* lp, zx_handle_t* process_out) {
    if (lp->error)
        return lp->error;

    launchpad_start_data_t data;
    zx_status_t status = prepare_start(lp, &data);
    if (status != ZX_OK)
        return status;

    status = zx_process_start(data.process, data.thread, data.entry, data.stack,
                              data.bootstrap, data.vdso_base);

    zx_handle_close(data.thread);
    zx_handle_close(data.root_vmar);

    if (status != ZX_OK) {
        zx_handle_close(data.process);
        return lp_error(lp, status, "zx_process_start() failed");
    }

    *process_out = data.process;
    return ZX_OK;
}

zx_status_t launchpad_go(launchpad_t* lp, zx_handle_t* proc, const char** errmsg) {
    zx_handle_t h = ZX_HANDLE_INVALID;
    zx_status_t status = launchpad_start(lp, &h);
    if (errmsg)
        *errmsg = lp->errmsg;
    if (status == ZX_OK) {
        if (proc) {
            *proc = h;
        } else {
            zx_handle_close(h);
        }
    }
    launchpad_destroy(lp);
    return status;
}

zx_status_t launchpad_ready_set(launchpad_t* lp,
                                launchpad_start_data_t* data,
                                const char** errmsg) {
    zx_status_t status = prepare_start(lp, data);
    if (errmsg)
        *errmsg = lp->errmsg;
    launchpad_destroy(lp);
    return status;
}

static zx_status_t launchpad_file_load_with_vdso(launchpad_t* lp, zx_handle_t vmo) {
    launchpad_file_load(lp, vmo);
    launchpad_load_vdso(lp, ZX_HANDLE_INVALID);
    return launchpad_add_vdso_vmo(lp);
}

zx_status_t launchpad_load_from_file(launchpad_t* lp, const char* path) {
    zx_handle_t vmo;
    zx_status_t status = launchpad_vmo_from_file(path, &vmo);
    if (status == ZX_OK) {
        return launchpad_file_load_with_vdso(lp, vmo);
    } else {
        return lp_error(lp, status, "launchpad_vmo_from_file failure");
    }
}

zx_status_t launchpad_load_from_vmo(launchpad_t* lp, zx_handle_t vmo) {
    return launchpad_file_load_with_vdso(lp, vmo);
}
