https://github.com/satyajanga created 
https://github.com/llvm/llvm-project/pull/149019

Summary:
This patch adds a new `DynamicLoaderDumpWithModuleList` plugin which can be 
used for coredump debugging. It leverages NT_FILE note in coredump to get 
module list instead of relying on posix rdebug data structure which highly 
depends on having a matching main executable available. Once the module list is 
generated a ObjectFilePlaceholder is created for each module.

This feature is only activated by both two conditions are true:
* `use-module-list-dyld` setting is true (false by default)
* coredump having `NT_FILE` notes

Per my testing, Meta's internal modern Linux kernel seems to always generate 
`NT_FILE` note so this should be very useful.

With this patch, coredump can be changed from
```
lldb <path_to_main_executable> -c <path_to_coredump>
```
to
```
lldb -c <path_to_coredump>
```

Test Plan:
* Added new unit test


Followup PR for `target module replace` command which enables to replace the 
object file place holders 
https://github.com/llvm/llvm-project/pull/148735/



>From 30c14619b06713074423bf879c8d46dbbf5b80a3 Mon Sep 17 00:00:00 2001
From: Jeffrey Tan <jeffrey...@meta.com>
Date: Wed, 21 Jul 2021 13:32:56 -0700
Subject: [PATCH] New DynamicLoaderDumpWithModuleList for coredump debugging

Summary:
This patch adds a new `DynamicLoaderDumpWithModuleList` plugin which can be 
used for coredump debugging.
It leverages NT_FILE note in coredump to get module list instead of relying on 
posix rdebug data structure which highly depends on having a matching main 
executable available. Once the module list is generated a ObjectFilePlaceholder 
is created for each module.

This feature is only activated by both two conditions are true:
* `use-module-list-dyld` setting is true (false by default)
* coredump having `NT_FILE` notes

Per my testing, Meta's modern Linux kernel seems to always generate `NT_FILE` 
note so this should be very useful.

With this patch, Meta's internal coredump can be changed from
```
lldb <path_to_main_executable> -c <path_to_coredump>
```
to
```
lldb -c <path_to_coredump>
```

Further diffs involving:
* New `target module replace` command to upgrade PlaceHolder module to real 
module
* Coredumper side change to generate fbpkg/rpm metadata so that 
`auto_debuginfo.py` can automatically locate debug info (in review)
* Implement `auto_debuginfo` to parse coredumper metadata to download fbpkg, 
unzip it, automatically run `target module replace` to upgrade all Placeholder 
modules into real modules.

I am landing this feature internally first because:
* Unblock the further work listed above
* Early beta testing from our users to get feedback and dogfooding.
* Quick turnover from open source code review

Once we got solid feedback, I will bring this to open source.

Test Plan:
* Added new unit test
* c4crasher end-to-end debugging

Reviewers: wanyi, hyubo, #lldb_team

Reviewed By: wanyi

Subscribers: jimmymalone, frd, #lldb_team

Differential Revision: https://phabricator.intern.facebook.com/D44558615
---
 lldb/include/lldb/Core/Debugger.h             |   2 +
 lldb/include/lldb/Core/LoadedModuleInfoList.h |  11 ++
 lldb/source/Core/CoreProperties.td            |   4 +
 lldb/source/Core/Debugger.cpp                 |   7 ++
 .../Plugins/DynamicLoader/CMakeLists.txt      |   1 +
 .../ModuleList-DYLD/CMakeLists.txt            |  11 ++
 .../DynamicLoaderDumpWithModuleList.cpp       | 109 ++++++++++++++++++
 .../DynamicLoaderDumpWithModuleList.h         |  75 ++++++++++++
 .../Plugins/Process/elf-core/CMakeLists.txt   |   1 +
 .../Process/elf-core/ProcessElfCore.cpp       |  70 ++++++++---
 .../Plugins/Process/elf-core/ProcessElfCore.h |   6 +
 11 files changed, 283 insertions(+), 14 deletions(-)
 create mode 100644 
lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt
 create mode 100644 
lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
 create mode 100644 
lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h

diff --git a/lldb/include/lldb/Core/Debugger.h 
b/lldb/include/lldb/Core/Debugger.h
index 504f936fe317a..e854b731270af 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -247,6 +247,8 @@ class Debugger : public 
std::enable_shared_from_this<Debugger>,
 
   FormatEntity::Entry GetDisassemblyFormat() const;
 
+  bool GetUseModuleListDyld() const;
+
   FormatEntity::Entry GetFrameFormat() const;
 
   FormatEntity::Entry GetFrameFormatUnique() const;
