pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lldb-netbsd: Read process virtual memory mapping



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Wed Mar 15 14:49:48 2017 +0100
Changeset:	d4af36204feb616dd83f5f3ffb871a4b7274e5e0

Modified Files:
	lldb-netbsd/distinfo
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
	lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h

Log Message:
lldb-netbsd: Read process virtual memory mapping

Port GetMemoryRegionInfo to NetBSD.

Sponsored by <The NetBSD Foundation>

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=d4af36204feb616dd83f5f3ffb871a4b7274e5e0

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 lldb-netbsd/distinfo                               |   4 +-
 ..._Plugins_Process_NetBSD_NativeProcessNetBSD.cpp | 181 +++++++++------------
 ...ce_Plugins_Process_NetBSD_NativeProcessNetBSD.h |   8 +-
 3 files changed, 87 insertions(+), 106 deletions(-)

diffs:
diff --git a/lldb-netbsd/distinfo b/lldb-netbsd/distinfo
index 8b298122b3..b43105e179 100644
--- a/lldb-netbsd/distinfo
+++ b/lldb-netbsd/distinfo
@@ -26,8 +26,8 @@ SHA1 (patch-source_Plugins_DynamicLoader_POSIX-DYLD_DYLDRendezvous.cpp) = 32d683
 SHA1 (patch-source_Plugins_DynamicLoader_POSIX-DYLD_DynamicLoaderPOSIXDYLD.cpp) = ed8077e029281f6d1a9f043edc5a3b16d126eea2
 SHA1 (patch-source_Plugins_Process_CMakeLists.txt) = c689ff4ec455234f8d506dc9eb8e0ed7f750d426
 SHA1 (patch-source_Plugins_Process_NetBSD_CMakeLists.txt) = a77f397020ab752875813a7a93b53ccd3a130e6f
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = 5a14d0b981c33db9c8878c93f74bc67f5112a114
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h) = c48bb2dd45682164ab904b8b3f7664b91ac35d5b
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = 78521c12fbd070ba6221fd2619630bf8306e4cbf
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h) = f051f86d7ca2047e9f4d414e46f454e626348c14
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp) = 89a9f56d1ee3103ac73c274f233f0d6816e20363
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h) = dccd470b53937f58c5697f7e2507cc76db497ce8
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp) = cd0965e27e5b2374708b392ec707a5f98f2392d8
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
index bdc00cceb5..70899b460a 100644
--- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
@@ -2,7 +2,7 @@ $NetBSD$
 
 --- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp.orig	2017-03-14 16:45:14.522261905 +0000
 +++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
-@@ -0,0 +1,1397 @@
+@@ -0,0 +1,1376 @@
 +//===-- NativeProcessNetBSD.cpp -------------------------------- -*- C++ -*-===//
 +//
 +//                     The LLVM Compiler Infrastructure
@@ -15,10 +15,15 @@ $NetBSD$
 +#include "NativeProcessNetBSD.h"
 +
 +// C Includes
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/sysctl.h>
++#include <uvm/uvm_prot.h>
 +#include <errno.h>
 +#include <stdint.h>
 +#include <string.h>
 +#include <unistd.h>
++#include <util.h>
 +
 +// C++ Includes
 +#include <fstream>
@@ -867,120 +872,31 @@ $NetBSD$
 +  return error;
 +}
 +
-+static Error
-+ParseMemoryRegionInfoFromProcMapsLine(const std::string &maps_line,
-+                                      MemoryRegionInfo &memory_region_info) {
-+  memory_region_info.Clear();
-+
-+  StringExtractor line_extractor(maps_line.c_str());
-+
-+  // 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 Error(
-+        "malformed /proc/{pid}/maps entry, missing dash between address range");
-+
-+  // 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 Error("malformed /proc/{pid}/maps entry, missing space after range");
-+
-+  // Save the range.
-+  memory_region_info.GetRange().SetRangeBase(start_address);
-+  memory_region_info.GetRange().SetRangeEnd(end_address);
-+
-+  // Any memory region in /proc/{pid}/maps is by definition mapped into the
-+  // process.
-+  memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
-+
-+  // Parse out each permission entry.
-+  if (line_extractor.GetBytesLeft() < 4)
-+    return Error("malformed /proc/{pid}/maps entry, missing some portion of "
-+                 "permissions");
-+
-+  // Handle read permission.
-+  const char read_perm_char = line_extractor.GetChar();
-+  if (read_perm_char == 'r')
-+    memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
-+  else if (read_perm_char == '-')
-+    memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
-+  else
-+    return Error("unexpected /proc/{pid}/maps read permission char");
-+
-+  // Handle write permission.
-+  const char write_perm_char = line_extractor.GetChar();
-+  if (write_perm_char == 'w')
-+    memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
-+  else if (write_perm_char == '-')
-+    memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
-+  else
-+    return Error("unexpected /proc/{pid}/maps write permission char");
-+
-+  // Handle execute permission.
-+  const char exec_perm_char = line_extractor.GetChar();
-+  if (exec_perm_char == 'x')
-+    memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
-+  else if (exec_perm_char == '-')
-+    memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
-+  else
-+    return Error("unexpected /proc/{pid}/maps exec permission char");
-+
-+  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)
-+    memory_region_info.SetName(name);
-+
-+  return Error();
-+}
-+
 +Error NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
 +                                              MemoryRegionInfo &range_info) {
-+#if 0
-+  // FIXME review that the final memory region returned extends to the end of
-+  // the virtual address space,
-+  // with no perms if it is not mapped.
-+
-+  // Use an approach that reads memory regions from /proc/{pid}/maps.
-+  // Assume proc maps entries are in ascending order.
-+  // FIXME assert if we find differently.
 +
 +  if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
 +    // We're done.
 +    return Error("unsupported");
 +  }
 +
