// Copyright 2014 The Chromium 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 "crazy_linker_system.h"

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#ifdef __ANDROID__
#include <android/log.h>
#endif

#include "crazy_linker_util.h"

// Note: unit-testing support files are in crazy_linker_files_mock.cpp

namespace crazy {

String MakeDirectoryPath(const char* parent) {
  return MakeDirectoryPath(parent, ::strlen(parent));
}

String MakeDirectoryPath(const char* parent, size_t parent_len) {
  if (parent_len == 0) {
    // Special case for empty inputs.
    return String("./");
  }
  String result(parent);
  if (parent_len > 0 && parent[parent_len - 1] != '/') {
    result += '/';
  }
  return result;
}

String MakeAbsolutePathFrom(const char* path) {
  return MakeAbsolutePathFrom(path, ::strlen(path));
}

String MakeAbsolutePathFrom(const char* path, size_t path_len) {
  if (path[0] == '/') {
    return String(path, path_len);
  } else {
    String cur_dir = GetCurrentDirectory();
    String result = MakeDirectoryPath(cur_dir.c_str(), cur_dir.size());
    result.Append(path, path_len);
    return result;
  }
}

bool IsSystemLibraryPath(const char* lib_path) {
  static const char* kSystemPrefixes[] = {
#ifdef __ANDROID__
      // From recent Android linker sources ($AOSP/bionic/linker/linker.cpp).
      "/system/lib64/", "/odm/lib64/", "/vendor/lib64/",
      "/data/asan/system/lib64/", "/data/asan/odm/lib64/",
      "/data/asan/vendor/lib64/",
      // It's ok to mix 32-bit and 64-bit paths in the same list here.
      "/system/lib/", "/odm/lib/", "/vendor/lib/", "/data/asan/system/lib/",
      "/data/asan/odm/lib/", "/data/asan/vendor/lib/",
#else
      // Typical system library directories for Linux systems.
      "/lib/",       "/lib32/",      "/lib64/",
      "/libx32/",    "/usr/lib/",    "/usr/lib32/",
      "/usr/lib64/", "/usr/libx32/", "/usr/local/lib/",
#endif
  };
  size_t lib_path_len = ::strlen(lib_path);
  for (const char* prefix : kSystemPrefixes) {
    size_t prefix_len = ::strlen(prefix);
    if (prefix_len < lib_path_len && !::memcmp(prefix, lib_path, prefix_len))
      return true;
  }
  return false;
}

}  // namespace crazy

#ifndef UNIT_TEST

namespace crazy {

ssize_t FileDescriptor::Read(void* buffer, size_t buffer_size) {
  return TEMP_FAILURE_RETRY(::read(fd_, buffer, buffer_size));
}

off_t FileDescriptor::SeekTo(off_t offset) {
  return ::lseek(fd_, offset, SEEK_SET);
}

void* FileDescriptor::Map(void* address,
                          size_t length,
                          int prot,
                          int flags,
                          off_t offset) {
  void* mem = ::mmap(address, length, prot, flags, fd_, offset);
  return (mem == MAP_FAILED) ? nullptr : mem;
}

int64_t FileDescriptor::GetFileSize() const {
  struct stat stat_buf;
  if (fstat(fd_, &stat_buf) == -1) {
    return -1;
  }
  // |st_size| is an off_t which is always signed, but can be 32-bit or
  // 64-bit depending on the platform. Always convert to a signed 64-bit
  // to ensure the client always deal properly with both cases.
  return static_cast<int64_t>(stat_buf.st_size);
}

// static
int FileDescriptor::DoOpenReadOnly(const char* path) {
  return TEMP_FAILURE_RETRY(::open(path, O_RDONLY));
}

// static
int FileDescriptor::DoOpenReadWrite(const char* path) {
  return TEMP_FAILURE_RETRY(::open(path, O_RDWR));
}

// static
void FileDescriptor::DoClose(int fd) {
  int old_errno = errno;
  // SUBTLE: Do not loop when close() returns EINTR. On Linux, this simply
  // means that a corresponding flush operation failed, but the file
  // descriptor will always be closed anyway.
  //
  // Other platforms have different behavior: e.g. on OS X, this could be
  // the result of an interrupt, and there is no reliable way to know
  // whether the fd was closed or not on exit :-(
  (void)close(fd);
  errno = old_errno;
}

const char* GetEnv(const char* var_name) { return ::getenv(var_name); }

String GetCurrentDirectory() {
  String result;
  size_t capacity = 128;
  for (;;) {
    result.Resize(capacity);
    if (getcwd(&result[0], capacity))
      break;
    capacity *= 2;
  }
  return result;
}

bool PathExists(const char* path) {
  struct stat st;
  if (TEMP_FAILURE_RETRY(stat(path, &st)) < 0)
    return false;

  return S_ISREG(st.st_mode) || S_ISDIR(st.st_mode);
}

bool PathIsFile(const char* path) {
  struct stat st;
  if (TEMP_FAILURE_RETRY(stat(path, &st)) < 0)
    return false;

  return S_ISREG(st.st_mode);
}

}  // namespace crazy

