/*
 * Copyright (C) 2015 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 <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>

#include <string>
#include <vector>

#include <platform/bionic/macros.h>

#include "Config.h"
#include "debug_log.h"

// Config constants
static constexpr uint8_t DEFAULT_FILL_ALLOC_VALUE = 0xeb;
static constexpr uint8_t DEFAULT_FILL_FREE_VALUE = 0xef;

static constexpr uint8_t DEFAULT_FRONT_GUARD_VALUE = 0xaa;
static constexpr uint8_t DEFAULT_REAR_GUARD_VALUE = 0xbb;

// Used as the default for all guard values.
static constexpr size_t DEFAULT_GUARD_BYTES = 32;
static constexpr size_t MAX_GUARD_BYTES = 16384;

static constexpr size_t DEFAULT_BACKTRACE_FRAMES = 16;
static constexpr size_t MAX_BACKTRACE_FRAMES = 256;
static constexpr const char DEFAULT_BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap";

static constexpr size_t DEFAULT_EXPAND_BYTES = 16;
static constexpr size_t MAX_EXPAND_BYTES = 16384;

static constexpr size_t DEFAULT_FREE_TRACK_ALLOCATIONS = 100;
static constexpr size_t MAX_FREE_TRACK_ALLOCATIONS = 16384;

static constexpr size_t DEFAULT_RECORD_ALLOCS = 8000000;
static constexpr size_t MAX_RECORD_ALLOCS = 50000000;
static constexpr const char DEFAULT_RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt";

const std::unordered_map<std::string, Config::OptionInfo> Config::kOptions = {
    {
        "guard",
        {FRONT_GUARD | REAR_GUARD | TRACK_ALLOCS, &Config::SetGuard},
    },
    {
        "front_guard",
        {FRONT_GUARD | TRACK_ALLOCS, &Config::SetFrontGuard},
    },
    {
        "rear_guard",
        {REAR_GUARD | TRACK_ALLOCS, &Config::SetRearGuard},
    },

    {
        "backtrace_size",
        {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceSize},
    },
    {
        "bt_sz",
        {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceSize},
    },
    {
        "backtrace_min_size",
        {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceMinSize},
    },
    {
        "bt_min_sz",
        {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceMinSize},
    },
    {
        "backtrace_max_size",
        {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceMaxSize},
    },
    {
        "bt_max_sz",
        {BACKTRACE_SPECIFIC_SIZES, &Config::SetBacktraceMaxSize},
    },
    {
        "backtrace",
        {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktrace},
    },
    {
        "bt",
        {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktrace},
    },
    {
        "backtrace_enable_on_signal",
        {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktraceEnableOnSignal},
    },
    {
        "bt_en_on_sig",
        {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktraceEnableOnSignal},
    },
    {
        "backtrace_dump_on_exit",
        {0, &Config::SetBacktraceDumpOnExit},
    },
    {
        "bt_dmp_on_ex",
        {0, &Config::SetBacktraceDumpOnExit},
    },
    {
        "backtrace_dump_prefix",
        {0, &Config::SetBacktraceDumpPrefix},
    },
    {
        "bt_dmp_pre",
        {0, &Config::SetBacktraceDumpPrefix},
    },
    {
        "backtrace_full",
        {BACKTRACE_FULL, &Config::VerifyValueEmpty},
    },
    {
        "bt_full",
        {BACKTRACE_FULL, &Config::VerifyValueEmpty},
    },

    {
        "fill",
        {FILL_ON_ALLOC | FILL_ON_FREE, &Config::SetFill},
    },
    {
        "fill_on_alloc",
        {FILL_ON_ALLOC, &Config::SetFillOnAlloc},
    },
    {
        "fill_on_free",
        {FILL_ON_FREE, &Config::SetFillOnFree},
    },

    {
        "expand_alloc",
        {EXPAND_ALLOC, &Config::SetExpandAlloc},
    },

    {
        "free_track",
        {FREE_TRACK | FILL_ON_FREE | TRACK_ALLOCS, &Config::SetFreeTrack},
    },
    {
        "free_track_backtrace_num_frames",
        {0, &Config::SetFreeTrackBacktraceNumFrames},
    },

    {
        "leak_track",
        {LEAK_TRACK | TRACK_ALLOCS, &Config::VerifyValueEmpty},
    },

    {
        "record_allocs",
        {RECORD_ALLOCS, &Config::SetRecordAllocs},
    },
    {
        "record_allocs_file",
        {0, &Config::SetRecordAllocsFile},
    },
    {
        "record_allocs_on_exit",
        {0, &Config::SetRecordAllocsOnExit},
    },

    {
        "verify_pointers",
        {TRACK_ALLOCS, &Config::VerifyValueEmpty},
    },
    {
        "abort_on_error",
        {ABORT_ON_ERROR, &Config::VerifyValueEmpty},
    },
    {
        "verbose",
        {VERBOSE, &Config::VerifyValueEmpty},
    },
    {
        "check_unreachable_on_signal",
        {CHECK_UNREACHABLE_ON_SIGNAL, &Config::VerifyValueEmpty},
    },
    {
        "log_allocator_stats_on_signal",
        {LOG_ALLOCATOR_STATS_ON_SIGNAL, &Config::VerifyValueEmpty},
    },
    {
        "log_allocator_stats_on_exit",
        {LOG_ALLOCATOR_STATS_ON_EXIT, &Config::VerifyValueEmpty},
    },
};

bool Config::ParseValue(const std::string& option, const std::string& value, size_t min_value,
                        size_t max_value, size_t* parsed_value) const {
  assert(!value.empty());

  // Parse the value into a size_t value.
  errno = 0;
  char* end;
  long long_value = strtol(value.c_str(), &end, 10);
  if (errno != 0) {
    error_log("%s: bad value for option '%s': %s", getprogname(), option.c_str(), strerror(errno));
    return false;
  }
  if (end == value.c_str()) {
    error_log("%s: bad value for option '%s'", getprogname(), option.c_str());
    return false;
  }
  if (static_cast<size_t>(end - value.c_str()) != value.size()) {
    error_log("%s: bad value for option '%s', non space found after option: %s", getprogname(),
              option.c_str(), end);
    return false;
  }
  if (long_value < 0) {
    error_log("%s: bad value for option '%s', value cannot be negative: %ld", getprogname(),
              option.c_str(), long_value);
    return false;
  }

  if (static_cast<size_t>(long_value) < min_value) {
    error_log("%s: bad value for option '%s', value must be >= %zu: %ld", getprogname(),
              option.c_str(), min_value, long_value);
    return false;
  }
  if (static_cast<size_t>(long_value) > max_value) {
    error_log("%s: bad value for option '%s', value must be <= %zu: %ld", getprogname(),
              option.c_str(), max_value, long_value);
    return false;
  }
  *parsed_value = static_cast<size_t>(long_value);
  return true;
}

bool Config::ParseValue(const std::string& option, const std::string& value, size_t default_value,
                        size_t min_value, size_t max_value, size_t* new_value) const {
  if (value.empty()) {
    *new_value = default_value;
    return true;
  }
  return ParseValue(option, value, min_value, max_value, new_value);
}

bool Config::SetGuard(const std::string& option, const std::string& value) {
  if (value.empty()) {
    // Set the defaults.
    front_guard_bytes_ = DEFAULT_GUARD_BYTES;
    rear_guard_bytes_ = DEFAULT_GUARD_BYTES;
    return true;
  }

  if (!ParseValue(option, value, 1, MAX_GUARD_BYTES, &rear_guard_bytes_)) {
    return false;
  }

  // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
  // make sure that the header is aligned properly.
  front_guard_bytes_ = __BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
  return true;
}

bool Config::SetFrontGuard(const std::string& option, const std::string& value) {
  if (!ParseValue(option, value, DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, &front_guard_bytes_)) {
    return false;
  }
  // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
  // make sure that the header is aligned properly.
  front_guard_bytes_ = __BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
  return true;
}

bool Config::SetRearGuard(const std::string& option, const std::string& value) {
  return ParseValue(option, value, DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, &rear_guard_bytes_);
}

bool Config::SetFill(const std::string& option, const std::string& value) {
  if (value.empty()) {
    // Set the defaults.
    fill_on_alloc_bytes_ = SIZE_MAX;
    fill_on_free_bytes_ = SIZE_MAX;
    return true;
  }

  if (!ParseValue(option, value, 1, SIZE_MAX, &fill_on_alloc_bytes_)) {
    return false;
  }
  fill_on_free_bytes_ = fill_on_alloc_bytes_;
  return true;
}

bool Config::SetFillOnAlloc(const std::string& option, const std::string& value) {
  return ParseValue(option, value, SIZE_MAX, 1, SIZE_MAX, &fill_on_alloc_bytes_);
}

bool Config::SetFillOnFree(const std::string& option, const std::string& value) {
  return ParseValue(option, value, SIZE_MAX, 1, SIZE_MAX, &fill_on_free_bytes_);
}

bool Config::SetBacktrace(const std::string& option, const std::string& value) {
  backtrace_enabled_ = true;
  return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES,
                    &backtrace_frames_);
}

bool Config::SetBacktraceEnableOnSignal(const std::string& option, const std::string& value) {
  backtrace_enable_on_signal_ = true;
  return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES,
                    &backtrace_frames_);
}

bool Config::SetBacktraceDumpOnExit(const std::string& option, const std::string& value) {
  if (Config::VerifyValueEmpty(option, value)) {
    backtrace_dump_on_exit_ = true;
    return true;
  }
  return false;
}

bool Config::SetBacktraceDumpPrefix(const std::string&, const std::string& value) {
  if (value.empty()) {
    backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX;
  } else {
    backtrace_dump_prefix_ = value;
  }
  return true;
}

bool Config::SetBacktraceSize(const std::string& option, const std::string& value) {
  if (!ParseValue(option, value, 1, SIZE_MAX, &backtrace_min_size_bytes_)) {
    return false;
  }
  backtrace_max_size_bytes_ = backtrace_min_size_bytes_;

  return true;
}

bool Config::SetBacktraceMinSize(const std::string& option, const std::string& value) {
  return ParseValue(option, value, 1, SIZE_MAX, &backtrace_min_size_bytes_);
}

bool Config::SetBacktraceMaxSize(const std::string& option, const std::string& value) {
  return ParseValue(option, value, 1, SIZE_MAX, &backtrace_max_size_bytes_);
}

bool Config::SetExpandAlloc(const std::string& option, const std::string& value) {
  return ParseValue(option, value, DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, &expand_alloc_bytes_);
}

bool Config::SetFreeTrack(const std::string& option, const std::string& value) {
  // This option enables fill on free, so set the bytes to the default value.
  if (fill_on_free_bytes_ == 0) {
    fill_on_free_bytes_ = SIZE_MAX;
  }
  if (free_track_backtrace_num_frames_ == 0) {
    free_track_backtrace_num_frames_ = DEFAULT_BACKTRACE_FRAMES;
  }

  return ParseValue(option, value, DEFAULT_FREE_TRACK_ALLOCATIONS, 1, MAX_FREE_TRACK_ALLOCATIONS,
                    &free_track_allocations_);
}

bool Config::SetFreeTrackBacktraceNumFrames(const std::string& option, const std::string& value) {
  return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 0, MAX_BACKTRACE_FRAMES,
                    &free_track_backtrace_num_frames_);
}

bool Config::SetRecordAllocs(const std::string& option, const std::string& value) {
  if (record_allocs_file_.empty()) {
    record_allocs_file_ = DEFAULT_RECORD_ALLOCS_FILE;
  }
  return ParseValue(option, value, DEFAULT_RECORD_ALLOCS, 1, MAX_RECORD_ALLOCS,
                    &record_allocs_num_entries_);
}

bool Config::SetRecordAllocsFile(const std::string&, const std::string& value) {
  if (value.empty()) {
    // Set the default.
    record_allocs_file_ = DEFAULT_RECORD_ALLOCS_FILE;
    return true;
  }
  record_allocs_file_ = value;
  return true;
}

bool Config::SetRecordAllocsOnExit(const std::string& option, const std::string& value) {
  if (Config::VerifyValueEmpty(option, value)) {
    record_allocs_on_exit_ = true;
    return true;
  }
  return false;
}

bool Config::VerifyValueEmpty(const std::string& option, const std::string& value) {
  if (!value.empty()) {
    // This is not valid.
    error_log("%s: value set for option '%s' which does not take a value", getprogname(),
              option.c_str());
    return false;
  }
  return true;
}

void Config::LogUsage() const {
  error_log("For malloc debug option descriptions go to:");
  error_log(
      "  https://android.googlesource.com/platform/bionic/+/main/libc/malloc_debug/README.md");
}

bool Config::GetOption(const char** options_str, std::string* option, std::string* value) {
  const char* cur = *options_str;
  // Process each property name we can find.
  while (isspace(*cur)) ++cur;

  if (*cur == '\0') {
    *options_str = cur;
    return false;
  }

  const char* start = cur;
  while (!isspace(*cur) && *cur != '=' && *cur != '\0') ++cur;

  *option = std::string(start, cur - start);

  // Skip any spaces after the name.
  while (isspace(*cur)) ++cur;

  value->clear();
  if (*cur == '=') {
    ++cur;
    // Skip the space after the equal.
    while (isspace(*cur)) ++cur;

    start = cur;
    while (!isspace(*cur) && *cur != '\0') ++cur;

    if (cur != start) {
      *value = std::string(start, cur - start);
    }
  }
  *options_str = cur;
  return true;
}

bool Config::Init(const char* options_str) {
  // Initialize a few default values.
  fill_alloc_value_ = DEFAULT_FILL_ALLOC_VALUE;
  fill_free_value_ = DEFAULT_FILL_FREE_VALUE;
  front_guard_value_ = DEFAULT_FRONT_GUARD_VALUE;
  rear_guard_value_ = DEFAULT_REAR_GUARD_VALUE;
  backtrace_signal_ = SIGRTMAX - 19;
  backtrace_dump_signal_ = SIGRTMAX - 17;
  record_allocs_signal_ = SIGRTMAX - 18;
  free_track_backtrace_num_frames_ = 0;
  record_allocs_file_.clear();
  fill_on_free_bytes_ = 0;
  backtrace_enable_on_signal_ = false;
  backtrace_enabled_ = false;
  backtrace_dump_on_exit_ = false;
  backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX;
  backtrace_min_size_bytes_ = 0;
  backtrace_max_size_bytes_ = SIZE_MAX;
  check_unreachable_signal_ = SIGRTMAX - 16;
  log_allocator_stats_signal_ = SIGRTMAX - 15;

  // Process each option name we can find.
  std::string option;
  std::string value;
  bool valid = true;
  while (GetOption(&options_str, &option, &value)) {
    auto entry = kOptions.find(option);
    if (entry == kOptions.end()) {
      error_log("%s: unknown option %s", getprogname(), option.c_str());
      valid = false;
      break;
    }

    const OptionInfo* info = &entry->second;
    auto process_func = info->process_func;
    if (process_func != nullptr && !(this->*process_func)(option, value)) {
      valid = false;
      break;
    }
    options_ |= info->option;
  }

  if (!valid || *options_str != '\0') {
    LogUsage();
    return false;
  }

  return true;
}