diff --git a/lldb/include/lldb/Core/LoadedModuleInfoList.h 
b/lldb/include/lldb/Core/LoadedModuleInfoList.h
index 537a2b0f1d379..5ff62b38d9a9c 100644
--- a/lldb/include/lldb/Core/LoadedModuleInfoList.h
+++ b/lldb/include/lldb/Core/LoadedModuleInfoList.h
@@ -27,6 +27,7 @@ class LoadedModuleInfoList {
       e_has_base,
       e_has_dynamic,
       e_has_link_map,
+      e_has_size,
       e_num
     };
 
@@ -77,6 +78,15 @@ class LoadedModuleInfoList {
       return m_has[e_has_dynamic];
     }
 
+    void set_size(const lldb::addr_t size) {
+      m_size = size;
+      m_has[e_has_size] = true;
+    }
+    bool get_size(lldb::addr_t &out) const {
+      out = m_size;
+      return m_has[e_has_size];
+    }
+
     bool has_info(e_data_point datum) const {
       assert(datum < e_num);
       return m_has[datum];
@@ -99,6 +109,7 @@ class LoadedModuleInfoList {
     lldb::addr_t m_base = LLDB_INVALID_ADDRESS;
     bool m_base_is_offset = false;
     lldb::addr_t m_dynamic = LLDB_INVALID_ADDRESS;
+    lldb::addr_t m_size = 0;
   };
 
   LoadedModuleInfoList() = default;
diff --git a/lldb/source/Core/CoreProperties.td 
b/lldb/source/Core/CoreProperties.td
index 53dd333f045c9..9aa86efb48bf4 100644
--- a/lldb/source/Core/CoreProperties.td
+++ b/lldb/source/Core/CoreProperties.td
@@ -268,4 +268,8 @@ let Definition = "debugger" in {
     Global,
     DefaultFalse,
     Desc<"Controls whether diagnostics can refer directly to the command 
input, drawing arrows to it. If false, diagnostics will echo the input.">;
+  def UseModuleListDyld: Property<"use-module-list-dyld", "Boolean">,
+    Global,
+    DefaultFalse,
+    Desc<"Use module list dynamic loader plugin for coredump debugging.">;
 }
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index ed674ee1275c7..c653a2caf5405 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -295,6 +295,13 @@ bool Debugger::GetAutoConfirm() const {
       idx, g_debugger_properties[idx].default_uint_value != 0);
 }
 
