// Copyright 2022 The Centipede Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Function interceptors for Centipede.
// Interceptors are disabled under ASAN/TSAN/MSAN because those sanitizers
// have their own conflicting interceptors.
// The typical usage of sanitizers with Centipede is via the --extra_binaries
// flag, where the sanitized binary does not produce coverage output and thus
// doesn't need (most of?) interceptors.
#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
    !defined(MEMORY_SANITIZER)
#include <dlfcn.h>  // for dlsym()
#include <pthread.h>

#include <cstdint>
#include <cstring>

#include "./centipede/runner.h"

using centipede::state;
using centipede::tls;

namespace {

// Wrapper for dlsym().
// Returns the pointer to the real function `function_name`.
// In most cases we need FuncAddr("foo") to be called before the first call to
// foo(), which means we either need to do this very early at startup
// (e.g. pre-init array), or on the first call.
// Currently, we do this on the first call via function-scope static.
template <typename FunctionT>
FunctionT FuncAddr(const char *function_name) {
  void *addr = dlsym(RTLD_NEXT, function_name);
  return reinterpret_cast<FunctionT>(addr);
}

// 3rd and 4th arguments to pthread_create(), packed into a struct.
struct ThreadCreateArgs {
  void *(*start_routine)(void *);
  void *arg;
};

// Wrapper for a `start_routine` argument of pthread_create().
// Calls the actual start_routine and returns its results.
// Performs custom actions before and after start_routine().
// `arg` is a `ThreadCreateArgs *` with the actual pthread_create() args.
void *MyThreadStart(void *arg) {
  auto *args = static_cast<ThreadCreateArgs *>(arg);
  tls.OnThreadStart();
  void *retval = args->start_routine(args->arg);
  tls.OnThreadStop();
  delete args;  // allocated in the pthread_create wrapper.
  return retval;
}

}  // namespace

// Initialize memcmp_orig at the module startup. This may still be too late,
// since memcmp may be used before this module is initialized.
// So, the interceptor may not assume that memcmp_orig != nullptr.
static auto memcmp_orig =
    FuncAddr<int (*)(const void *s1, const void *s2, size_t n)>("memcmp");

// TODO(kcc): as we implement more functions like memcmp_fallback and
// length_of_common_prefix, move them into a separate module and unittest.

// Fallback for the case memcmp_orig is null.
// Will be executed several times at process startup, if at all.
static int memcmp_fallback(const void *s1, const void *s2, size_t n) {
  const auto *p1 = static_cast<const uint8_t *>(s1);
  const auto *p2 = static_cast<const uint8_t *>(s2);
  for (size_t i = 0; i < n; ++i) {
    int diff = p1[i] - p2[i];
    if (diff) return diff;
  }
  return 0;
}

// Returns the length of the common prefix of `s1` and `s2`, but not more
// than 63. I.e. the returned value is in [0, 64).
static size_t length_of_common_prefix(const void *s1, const void *s2,
                                      size_t n) {
  const auto *p1 = static_cast<const uint8_t *>(s1);
  const auto *p2 = static_cast<const uint8_t *>(s2);
  static constexpr size_t kMaxLen = 63;
  if (n > kMaxLen) n = kMaxLen;
  for (size_t i = 0; i < n; ++i) {
    if (p1[i] != p2[i]) return i;
  }
  return n;
}

// memcmp interceptor.
// Calls the real memcmp() and possibly modifies state.cmp_feature_set.
extern "C" int memcmp(const void *s1, const void *s2, size_t n) {
  if (state.run_time_flags.use_cmp_features) {
    auto caller_pc = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
    uintptr_t pc_offset = caller_pc - state.main_object.start_address;
    uintptr_t hash =
        centipede::Hash64Bits(pc_offset) ^ tls.path_ring_buffer.hash();
    const size_t lcp = length_of_common_prefix(s1, s2, n);
    hash <<= 6;  // lcp is a 6-bit number.
    state.cmp_feature_set.set(hash | lcp);
  }
  int result =
      memcmp_orig ? memcmp_orig(s1, s2, n) : memcmp_fallback(s1, s2, n);
  if (result != 0 && state.run_time_flags.use_auto_dictionary) {
    tls.cmp_traceN.Capture(n, reinterpret_cast<const uint8_t *>(s1),
                           reinterpret_cast<const uint8_t *>(s2));
  }
  // Normalize the return value to be one of {1, -1, 0}.
  // According to the spec, memcmp can return any positive or negative value,
  // and in fact it does return various different positive and negative values
  // depending on <some random factors>. These values are later passed to our
  // CMP instrumentation and are used to produce features.
  // If we don't normalize the return value here, our tests may be flaky.
  if (result < 0) return -1;
  if (result > 0) return 1;
  return result;
}

// pthread_create interceptor.
// Calls real pthread_create, but wraps the start_routine() in MyThreadStart.
extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                              void *(*start_routine)(void *), void *arg) {
  static auto pthread_create_orig =
      FuncAddr<int (*)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
                       void *)>("pthread_create");
  // Wrap the arguments. Will be deleted in MyThreadStart.
  auto *wrapped_args = new ThreadCreateArgs{start_routine, arg};
  // Run the actual pthread_create.
  return pthread_create_orig(thread, attr, MyThreadStart, wrapped_args);
}
#endif  // not ASAN/TSAN/MSAN
