//===-- LinuxProcMaps.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "LinuxProcMaps.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringExtractor.h"
#include "llvm/ADT/StringRef.h"

using namespace lldb_private;

enum class MapsKind { Maps, SMaps };

static llvm::Expected<MemoryRegionInfo> ProcMapError(const char *msg,
                                                     MapsKind kind) {
  return llvm::createStringError(llvm::inconvertibleErrorCode(), msg,
                                 kind == MapsKind::Maps ? "maps" : "smaps");
}

static llvm::Expected<MemoryRegionInfo>
ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
                                      MapsKind maps_kind) {
  MemoryRegionInfo region;
  StringExtractor line_extractor(maps_line);

  // Format: {address_start_hex}-{address_end_hex} perms offset  dev   inode
  // pathname perms: rwxp   (letter is present if set, '-' if not, final
  // character is p=private, s=shared).

  // Parse out the starting address
  lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);

  // Parse out hyphen separating start and end address from range.
  if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
    return ProcMapError(
        "malformed /proc/{pid}/%s entry, missing dash between address range",
        maps_kind);

  // Parse out the ending address
  lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);

  // Parse out the space after the address.
  if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
    return ProcMapError(
        "malformed /proc/{pid}/%s entry, missing space after range", maps_kind);

  // Save the range.
  region.GetRange().SetRangeBase(start_address);
  region.GetRange().SetRangeEnd(end_address);

  // Any memory region in /proc/{pid}/(maps|smaps) is by definition mapped
  // into the process.
  region.SetMapped(MemoryRegionInfo::OptionalBool::eYes);

  // Parse out each permission entry.
  if (line_extractor.GetBytesLeft() < 4)
    return ProcMapError(
        "malformed /proc/{pid}/%s entry, missing some portion of "
        "permissions",
        maps_kind);

  // Handle read permission.
  const char read_perm_char = line_extractor.GetChar();
  if (read_perm_char == 'r')
    region.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
  else if (read_perm_char == '-')
    region.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
  else
    return ProcMapError("unexpected /proc/{pid}/%s read permission char",
                        maps_kind);

  // Handle write permission.
  const char write_perm_char = line_extractor.GetChar();
  if (write_perm_char == 'w')
    region.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
  else if (write_perm_char == '-')
    region.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
  else
    return ProcMapError("unexpected /proc/{pid}/%s write permission char",
                        maps_kind);

  // Handle execute permission.
  const char exec_perm_char = line_extractor.GetChar();
  if (exec_perm_char == 'x')
    region.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
  else if (exec_perm_char == '-')
    region.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
  else
    return ProcMapError("unexpected /proc/{pid}/%s exec permission char",
                        maps_kind);

  line_extractor.GetChar();              // Read the private bit
  line_extractor.SkipSpaces();           // Skip the separator
  line_extractor.GetHexMaxU64(false, 0); // Read the offset
  line_extractor.GetHexMaxU64(false, 0); // Read the major device number
  line_extractor.GetChar();              // Read the device id separator
  line_extractor.GetHexMaxU64(false, 0); // Read the major device number
  line_extractor.SkipSpaces();           // Skip the separator
  line_extractor.GetU64(0, 10);          // Read the inode number

  line_extractor.SkipSpaces();
  const char *name = line_extractor.Peek();
  if (name)
    region.SetName(name);

  return region;
}

void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
                                        LinuxMapCallback const &callback) {
  llvm::StringRef lines(linux_map);
  llvm::StringRef line;
  while (!lines.empty()) {
    std::tie(line, lines) = lines.split('\n');
    if (!callback(ParseMemoryRegionInfoFromProcMapsLine(line, MapsKind::Maps)))
      break;
  }
}

void lldb_private::ParseLinuxSMapRegions(llvm::StringRef linux_smap,
                                         LinuxMapCallback const &callback) {
  // Entries in /smaps look like:
  // 00400000-0048a000 r-xp 00000000 fd:03 960637
  // Size:                552 kB
  // Rss:                 460 kB
  // <...>
  // VmFlags: rd ex mr mw me dw
  // 00500000-0058a000 rwxp 00000000 fd:03 960637
  // <...>
  //
  // Where the first line is identical to the /maps format
  // and VmFlags is only printed for kernels >= 3.8.

  llvm::StringRef lines(linux_smap);
  llvm::StringRef line;
  llvm::Optional<MemoryRegionInfo> region;

  while (lines.size()) {
    std::tie(line, lines) = lines.split('\n');

    // A property line looks like:
    // <word>: <value>
    // (no spaces on the left hand side)
    // A header will have a ':' but the LHS will contain spaces
    llvm::StringRef name;
    llvm::StringRef value;
    std::tie(name, value) = line.split(':');

    // If this line is a property line
    if (!name.contains(' ')) {
      if (region) {
        if (name == "VmFlags") {
          if (value.contains("mt"))
            region->SetMemoryTagged(MemoryRegionInfo::eYes);
          else
            region->SetMemoryTagged(MemoryRegionInfo::eNo);
        }
        // Ignore anything else
      } else {
        // Orphaned settings line
        callback(ProcMapError(
            "Found a property line without a corresponding mapping "
            "in /proc/{pid}/%s",
            MapsKind::SMaps));
        return;
      }
    } else {
      // Must be a new region header
      if (region) {
        // Save current region
        callback(*region);
        region.reset();
      }

      // Try to start a new region
      llvm::Expected<MemoryRegionInfo> new_region =
          ParseMemoryRegionInfoFromProcMapsLine(line, MapsKind::SMaps);
      if (new_region) {
        region = *new_region;
      } else {
        // Stop at first invalid region header
        callback(new_region.takeError());
        return;
      }
    }
  }

  // Catch last region
  if (region)
    callback(*region);
}