+
+bool Debugger::GetUseModuleListDyld() const {
+  const uint32_t idx = ePropertyUseModuleListDyld;
+  return GetPropertyAtIndexAs<bool>(
+      idx, g_debugger_properties[idx].default_uint_value != 0);
+}
+
 FormatEntity::Entry Debugger::GetDisassemblyFormat() const {
   constexpr uint32_t idx = ePropertyDisassemblyFormat;
   return GetPropertyAtIndexAs<FormatEntity::Entry>(idx, {});
diff --git a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt 
b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
index 01aba34b94169..6db81b125ed9c 100644
--- a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
+++ b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
@@ -8,6 +8,7 @@ set_property(DIRECTORY PROPERTY 
LLDB_TOLERATED_PLUGIN_DEPENDENCIES
 add_subdirectory(Darwin-Kernel)
 add_subdirectory(FreeBSD-Kernel)
 add_subdirectory(MacOSX-DYLD)
+add_subdirectory(ModuleList-DYLD)
 add_subdirectory(POSIX-DYLD)
 add_subdirectory(Static)
 add_subdirectory(Hexagon-DYLD)
diff --git a/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt 
b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt
new file mode 100644
index 0000000000000..94d95e3715da1
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginDynamicLoaderDumpWithModuleList PLUGIN
+  DynamicLoaderDumpWithModuleList.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbHost
+    lldbTarget
+    lldbPluginProcessElfCore
+  LINK_COMPONENTS
+    Support
+  )
diff --git 
a/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
 
b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
new file mode 100644
index 0000000000000..3337a69ea80e4
--- /dev/null
+++ 
b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
@@ -0,0 +1,109 @@
+//===-- DynamicLoaderDumpWithModuleList.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
+//
+//===----------------------------------------------------------------------===//
+
+// Main header include
+#include "DynamicLoaderDumpWithModuleList.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+
+#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderDumpWithModuleList,
+                       DynamicLoaderDumpWithModuleList)
+
+void DynamicLoaderDumpWithModuleList::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void DynamicLoaderDumpWithModuleList::Terminate() {}
+
+llvm::StringRef DynamicLoaderDumpWithModuleList::GetPluginDescriptionStatic() {
+  return "Dynamic loader plug-in for dumps with module list available";
+}
+
+DynamicLoader *DynamicLoaderDumpWithModuleList::CreateInstance(Process 
*process,
+                                                               bool force) {
+  // This plug-in is only used when it is requested by name from
+  // ProcessELFCore. ProcessELFCore will look to see if the core
+  // file contains a NT_FILE ELF note, and ask for this plug-in
+  // by name if it does.
+  if (force)
+    return new DynamicLoaderDumpWithModuleList(process);
+  return nullptr;
+}
+
+DynamicLoaderDumpWithModuleList::DynamicLoaderDumpWithModuleList(
+    Process *process)
+    : DynamicLoader(process) {}
+
+DynamicLoaderDumpWithModuleList::~DynamicLoaderDumpWithModuleList() {}
+
+void DynamicLoaderDumpWithModuleList::DidAttach() {
+  Log *log = GetLog(LLDBLog::DynamicLoader);
+  LLDB_LOGF(log, "DynamicLoaderDumpWithModuleList::%s() pid %" PRIu64,
+            __FUNCTION__,
+            m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+  // Curently only used by ProcessELFCore who will return the results of the
+  // NT_FILE list from ProcessELFCore::GetLoadedModuleList.
+  llvm::Expected<LoadedModuleInfoList> module_info_list_ep =
+      m_process->GetLoadedModuleList();
+  if (!module_info_list_ep) {
+    // TODO: log failure.
+    llvm::consumeError(module_info_list_ep.takeError());
+    return;
+  }
+
+  ModuleList module_list;
+  const LoadedModuleInfoList &module_info_list = *module_info_list_ep;
+  for (const LoadedModuleInfoList::LoadedModuleInfo &modInfo :
+       module_info_list.m_list) {
+    addr_t base_addr, module_size;
+    std::string name;
+    if (!modInfo.get_base(base_addr) || !modInfo.get_name(name) ||
+        !modInfo.get_size(module_size))
+      continue;
+
+    addr_t link_map_addr = 0;
+    FileSpec file(name, m_process->GetTarget().GetArchitecture().GetTriple());
+    const bool base_addr_is_offset = false;
+    ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress(
+        file, link_map_addr, base_addr, base_addr_is_offset);
+    if (module_sp.get()) {
+      LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}", name.c_str());
+      module_list.Append(module_sp);
+    } else {
+      Log *log = GetLog(LLDBLog::DynamicLoader);
+      LLDB_LOGF(
+          log,
+          "DynamicLoaderDumpWithModuleList::%s unable to locate the matching "
+          "object file %s, creating a placeholder module at 0x%" PRIx64,
+          __FUNCTION__, name.c_str(), base_addr);
+
+      ModuleSpec module_spec(file, m_process->GetTarget().GetArchitecture());
+      module_sp = Module::CreateModuleFromObjectFile<ObjectFilePlaceholder>(
+          module_spec, base_addr, module_size);
+      UpdateLoadedSections(module_sp, link_map_addr, base_addr,
+                           base_addr_is_offset);
+      m_process->GetTarget().GetImages().Append(module_sp, /*notify*/ true);
+    }
+  }
+  m_process->GetTarget().ModulesDidLoad(module_list);
+}
+
+lldb_private::Status DynamicLoaderDumpWithModuleList::CanLoadImage() {
+  return Status();
+}
diff --git 
a/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h
 
