/*
 * Copyright (C) 2020 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.
 */

#include <sys/thread_properties.h>

#include <async_safe/CHECK.h>
#include <async_safe/log.h>

#include <elf.h>
#include <pthread.h>
#include <unistd.h>

#include <sys/ptrace.h>
#include <sys/uio.h>
#include <sys/user.h>

#if defined(__i386__)
#include <asm/ldt.h>
#endif

#include "private/ErrnoRestorer.h"
#include "private/bionic_elf_tls.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
#include "pthread_internal.h"

void __libc_get_static_tls_bounds(void** stls_begin, void** stls_end) {
  const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
  *stls_begin = reinterpret_cast<char*>(__get_bionic_tcb()) - layout.offset_bionic_tcb();
  *stls_end = reinterpret_cast<char*>(*stls_begin) + layout.size();
}

void __libc_register_thread_exit_callback(thread_exit_cb_t cb) {
  TlsModules& modules = __libc_shared_globals()->tls_modules;

  if (modules.first_thread_exit_callback == nullptr) {
    modules.first_thread_exit_callback = cb;
    return;
  }

  BionicAllocator& allocator = __libc_shared_globals()->tls_allocator;
  CallbackHolder* new_node =
      reinterpret_cast<CallbackHolder*>(allocator.alloc(sizeof(CallbackHolder)));
  new_node->cb = cb;
  new_node->prev = modules.thread_exit_callback_tail_node;
  modules.thread_exit_callback_tail_node = new_node;
}

static inline __always_inline bionic_tcb* __get_bionic_tcb_for_thread(pid_t tid) {
  // If tid is same as self, then we don't need ptrace.
  if (gettid() == tid) return __get_bionic_tcb();

  // Find the thread-pointer register for the given thread.
  void** tp_reg = nullptr;
#if defined(__aarch64__)
  uint64_t reg;
  struct iovec pt_iov { .iov_base = &reg, .iov_len = sizeof(reg) };
  if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_TLS, &pt_iov) == 0) {
    tp_reg = reinterpret_cast<void**>(reg);
  }
#elif defined(__arm__)
  if (ptrace(PTRACE_GET_THREAD_AREA, tid, nullptr, &tp_reg) != 0) {
    // Reset the tp_reg if ptrace was unsuccessful.
    tp_reg = nullptr;
  }
#elif defined(__i386__)
  struct user_regs_struct regs;
  struct iovec pt_iov = { .iov_base = &regs, .iov_len = sizeof(regs) };
  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
    struct user_desc u_info;
    u_info.entry_number = regs.xgs >> 3;
    if (ptrace(PTRACE_GET_THREAD_AREA, tid, u_info.entry_number, &u_info) == 0) {
      tp_reg = reinterpret_cast<void**>(u_info.base_addr);
    }
  }
#elif defined(__riscv)
  struct user_regs_struct regs;
  struct iovec pt_iov = { .iov_base = &regs, .iov_len = sizeof(regs) };
  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
    tp_reg = reinterpret_cast<void**>(regs.tp);
  }
#elif defined(__x86_64__)
  {
    ErrnoRestorer errno_restorer;
    errno = 0;
    uintptr_t fs_base = ptrace(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr);
    if (errno == 0) {
      tp_reg = reinterpret_cast<void**>(fs_base);
    }
  }
#endif

  if (tp_reg == nullptr) {
    async_safe_write_log(ANDROID_LOG_FATAL, "libc",
                         "__get_bionic_tcb_for_thread failed to read thread register.");
  }

  return reinterpret_cast<bionic_tcb*>(&tp_reg[MIN_TLS_SLOT]);
}

void __libc_iterate_dynamic_tls(pid_t tid,
                                void (*cb)(void* __dynamic_tls_begin, void* __dynamic_tls_end,
                                           size_t __dso_id, void* __arg),
                                void* arg) {
  TlsModules& modules = __libc_shared_globals()->tls_modules;
  bionic_tcb* const tcb = __get_bionic_tcb_for_thread(tid);
  TlsDtv* const dtv = __get_tcb_dtv(tcb);
  BionicAllocator& allocator = __libc_shared_globals()->tls_allocator;

  for (size_t i = modules.static_module_count; i < dtv->count; ++i) {
    void* dtls_begin = dtv->modules[i];
    if (dtls_begin == nullptr) continue;
    void* dtls_end =
        static_cast<void*>(static_cast<char*>(dtls_begin) + allocator.get_chunk_size(dtls_begin));
    size_t dso_id = __tls_module_idx_to_id(i);

    cb(dtls_begin, dtls_end, dso_id, arg);
  }
}

void __libc_register_dynamic_tls_listeners(dtls_listener_t on_creation,
                                           dtls_listener_t on_destruction) {
  TlsModules& tls_modules = __libc_shared_globals()->tls_modules;
  tls_modules.on_creation_cb = on_creation;
  tls_modules.on_destruction_cb = on_destruction;
}
