// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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
//
//     http://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.

#include "util/linux/memory_map.h"

#include <stdio.h>
#include <string.h>
#include <sys/sysmacros.h>

#include "base/files/file_path.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "util/file/delimited_file_reader.h"
#include "util/file/file_io.h"
#include "util/file/string_file.h"
#include "util/stdlib/string_number_conversion.h"

namespace crashpad {

namespace {

// This function is used in this file specfically for signed or unsigned longs.
// longs are typically either int or int64 sized, but pointers to longs are not
// automatically coerced to pointers to ints when they are the same size.
// Simply adding a StringToNumber for longs doesn't work since sometimes long
// and int64_t are actually the same type, resulting in a redefinition error.
template <typename Type>
bool LocalStringToNumber(const std::string& string, Type* number) {
  static_assert(sizeof(Type) == sizeof(int) || sizeof(Type) == sizeof(int64_t),
                "Unexpected Type size");

  if (sizeof(Type) == sizeof(int)) {
    return std::numeric_limits<Type>::is_signed
               ? StringToNumber(string, reinterpret_cast<int*>(number))
               : StringToNumber(string,
                                reinterpret_cast<unsigned int*>(number));
  } else {
    return std::numeric_limits<Type>::is_signed
               ? StringToNumber(string, reinterpret_cast<int64_t*>(number))
               : StringToNumber(string, reinterpret_cast<uint64_t*>(number));
  }
}

template <typename Type>
bool HexStringToNumber(const std::string& string, Type* number) {
  return LocalStringToNumber("0x" + string, number);
}

// The result from parsing a line from the maps file.
enum class ParseResult {
  // A line was successfully parsed.
  kSuccess = 0,

  // The end of the file was successfully reached.
  kEndOfFile,

  // There was an error in the file, likely because it was read non-atmoically.
  // We should try to read it again.
  kRetry,

  // An error with a message logged.
  kError
};

// Reads a line from a maps file being read by maps_file_reader and extends
// mappings with a new MemoryMap::Mapping describing the line.
ParseResult ParseMapsLine(DelimitedFileReader* maps_file_reader,
                          std::vector<MemoryMap::Mapping>* mappings) {
  std::string field;
  LinuxVMAddress start_address;
  switch (maps_file_reader->GetDelim('-', &field)) {
    case DelimitedFileReader::Result::kError:
      return ParseResult::kError;
    case DelimitedFileReader::Result::kEndOfFile:
      return ParseResult::kEndOfFile;
    case DelimitedFileReader::Result::kSuccess:
      field.pop_back();
      if (!HexStringToNumber(field, &start_address)) {
        LOG(ERROR) << "format error";
        return ParseResult::kError;
      }
      if (!mappings->empty() && start_address < mappings->back().range.End()) {
        return ParseResult::kRetry;
      }
  }

  LinuxVMAddress end_address;
  if (maps_file_reader->GetDelim(' ', &field) !=
          DelimitedFileReader::Result::kSuccess ||
      (field.pop_back(), !HexStringToNumber(field, &end_address))) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }
  if (end_address <= start_address) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }

  // TODO(jperaza): set bitness properly
#if defined(ARCH_CPU_64_BITS)
  constexpr bool is_64_bit = true;
#else
  constexpr bool is_64_bit = false;
#endif

  MemoryMap::Mapping mapping;
  mapping.range.SetRange(is_64_bit, start_address, end_address - start_address);

  if (maps_file_reader->GetDelim(' ', &field) !=
          DelimitedFileReader::Result::kSuccess ||
      (field.pop_back(), field.size() != 4)) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }
#define SET_FIELD(actual_c, outval, true_chars, false_chars) \
  do {                                                       \
    if (strchr(true_chars, actual_c)) {                      \
      *outval = true;                                        \
    } else if (strchr(false_chars, actual_c)) {              \
      *outval = false;                                       \
    } else {                                                 \
      LOG(ERROR) << "format error";                          \
      return ParseResult::kError;                            \
    }                                                        \
  } while (false)
  SET_FIELD(field[0], &mapping.readable, "r", "-");
  SET_FIELD(field[1], &mapping.writable, "w", "-");
  SET_FIELD(field[2], &mapping.executable, "x", "-");
  SET_FIELD(field[3], &mapping.shareable, "sS", "p");