b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h
new file mode 100644
index 0000000000000..30c493bdff999
--- /dev/null
+++ 
b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h
@@ -0,0 +1,75 @@
+//===-- DynamicLoaderDumpWithModuleList.h --------------------------------*- 
C++
+//-*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MODULELIST_DYLD_DYNAMICLOADERDUMPWITHMODULELIST_H
+#define 
LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MODULELIST_DYLD_DYNAMICLOADERDUMPWITHMODULELIST_H
+
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Target/DynamicLoader.h"
+
+/**
+ * Dynamic loader for dump process with module list available.
+ * For example, some coredump files have NT_FILE note section available
+ * so can directly provide the module list without main executable's dynamic
+ * section.
+ */
+class DynamicLoaderDumpWithModuleList : public lldb_private::DynamicLoader {
+public:
+  DynamicLoaderDumpWithModuleList(lldb_private::Process *process);
+
+  ~DynamicLoaderDumpWithModuleList() override;
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static llvm::StringRef GetPluginNameStatic() {
+    return "dump-modulelist-dyld";
+  }
+
+  static llvm::StringRef GetPluginDescriptionStatic();
+
+  static lldb_private::DynamicLoader *
+  CreateInstance(lldb_private::Process *process, bool force);
+
+  // DynamicLoader protocol
+
+  void DidAttach() override;
+
+  void DidLaunch() override {
+    llvm_unreachable(
+        "DynamicLoaderDumpWithModuleList::DidLaunch shouldn't be called");
+  }
+
+  lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+                                                  bool stop_others) override {
+    llvm_unreachable("DynamicLoaderDumpWithModuleList::"
+                     "GetStepThroughTrampolinePlan shouldn't be called");
+  }
+
+  lldb_private::Status CanLoadImage() override;
+
+  lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+                                  const lldb::ThreadSP thread,
+                                  lldb::addr_t tls_file_addr) override {
+    // TODO: how to implement this?
+    return LLDB_INVALID_ADDRESS;
+  }
+
+  // PluginInterface protocol
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+private:
+  DynamicLoaderDumpWithModuleList(const DynamicLoaderDumpWithModuleList &) =
+      delete;
+  const DynamicLoaderDumpWithModuleList &
+  operator=(const DynamicLoaderDumpWithModuleList &) = delete;
+};
+
+#endif // 
LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MODULELIST_DYLD_DYNAMICLOADERDUMPWITHMODULELIST_H
diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt 
b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
index 0bc26bb0efbe3..7c636e88b58f1 100644
--- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -20,6 +20,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
   LINK_LIBS
     lldbCore
     lldbTarget
+    lldbPluginDynamicLoaderDumpWithModuleList
     lldbPluginDynamicLoaderPosixDYLD
     lldbPluginObjectFileELF
     lldbPluginProcessUtility
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp 
b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 88eeddf178788..a0402dde5594a 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -11,6 +11,7 @@
 #include <memory>
 #include <mutex>
 
+#include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
@@ -28,6 +29,7 @@
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Support/Threading.h"
 
+#include 
"Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h"
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 #include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -295,12 +297,53 @@ UUID ProcessElfCore::FindModuleUUID(const llvm::StringRef 
path) {
 }
 
 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
-  if (m_dyld_up.get() == nullptr)
-    m_dyld_up.reset(DynamicLoader::FindPlugin(
-        this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic()));
+  if (m_dyld_up.get() == nullptr) {
+    if (GetTarget().GetDebugger().GetUseModuleListDyld()) {
+      llvm::Expected<LoadedModuleInfoList> module_info_list_ep =
+          GetLoadedModuleList();
+      if (module_info_list_ep && !(*module_info_list_ep).m_list.empty())
+        m_dyld_up.reset(DynamicLoader::FindPlugin(
+            this, DynamicLoaderDumpWithModuleList::GetPluginNameStatic()));
+    }
+
+    if (m_dyld_up.get() == nullptr)
+      m_dyld_up.reset(DynamicLoader::FindPlugin(
+          this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic()));
+  }
   return m_dyld_up.get();
 }
 
