/*
 * 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 <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 <sys/system_properties.h>

#include <private/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 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";

struct Option {
  Option(std::string name, uint64_t option, bool combo_option = false, bool* config = nullptr)
      : name(name), option(option), combo_option(combo_option), config(config) {}
  virtual ~Option() = default;

  std::string name;

  uint64_t option;
  // If set to true, then all of the options following are set on until
  // the combo_option value is set to false.
  bool combo_option = false;
  bool* config;

  virtual bool ParseValue(const std::string& option_name, const std::string& value) const;

  virtual void SetDefault() const { }
};

bool Option::ParseValue(const std::string& option_name, const std::string& raw_value) const {
  if (!raw_value.empty()) {
    error_log("%s: value set for option '%s' which does not take a value",
              getprogname(), option_name.c_str());
    return false;
  }
  return true;
}

struct OptionString : public Option {
  OptionString(std::string name, uint64_t option, std::string default_value,
                std::string* value, bool combo_option = false,
                bool* config = nullptr)
      : Option(name, option, combo_option, config), default_value(default_value), value(value) {}
  virtual ~OptionString() = default;

  std::string default_value;
  std::string* value;

  bool ParseValue(const std::string& option_name, const std::string& value) const override;

  void SetDefault() const override { if (value) *value = default_value; }
};

bool OptionString::ParseValue(const std::string&, const std::string& raw_value) const {
  if (!raw_value.empty()) {
    *value = raw_value;
  }
  return true;
}

struct OptionSizeT : public Option {
  OptionSizeT(std::string name, size_t default_value, size_t min_value, size_t max_value,
          uint64_t option, size_t* value, bool combo_option = false, bool* config = nullptr)
      : Option(name, option, combo_option, config), default_value(default_value),
        min_value(min_value), max_value(max_value), value(value) {}
  virtual ~OptionSizeT() = default;

  size_t default_value;
  size_t min_value;
  size_t max_value;

  size_t* value;

  bool ParseValue(const std::string& option_name, const std::string& value) const override;

  void SetDefault() const override { if (value) *value = default_value; }
};

bool OptionSizeT::ParseValue(const std::string& option_name, const std::string& raw_value) const {
  if (raw_value.empty()) {
    // Value should have been set by the SetDefault() pass.
    return true;
  }

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

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

class PropertyParser {
 public:
  explicit PropertyParser(const char* property) : cur_(property) {}

  bool Get(std::string* property, std::string* value);

  bool Done() { return done_; }

  void LogUsage();

 private:
  const char* cur_ = nullptr;

  bool done_ = false;

  DISALLOW_COPY_AND_ASSIGN(PropertyParser);
};

bool PropertyParser::Get(std::string* property, std::string* value) {
  // Process each property name we can find.
  while (isspace(*cur_))
    ++cur_;

  if (*cur_ == '\0') {
    done_ = true;
    return false;
  }

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

  *property = 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);
    }
  }
  return true;
}

void PropertyParser::LogUsage() {
  error_log("malloc debug options usage:");
  error_log("");
  error_log("  front_guard[=XX]");
  error_log("    Enables a front guard on all allocations. If XX is set");
  error_log("    it sets the number of bytes in the guard. The default is");
  error_log("    %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES);
  error_log("");
  error_log("  rear_guard[=XX]");
  error_log("    Enables a rear guard on all allocations. If XX is set");
  error_log("    it sets the number of bytes in the guard. The default is");
  error_log("    %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES);
  error_log("");
  error_log("  guard[=XX]");
  error_log("    Enables both a front guard and a rear guard on all allocations.");
  error_log("    If XX is set it sets the number of bytes in both guards.");
  error_log("    The default is %zu bytes, the max bytes is %zu.",
            DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES);
  error_log("");
  error_log("  backtrace[=XX]");
  error_log("    Enable capturing the backtrace at the point of allocation.");
  error_log("    If XX is set it sets the number of backtrace frames.");
  error_log("    The default is %zu frames, the max number of frames is %zu.",
            DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
  error_log("");
  error_log("  backtrace_enable_on_signal[=XX]");
  error_log("    Enable capturing the backtrace at the point of allocation.");
  error_log("    The backtrace capture is not enabled until the process");
  error_log("    receives a signal. If XX is set it sets the number of backtrace");
  error_log("    frames. The default is %zu frames, the max number of frames is %zu.",
            DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
  error_log("");
  error_log("  fill_on_alloc[=XX]");
  error_log("    On first allocation, fill with the value 0x%02x.", DEFAULT_FILL_ALLOC_VALUE);
  error_log("    If XX is set it will only fill up to XX bytes of the");
  error_log("    allocation. The default is to fill the entire allocation.");
  error_log("");
  error_log("  fill_on_free[=XX]");
  error_log("    On free, fill with the value 0x%02x. If XX is set it will",
            DEFAULT_FILL_FREE_VALUE);
  error_log("    only fill up to XX bytes of the allocation. The default is to");
  error_log("    fill the entire allocation.");
  error_log("");
  error_log("  fill[=XX]");
  error_log("    On both first allocation free, fill with the value 0x%02x on",
            DEFAULT_FILL_ALLOC_VALUE);
  error_log("    first allocation and the value 0x%02x. If XX is set, only fill",
            DEFAULT_FILL_FREE_VALUE);
  error_log("    up to XX bytes. The default is to fill the entire allocation.");
  error_log("");
  error_log("  expand_alloc[=XX]");
  error_log("    Allocate an extra number of bytes for every allocation call.");
  error_log("    If XX is set, that is the number of bytes to expand the");
  error_log("    allocation by. The default is %zu bytes, the max bytes is %zu.",
            DEFAULT_EXPAND_BYTES, MAX_EXPAND_BYTES);
  error_log("");
  error_log("  free_track[=XX]");
  error_log("    When a pointer is freed, do not free the memory right away.");
  error_log("    Instead, keep XX of these allocations around and then verify");
  error_log("    that they have not been modified when the total number of freed");
  error_log("    allocations exceeds the XX amount. When the program terminates,");
  error_log("    the rest of these allocations are verified. When this option is");
  error_log("    enabled, it automatically records the backtrace at the time of the free.");
  error_log("    The default is to record %zu allocations, the max allocations",
            DEFAULT_FREE_TRACK_ALLOCATIONS);
  error_log("    to record is %zu.", MAX_FREE_TRACK_ALLOCATIONS);
  error_log("");
  error_log("  free_track_backtrace_num_frames[=XX]");
  error_log("    This option only has meaning if free_track is set. This indicates");
  error_log("    how many backtrace frames to capture when an allocation is freed.");
  error_log("    If XX is set, that is the number of frames to capture. If XX");
  error_log("    is set to zero, then no backtrace will be captured.");
  error_log("    The default is to record %zu frames, the max number of frames is %zu.",
            DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
  error_log("");
  error_log("  leak_track");
  error_log("    Enable the leak tracking of memory allocations.");
  error_log("");
  error_log("  record_allocs[=XX]");
  error_log("    Record every single allocation/free call. When a specific signal");
  error_log("    is sent to the process, the contents of recording are written to");
  error_log("    a file (%s) and the recording is cleared.", DEFAULT_RECORD_ALLOCS_FILE);
  error_log("    If XX is set, that is the total number of allocations/frees that can");
  error_log("    recorded. of frames to capture. The default value is %zu.", DEFAULT_RECORD_ALLOCS);
  error_log("    If the allocation list fills up, all further allocations are not recorded.");
  error_log("");
  error_log("  record_alloc_file[=FILE]");
  error_log("    This option only has meaning if the record_allocs options has been specified.");
  error_log("    This is the name of the file to which recording information will be dumped.");
  error_log("    The default is %s.", DEFAULT_RECORD_ALLOCS_FILE);
}

// This function is designed to be called once. A second call will not
// reset all variables.
bool Config::SetFromProperties() {
  char property_str[PROP_VALUE_MAX];
  memset(property_str, 0, sizeof(property_str));
  if (!__system_property_get("libc.debug.malloc.options", property_str)) {
    return false;
  }

  // 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;
  record_allocs_signal = SIGRTMAX - 18;
  free_track_backtrace_num_frames = 0;
  record_allocs_file.clear();

  // Parse the options are of the format:
  //   option_name or option_name=XX

  // Supported options:
  const OptionSizeT option_guard(
      "guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, 0, nullptr, true);
  // Enable front guard. Value is the size of the guard.
  const OptionSizeT option_front_guard(
      "front_guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, FRONT_GUARD,
      &this->front_guard_bytes, true);
  // Enable end guard. Value is the size of the guard.
  const OptionSizeT option_rear_guard(
      "rear_guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, REAR_GUARD, &this->rear_guard_bytes,
      true);

  // Enable logging the backtrace on allocation. Value is the total
  // number of frames to log.
  const OptionSizeT option_backtrace(
      "backtrace", DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, BACKTRACE | TRACK_ALLOCS,
      &this->backtrace_frames, false, &this->backtrace_enabled);
  // Enable gathering backtrace values on a signal.
  const OptionSizeT option_backtrace_enable_on_signal(
      "backtrace_enable_on_signal", DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES,
      BACKTRACE | TRACK_ALLOCS, &this->backtrace_frames, false, &this->backtrace_enable_on_signal);

  const OptionSizeT option_fill("fill", SIZE_MAX, 1, SIZE_MAX, 0, nullptr, true);
  // Fill the allocation with an arbitrary pattern on allocation.
  // Value is the number of bytes of the allocation to fill
  // (default entire allocation).
  const OptionSizeT option_fill_on_alloc(
      "fill_on_alloc", SIZE_MAX, 1, SIZE_MAX, FILL_ON_ALLOC, &this->fill_on_alloc_bytes, true);
  // Fill the allocation with an arbitrary pattern on free.
  // Value is the number of bytes of the allocation to fill
  // (default entire allocation).
  const OptionSizeT option_fill_on_free(
      "fill_on_free", SIZE_MAX, 1, SIZE_MAX, FILL_ON_FREE, &this->fill_on_free_bytes, true);

  // Expand the size of every alloc by this number bytes. Value is
  // the total number of bytes to expand every allocation by.
  const OptionSizeT option_expand_alloc(
      "expand_alloc", DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, EXPAND_ALLOC,
      &this->expand_alloc_bytes);

  // Keep track of the freed allocations and verify at a later date
  // that they have not been used. Turning this on, also turns on
  // fill on free.
  const OptionSizeT option_free_track(
      "free_track", DEFAULT_FREE_TRACK_ALLOCATIONS, 1, MAX_FREE_TRACK_ALLOCATIONS,
      FREE_TRACK | FILL_ON_FREE, &this->free_track_allocations);
  // Number of backtrace frames to keep when free_track is enabled. If this
  // value is set to zero, no backtrace will be kept.
  const OptionSizeT option_free_track_backtrace_num_frames(
      "free_track_backtrace_num_frames", DEFAULT_BACKTRACE_FRAMES, 0, MAX_BACKTRACE_FRAMES, 0,
      &this->free_track_backtrace_num_frames);

  // Enable printing leaked allocations.
  const Option option_leak_track("leak_track", LEAK_TRACK | TRACK_ALLOCS);

  const OptionSizeT option_record_allocs(
      "record_allocs", DEFAULT_RECORD_ALLOCS, 1, MAX_RECORD_ALLOCS, RECORD_ALLOCS,
      &this->record_allocs_num_entries);
  const OptionString option_record_allocs_file(
      "record_allocs_file", 0, DEFAULT_RECORD_ALLOCS_FILE, &this->record_allocs_file);

  const Option* option_list[] = {
    &option_guard, &option_front_guard, &option_rear_guard,
    &option_backtrace, &option_backtrace_enable_on_signal,
    &option_fill, &option_fill_on_alloc, &option_fill_on_free,
    &option_expand_alloc,
    &option_free_track, &option_free_track_backtrace_num_frames,
    &option_leak_track,
    &option_record_allocs, &option_record_allocs_file,
  };

  // Set defaults for all of the options.
  for (size_t i = 0; i < sizeof(option_list)/sizeof(Option*); i++) {
    option_list[i]->SetDefault();
  }

  // Process each property name we can find.
  PropertyParser parser(property_str);
  bool valid = true;
  std::string property;
  std::string value;
  while (valid && parser.Get(&property, &value)) {
    bool found = false;
    for (size_t i = 0; i < sizeof(option_list)/sizeof(Option*); i++) {
      if (property == option_list[i]->name) {
        if (option_list[i]->option == 0 && option_list[i]->combo_option) {
          const std::string* option_name = &option_list[i]->name;
          i++;
          for (; i < sizeof(option_list)/sizeof(Option*) && option_list[i]->combo_option; i++) {
            if (!option_list[i]->ParseValue(*option_name, value)) {
              valid = false;
              break;
            }
            if (option_list[i]->config) {
              *option_list[i]->config = true;
            }
            options |= option_list[i]->option;
          }
          if (!valid) {
            break;
          }
        } else {
          if (!option_list[i]->ParseValue(option_list[i]->name, value)) {
            valid = false;
            break;
          }
          if (option_list[i]->config) {
            *option_list[i]->config = true;
          }
          options |= option_list[i]->option;
        }
        found = true;
        break;
      }
    }
    if (valid && !found) {
      error_log("%s: unknown option %s", getprogname(), property.c_str());
      valid = false;
      break;
    }
  }

  valid = valid && parser.Done();

  if (valid) {
    // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
    // make sure that the header is aligned properly.
    if (options & FRONT_GUARD) {
      front_guard_bytes = BIONIC_ALIGN(front_guard_bytes, MINIMUM_ALIGNMENT_BYTES);
    }
  } else {
    parser.LogUsage();
  }

  return valid;
}