-+  lldb::addr_t prev_base_address = 0;
++  Error error = PopulateMemoryRegionCache();
++  if (error.Fail()) {
++    return error;
++  }
 +
++  lldb::addr_t prev_base_address = 0;
 +  // FIXME start by finding the last region that is <= target address using
 +  // binary search.  Data is sorted.
 +  // There can be a ton of regions on pthreads apps with lots of threads.
 +  for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
 +       ++it) {
-+    MemoryRegionInfo &proc_entry_info = *it;
-+
++    MemoryRegionInfo &proc_entry_info = it->first;
 +    // Sanity check assumption that /proc/{pid}/maps entries are ascending.
 +    assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
 +           "descending /proc/pid/maps entries detected, unexpected");
 +    prev_base_address = proc_entry_info.GetRange().GetRangeBase();
-+
++    UNUSED_IF_ASSERT_DISABLED(prev_base_address);
 +    // If the target address comes before this entry, indicate distance to next
 +    // region.
 +    if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
@@ -991,18 +907,15 @@ $NetBSD$
 +      range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
 +      range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
 +      range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
-+
 +      return error;
 +    } else if (proc_entry_info.GetRange().Contains(load_addr)) {
 +      // The target address is within the memory region we're processing here.
 +      range_info = proc_entry_info;
 +      return error;
 +    }
-+
 +    // The target memory address comes somewhere after the region we just
 +    // parsed.
 +  }
-+
 +  // If we made it here, we didn't find an entry that contained the given
 +  // address. Return the
 +  // load_addr as start and the amount of bytes betwwen load address and the end
@@ -1015,7 +928,73 @@ $NetBSD$
 +  range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
 +  range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
 +  return error;
-+#endif
++}
++
++
++Error NativeProcessNetBSD::PopulateMemoryRegionCache() {
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  // If our cache is empty, pull the latest.  There should always be at least
++  // one memory region if memory region handling is supported.
++  if (!m_mem_region_cache.empty()) {
++    LLDB_LOG(log, "reusing {0} cached memory region entries",
++             m_mem_region_cache.size());
++    return Error();
++  }
++
++  struct kinfo_vmentry *vm;
++  size_t count, i;
++  vm = kinfo_getvmmap(getpid(), &count);
++  if (vm == NULL) {
++    m_supports_mem_region = LazyBool::eLazyBoolNo;
++    Error error;
++    error.SetErrorString("not supported");
++    return error;
++  }
++  for (i = 0; i < count; i++) {
++    MemoryRegionInfo info;
++    info.Clear();
++    info.GetRange().SetRangeBase(vm[i].kve_start);
++    info.GetRange().SetRangeEnd(vm[i].kve_end);
++    info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
++
++    if (vm[i].kve_protection & VM_PROT_READ)
++      info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
++    else
++      info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
++
++    if (vm[i].kve_protection & VM_PROT_WRITE)
++      info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
++    else
++      info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
++
++    if (vm[i].kve_protection & VM_PROT_EXECUTE)
++      info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
++    else
++      info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
++
++    if (vm[i].kve_path)
++      info.SetName(vm[i].kve_path);
++
++    m_mem_region_cache.emplace_back(
++      info, FileSpec(info.GetName().GetCString(), true));
++  }
++  free(vm);
++
++  if (m_mem_region_cache.empty()) {
++    // No entries after attempting to read them.  This shouldn't happen.
++    // Assume we don't support map entries.
++    LLDB_LOG(log,
++             "failed to find any vmmap entries, assuming no support "
++             "for memory region metadata retrieval");
++    m_supports_mem_region = LazyBool::eLazyBoolNo;
++    Error error;
++    error.SetErrorString("not supported");
++    return error;
++  }
++  LLDB_LOG(log, "read {0} memory region entries from process {1}",
++           m_mem_region_cache.size(), GetID());
++  // We support memory retrieval, remember that.
++  m_supports_mem_region = LazyBool::eLazyBoolYes;
 +  return Error();
 +}
 +
diff --git a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
index ffb2b10852..dc03fa95eb 100644
--- a/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
+++ b/lldb-netbsd/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
@@ -1,8 +1,8 @@
 $NetBSD$
 
---- source/Plugins/Process/NetBSD/NativeProcessNetBSD.h.orig	2017-01-31 18:01:27.506688091 +0000
+--- source/Plugins/Process/NetBSD/NativeProcessNetBSD.h.orig	2017-03-14 16:45:14.529112718 +0000
 +++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
-@@ -0,0 +1,183 @@
+@@ -0,0 +1,185 @@
 +//===-- NativeProcessNetBSD.h ---------------------------------- -*- C++ -*-===//
 +//
 +//                     The LLVM Compiler Infrastructure
@@ -122,7 +122,7 @@ $NetBSD$
 +  ArchSpec m_arch;
 +
 +  LazyBool m_supports_mem_region;
-+  std::vector<MemoryRegionInfo> m_mem_region_cache;
++  std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 +
 +  lldb::tid_t m_pending_notification_tid;
 +
@@ -180,6 +180,8 @@ $NetBSD$
 +                     int signo);
 +
 +  void SigchldHandler();
++
++  Error PopulateMemoryRegionCache();
 +};
 +
 +} // namespace process_netbsd


Home | Main Index | Thread Index | Old Index