+llvm::Expected<lldb_private::LoadedModuleInfoList>
+ProcessElfCore::GetLoadedModuleList() {
+  if (m_module_info_list.m_list.empty()) {
+    std::unordered_map<std::string, std::pair<lldb::addr_t, lldb::addr_t>>
+        module_range_map;
+    for (const NT_FILE_Entry &file_entry : m_nt_file_entries) {
+      const std::string& module_path = file_entry.path;
+      auto module_iter = module_range_map.find(module_path);
+      if (module_iter == module_range_map.end() ||
+          module_iter->second.first > file_entry.start)
+        module_range_map[module_path] =
+            std::make_pair(file_entry.start, file_entry.end - 
file_entry.start);
+      else {
+        // Expand module's range to include later sections.
+        auto &module_range = module_range_map[module_path];
+        assert(file_entry.end >= module_range.first);
+        module_range.second = file_entry.end - module_range.first;
+      }
+    }
+
+    for (const auto &module_range_entry : module_range_map) {
+      LoadedModuleInfoList::LoadedModuleInfo module;
+      module.set_name(module_range_entry.first);
+      module.set_base(module_range_entry.second.first);
+      module.set_size(module_range_entry.second.second);
+      m_module_info_list.add(module);
+    }
+  }
+  return m_module_info_list;
+}
+
 bool ProcessElfCore::DoUpdateThreadList(ThreadList &old_thread_list,
                                         ThreadList &new_thread_list) {
   const uint32_t num_threads = GetNumThreadContexts();
@@ -406,7 +449,7 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void 
*buf, size_t size,
   const lldb::addr_t file_start = address_range->data.GetRangeBase();
   const lldb::addr_t file_end = address_range->data.GetRangeEnd();
   size_t bytes_to_read = size; // Number of bytes to read from the core file
-  size_t bytes_copied = 0;   // Number of bytes actually read from the core 
file
+  size_t bytes_copied = 0; // Number of bytes actually read from the core file
   lldb::addr_t bytes_left =
       0; // Number of bytes available in the core file from the given address
 
@@ -489,8 +532,7 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
 
 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
 static void ParseFreeBSDPrStatus(ThreadData &thread_data,
-                                 const DataExtractor &data,
-                                 bool lp64) {
+                                 const DataExtractor &data, bool lp64) {
   lldb::offset_t offset = 0;
   int pr_version = data.GetU32(&offset);
 
@@ -517,8 +559,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data,
 
 // Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details.
 static void ParseFreeBSDPrPsInfo(ProcessElfCore &process,
-                                 const DataExtractor &data,
-                                 bool lp64) {
+                                 const DataExtractor &data, bool lp64) {
   lldb::offset_t offset = 0;
   int pr_version = data.GetU32(&offset);
 
@@ -537,8 +578,7 @@ static void ParseFreeBSDPrPsInfo(ProcessElfCore &process,
 }
 
 static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data,
-                                       uint32_t &cpi_nlwps,
-                                       uint32_t &cpi_signo,
+                                       uint32_t &cpi_nlwps, uint32_t 
&cpi_signo,
                                        uint32_t &cpi_siglwp,
                                        uint32_t &cpi_pid) {
   lldb::offset_t offset = 0;
@@ -706,8 +746,8 @@ llvm::Error 
ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
 
     if (name == "NetBSD-CORE") {
       if (note.info.n_type == NETBSD::NT_PROCINFO) {
-        llvm::Error error = ParseNetBSDProcInfo(note.data, nlwps, signo,
-                                                siglwp, pr_pid);
+        llvm::Error error =
+            ParseNetBSDProcInfo(note.data, nlwps, signo, siglwp, pr_pid);
         if (error)
           return error;
         SetID(pr_pid);
@@ -933,7 +973,9 @@ llvm::Error 
ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
       Status status = prpsinfo.Parse(note.data, arch);
       if (status.Fail())
         return status.ToError();
-      thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, 
sizeof (prpsinfo.pr_fname)));
+      thread_data.name.assign(
+          prpsinfo.pr_fname,
+          strnlen(prpsinfo.pr_fname, sizeof(prpsinfo.pr_fname)));
       SetID(prpsinfo.pr_pid);
       break;
     }
@@ -987,7 +1029,7 @@ llvm::Error 
ProcessElfCore::ParseThreadContextsFromNoteSegment(
   assert(segment_header.p_type == llvm::ELF::PT_NOTE);
 
   auto notes_or_error = parseSegment(segment_data);
-  if(!notes_or_error)
+  if (!notes_or_error)
     return notes_or_error.takeError();
   switch (GetArchitecture().GetTriple().getOS()) {
   case llvm::Triple::FreeBSD:
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h 
b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index a91c04a277f60..cbfa366e90204 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -19,6 +19,7 @@
 #include <list>
 #include <vector>
 
+#include "lldb/Core/LoadedModuleInfoList.h"
 #include "lldb/Target/PostMortemProcess.h"
 #include "lldb/Utility/Status.h"
 
@@ -74,6 +75,9 @@ class ProcessElfCore : public lldb_private::PostMortemProcess 
{
   // Process Queries
   bool IsAlive() override;
 
+  llvm::Expected<lldb_private::LoadedModuleInfoList>
+  GetLoadedModuleList() override;
+
   bool WarnBeforeDetach() const override { return false; }
 
   // Process Memory
@@ -152,6 +156,8 @@ class ProcessElfCore : public 
lldb_private::PostMortemProcess {
   // NT_FILE entries found from the NOTE segment
   std::vector<NT_FILE_Entry> m_nt_file_entries;
 
+  lldb_private::LoadedModuleInfoList m_module_info_list;
+
   // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE 
segment
   llvm::Error ParseThreadContextsFromNoteSegment(
       const elf::ELFProgramHeader &segment_header,

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to