#undef SET_FIELD

  if (maps_file_reader->GetDelim(' ', &field) !=
          DelimitedFileReader::Result::kSuccess ||
      (field.pop_back(), !HexStringToNumber(field, &mapping.offset))) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }

  uint32_t major;
  if (maps_file_reader->GetDelim(':', &field) !=
          DelimitedFileReader::Result::kSuccess ||
      (field.pop_back(), field.size()) < 2 ||
      !HexStringToNumber(field, &major)) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }

  uint32_t minor;
  if (maps_file_reader->GetDelim(' ', &field) !=
          DelimitedFileReader::Result::kSuccess ||
      (field.pop_back(), field.size()) < 2 ||
      !HexStringToNumber(field, &minor)) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }

  mapping.device = makedev(major, minor);

  if (maps_file_reader->GetDelim(' ', &field) !=
          DelimitedFileReader::Result::kSuccess ||
      (field.pop_back(), !LocalStringToNumber(field, &mapping.inode))) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }

  if (maps_file_reader->GetDelim('\n', &field) !=
      DelimitedFileReader::Result::kSuccess) {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }
  if (field.back() != '\n') {
    LOG(ERROR) << "format error";
    return ParseResult::kError;
  }
  field.pop_back();

  mappings->push_back(mapping);

  size_t path_start = field.find_first_not_of(' ');
  if (path_start != std::string::npos) {
    mappings->back().name = field.substr(path_start);
  }
  return ParseResult::kSuccess;
}

}  // namespace

MemoryMap::Mapping::Mapping()
    : name(),
      range(false, 0, 0),
      offset(0),
      device(0),
      inode(0),
      readable(false),
      writable(false),
      executable(false),
      shareable(false) {}

MemoryMap::MemoryMap() : mappings_(), initialized_() {}

MemoryMap::~MemoryMap() {}

bool MemoryMap::Mapping::Equals(const Mapping& other) const {
  DCHECK_EQ(range.Is64Bit(), other.range.Is64Bit());
  return range.Base() == other.range.Base() &&
         range.Size() == other.range.Size() && name == other.name &&
         offset == other.offset && device == other.device &&
         inode == other.inode && readable == other.readable &&
         writable == other.writable && executable == other.executable &&
         shareable == other.shareable;
}

bool MemoryMap::Initialize(pid_t pid) {
  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);

  // If the maps file is not read atomically, entries can be read multiple times
  // or missed entirely. The kernel reads entries from this file into a page
  // sized buffer, so maps files larger than a page require multiple reads.
  // Attempt to reduce the time between reads by reading the entire file into a
  // StringFile before attempting to parse it. If ParseMapsLine detects
  // duplicate, overlapping, or out-of-order entries, it will trigger restarting
  // the read up to |attempts| times.
  int attempts = 3;
  do {
    std::string contents;
    char path[32];
    snprintf(path, sizeof(path), "/proc/%d/maps", pid);
    if (!LoggingReadEntireFile(base::FilePath(path), &contents)) {
      return false;
    }

    StringFile maps_file;
    maps_file.SetString(contents);
    DelimitedFileReader maps_file_reader(&maps_file);

    ParseResult result;
    while ((result = ParseMapsLine(&maps_file_reader, &mappings_)) ==
           ParseResult::kSuccess) {
    }
    if (result == ParseResult::kEndOfFile) {
      INITIALIZATION_STATE_SET_VALID(initialized_);
      return true;
    }
    if (result == ParseResult::kError) {
      return false;
    }

    DCHECK(result == ParseResult::kRetry);
  } while (--attempts > 0);

  LOG(ERROR) << "retry count exceeded";
  return false;
}

const MemoryMap::Mapping* MemoryMap::FindMapping(LinuxVMAddress address) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  for (const auto& mapping : mappings_) {
    if (mapping.range.Base() <= address && mapping.range.End() > address) {
      return &mapping;
    }
  }
  return nullptr;
}

const MemoryMap::Mapping* MemoryMap::FindMappingWithName(
    const std::string& name) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  for (const auto& mapping : mappings_) {
    if (mapping.name == name) {
      return &mapping;
    }
  }
  return nullptr;
}

const MemoryMap::Mapping* MemoryMap::FindFileMmapStart(
    const Mapping& mapping) const {
  INITIALIZATION_STATE_DCHECK_VALID(initialized_);

  size_t index = 0;
  for (; index < mappings_.size(); ++index) {
    if (mappings_[index].Equals(mapping)) {
      break;
    }
  }
  if (index >= mappings_.size()) {
    LOG(ERROR) << "mapping not found";
    return nullptr;
  }

  // If the mapping is anonymous, as is for the VDSO, there is no mapped file to
  // find the start of, so just return the input mapping.
  if (mapping.device == 0 && mapping.inode == 0) {
    return &mappings_[index];
  }

  do {
    // There may by anonymous mappings or other files mapped into the holes,
    // so check that the mapping uses the same file as the input, but keep
    // searching if it doesn't.
    if (mappings_[index].device == mapping.device &&
        mappings_[index].inode == mapping.inode &&
        mappings_[index].offset == 0) {
      return &mappings_[index];
    }
  } while (index--);

  LOG(ERROR) << "mapping not found";
  return nullptr;
}

}  // namespace crashpad