#if !defined(CRAZY_LINKER_ENABLE_FUZZING)

// Custom implementation of new and malloc, this prevents dragging
// the libc++ implementation, which drags exception-related machine
// code that is not needed here. This helps reduce the size of the
// final binary considerably.

// IMPORTANT: These symbols are not exported by the crazy linker, thus this
//            does not affect the libraries that it will load, only the
//            linker binary itself!
//
void* operator new(size_t size) {
  void* ptr = ::malloc(size);
  if (ptr != nullptr)
    return ptr;

  // Don't assume it is possible to call any C library function like
  // snprintf() here, since it might allocate heap memory and crash at
  // runtime. Hence our fatal message does not contain the number of
  // bytes requested by the allocation.
  static const char kFatalMessage[] = "Out of memory!";
#ifdef __ANDROID__
  __android_log_write(ANDROID_LOG_FATAL, "crazy_linker", kFatalMessage);
#else
  ::write(STDERR_FILENO, kFatalMessage, sizeof(kFatalMessage) - 1);
#endif
  _exit(1);
#if defined(__GNUC__)
  __builtin_unreachable();
#endif

  // NOTE: Adding a 'return nullptr' here will make the compiler error
  // with a message stating that 'operator new(size_t)' is not allowed
  // to return nullptr.
  //
  // Indeed, an new expression like 'new T' shall never return nullptr,
  // according to the C++ specification, and an optimizing compiler will gladly
  // remove any null-checks after them (something the Fuschsia team had to
  // learn the hard way when writing their kernel in C++). What is meant here
  // is something like:
  //
  //   Foo* foo = new Foo(10);
  //   if (!foo) {                             <-- entire check and branch
  //      ... Handle out-of-memory condition.  <-- removed by an optimizing
  //   }                                       <-- compiler.
  //
  // Note that some C++ library implementations (e.g. recent libc++) recognize
  // when they are compiled with -fno-exceptions and provide a simpler version
  // of operator new that can return nullptr. However, it is very hard to
  // guarantee at build time that this code is linked against such a version
  // of the runtime. Moreoever, technically disabling exceptions is completely
  // out-of-spec regarding the C++ language, and what the compiler is allowed
  // to do in this case is mostly implementation-defined, so better be safe
  // than sorry here.
  //
  // C++ provides a non-throwing new expression that can return a nullptr
  // value, but it must be written as 'new (std::nothrow) T' instead of
  // 'new T', and thus nobody uses this. This ends up calling
  // 'operator new(size_t, const std::nothrow_t&)' which is not implemented
  // here.
}

void* operator new[](size_t size) {
  return operator new(size);
}

void operator delete(void* ptr) {
  // The compiler-generated code already checked that |ptr != nullptr|
  // so don't to it a second time.
  ::free(ptr);
}

void operator delete[](void* ptr) {
  ::free(ptr);
}

#endif  // !CRAZY_LINKER_ENABLE_FUZZING

#endif  // !UNIT_TEST
