// 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);
  if (lp->handle_count != 0) {
    // If we have already free the handles, don't free them again.
    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");
  }
}
