/*
 * Copyright (C) 2021 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#define START "__dlwrap__start"

#include "crt_arch.h"

#include <elf.h>
#include <link.h>
#include "reloc.h"

#define AUX_CNT 32

#include "ldso_trampoline_phdr.h"

// The location of the embedded linker in the executable.
// Hidden visibility is used to get a pc-relative reference instead
// of a GOT reference, which isn't available when this code runs.
__attribute__((visibility("hidden"))) extern const char __dlwrap_linker;
__attribute__((visibility("hidden"))) extern const char __dlwrap_linker_end;

// The real entry point of the binary to use after linker bootstrapping.
extern "C" void _start();

// Allocate some R/W memory to store a copy of the program headers.
static ElfW(Phdr) phdr_copy[64];

static size_t get_auxv(size_t* auxv, size_t entry) {
  for (size_t i = 0; auxv[i]; i += 2)
    if (auxv[i] == entry) return auxv[i + 1];
  return 0;
}

static void set_auxv(size_t* auxv, size_t entry, size_t value) {
  for (size_t i = 0; auxv[i]; i += 2) {
    if (auxv[i] == entry) {
      auxv[i + 1] = value;
      return;
    }
  }
  __builtin_trap();
}

/*
 * This is the entry point for the linker wrapper, which finds
 * the real linker, then bootstraps into it.
 */
extern "C" void __dlwrap__start_c(size_t* sp) {
  size_t i, aux[AUX_CNT];

  int argc = *sp;
  char** argv = reinterpret_cast<char**>(sp + 1);

  for (i = argc + 1; argv[i]; i++)
    ;
  size_t* auxv = reinterpret_cast<size_t*>(argv + i + 1);

  for (i = 0; i < AUX_CNT; i++) aux[i] = 0;
  for (i = 0; auxv[i]; i += 2)
    if (auxv[i] < AUX_CNT) aux[auxv[i]] = auxv[i + 1];

  ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(get_auxv(auxv, AT_PHDR));
  size_t phdr_count = get_auxv(auxv, AT_PHNUM);
  ElfW(Addr) load_bias = get_elf_load_bias_from_phdr(phdr, phdr_count);

  ElfW(Addr) linker_addr = reinterpret_cast<ElfW(Addr)>(&__dlwrap_linker);
  ElfW(Addr) linker_size = static_cast<ElfW(Addr)>(&__dlwrap_linker_end - &__dlwrap_linker);
  ElfW(Addr) linker_vaddr = linker_addr - load_bias;
  ElfW(Addr) linker_entry_offset = reinterpret_cast<ElfW(Ehdr)*>(linker_addr)->e_entry;

  // Make a copy of the ELF program headers that does not contain the load
  // segments for the embedded linker.  The embedded linker contains its
  // own copy of its load segments, which causes problems if musl uses
  // both sets of load segments when donating unused space to the heap.
  if (phdr_count > sizeof(phdr_copy) / sizeof(phdr_copy[0])) __builtin_trap();
  copy_phdr(phdr, phdr_copy, phdr_count, load_bias);
  phdr_trim_embedded_linker(phdr_copy, phdr_count, linker_vaddr, linker_vaddr + linker_size);

  // Set AT_BASE to the embedded linker
  set_auxv(auxv, AT_BASE, linker_addr);
  // Set AT_ENTRY to the proper entry point
  set_auxv(auxv, AT_ENTRY, reinterpret_cast<ElfW(Addr)>(&_start));
  // Set AT_PHDR to the copied program headers
  set_auxv(auxv, AT_PHDR, reinterpret_cast<ElfW(Addr)>(&phdr_copy));

  // Jump to linker entry point
  CRTJMP(linker_addr + linker_entry_offset, sp);
}
