// 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 <assert.h>
#include <lib/elf-psabi/sp.h>
#include <lib/fdio/io.h>
#include <lib/fidl/txn_header.h>
#include <lib/zircon-internal/default_stack_size.h>
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <threads.h>
#include <zircon/assert.h>
#include <zircon/dlfcn.h>
#include <zircon/errors.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <launchpad/launchpad.h>
#include <launchpad/vmo.h>
#include <ldmsg/ldmsg.h>

#include "elf.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;

  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,
};

// Returned by extract_ld_envvars to indicate the number of environment variables, and the total
// length of envp.
struct envvars_size {
  size_t count;
  size_t length;
};

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;
}

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

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

__EXPORT
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])

__EXPORT
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->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.
__EXPORT
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 != ZX_OK) {
    lp->error = ZX_OK;
    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;
}

__EXPORT
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);
}

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

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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);
}

__EXPORT
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;
}

__EXPORT
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, uint64_t ordinal, const void* data,
                                  size_t len, zx_handle_t* out) {
  static _Atomic zx_txid_t next_txid;

  ldmsg_req_t req;
  fidl_init_txn_header(&req.header, atomic_fetch_add(&next_txid, 1), ordinal);

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

  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;

  // Don't send null terminator in LoadObject call; FIDL strings are not null-terminated.
  if (interp[interp_len] != '\0') {
    return ZX_ERR_INVALID_ARGS;
  }
  interp_len--;

  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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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));
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
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;
}

// Returns the number of envvars extracted.
//
static struct envvars_size extract_ld_envvars(uint8_t* buffer, launchpad_t* lp) {
  // The only variables the loader cares about are these two.
#define LD_DEBUG "LD_DEBUG="
#define LD_TRACE "LD_TRACE="

  size_t count = 0;
  size_t length = 0;
  const char* current_envvar = lp->env;
  for (size_t i = 0; i < lp->env_len; ++i) {
    size_t len = strlen(current_envvar) + 1;
    if ((!strncmp(LD_DEBUG, current_envvar, strlen(LD_DEBUG))) ||
        (!strncmp(LD_TRACE, current_envvar, strlen(LD_TRACE)))) {
      memcpy(buffer, current_envvar, len);
      buffer += len;
      count += 1;
      length += len;
    }
  }
  return ((struct envvars_size){.count = count, .length = length});
}

// 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.
// |is_loader| is used to determine whether to send a message with limited
// args and envvars, and no names, as the loader does not need them.
//
// 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 is_loader) {
  // Compute a conservative message size. In particular, when |is_loader| is true the message may be
  // considerably smaller as names and most arguments and envvars are discarded.
  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->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);

  // We want to compute an accurate message size. In particular, a loader message is decoded in a
  // constrained environment, and the conservative message size may be far too large when lots of
  // argument or environment data is sent.
  size_t actual_message_size = 0;

  // Include the argument strings so the dynamic linker can use argv[0]
  // in messages it prints, and the environment strings so the dynamic linker can
  // see options like LD_DEBUG or whatnot.
  header->args_off = header->handle_info_off + sizeof(uint32_t) * num_handles;
  if (is_loader) {
    size_t env_off = header->args_off;

    // The loader message only needs argv[0], if present.
    header->args_num = lp->argc ? 1 : 0;
    if (header->args_num > 0) {
      uint8_t* args_start = (uint8_t*)msg + header->args_off;
      size_t len = strlen(lp->args) + 1;
      memcpy(args_start, lp->args, len);
      env_off += len;
    }

    // The loader only needs the values of LD_TRACE and LD_DEBUG.
    struct envvars_size env_info = extract_ld_envvars(msg + env_off, lp);
    if (env_info.count > 0) {
      header->environ_off = env_off;
      header->environ_num = env_info.count;
    }

    // The loader does not need any names, so the actual message size computation stops here.
    actual_message_size = env_off + env_info.length;
  } else {
    header->args_num = lp->argc;
    if (header->args_num > 0) {
      uint8_t* args_start = (uint8_t*)msg + header->args_off;
      memcpy(args_start, lp->args, lp->args_len);
    }

    if (lp->envc > 0) {
      header->environ_off = header->args_off + lp->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 (lp->namec > 0) {
      header->names_off = header->args_off + lp->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);
    }

    // The conservative size is fine for non-loader messages.
    actual_message_size = msg_size;
  }

  *msg_buf = msg;
  *buf_size = actual_message_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, /*is_loader*/ true);
  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;
}

__EXPORT
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,
                    /*is_loader*/ false) != 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_handle_close(stack_vmo);
      lp_error(lp, status, "cannot map stack vmo");
      goto cleanup;
    }

    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) {
      // launchpad_add_handle consumed the handle even in the error case.
      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;
}

__EXPORT
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;
}

__EXPORT
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;
}

__EXPORT
zx_status_t launchpad_load_from_vmo(launchpad_t* lp, zx_handle_t vmo) {
  launchpad_elf_load(lp, vmo);
  launchpad_load_vdso(lp, ZX_HANDLE_INVALID);
  return launchpad_add_vdso_vmo(lp);
}

__EXPORT
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_load_from_vmo(lp, vmo);
  } else {
    return lp_error(lp, status, "launchpad_vmo_from_file failure");
  }
}
