xref: /llvm-project/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h (revision 0123cefc00177e4fc7daa0dadf98ca8336760785)
1 //===-- ProcessMachCore.h ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_PROCESSMACHCORE_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_PROCESSMACHCORE_H
11 
12 #include <list>
13 #include <vector>
14 
15 #include "lldb/Target/PostMortemProcess.h"
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/Utility/Status.h"
18 
19 class ThreadKDP;
20 
21 class ProcessMachCore : public lldb_private::PostMortemProcess {
22 public:
23   // Constructors and Destructors
24   ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener,
25                   const lldb_private::FileSpec &core_file);
26 
27   ~ProcessMachCore() override;
28 
29   static lldb::ProcessSP
30   CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
31                  const lldb_private::FileSpec *crash_file_path,
32                  bool can_connect);
33 
34   static void Initialize();
35 
36   static void Terminate();
37 
GetPluginNameStatic()38   static llvm::StringRef GetPluginNameStatic() { return "mach-o-core"; }
39 
40   static llvm::StringRef GetPluginDescriptionStatic();
41 
42   // Check if a given Process
43   bool CanDebug(lldb::TargetSP target_sp,
44                 bool plugin_specified_by_name) override;
45 
46   // Creating a new process, or attaching to an existing one
47   lldb_private::Status DoLoadCore() override;
48 
49   lldb_private::DynamicLoader *GetDynamicLoader() override;
50 
51   // PluginInterface protocol
GetPluginName()52   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
53 
54   // Process Control
55   lldb_private::Status DoDestroy() override;
56 
57   void RefreshStateAfterStop() override;
58 
59   // Process Queries
60   bool IsAlive() override;
61 
62   bool WarnBeforeDetach() const override;
63 
64   // Process Memory
65   size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
66                     lldb_private::Status &error) override;
67 
68   size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
69                       lldb_private::Status &error) override;
70 
71   lldb::addr_t GetImageInfoAddress() override;
72 
73 protected:
74   friend class ThreadMachCore;
75 
76   void Clear();
77 
78   bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
79                           lldb_private::ThreadList &new_thread_list) override;
80 
81   lldb_private::ObjectFile *GetCoreObjectFile();
82 
83   lldb_private::Status
84   DoGetMemoryRegionInfo(lldb::addr_t load_addr,
85                         lldb_private::MemoryRegionInfo &region_info) override;
86 
87 private:
88   void CreateMemoryRegions();
89 
90   bool LoadBinaryViaLowmemUUID();
91 
92   /// \return
93   ///   True if any metadata were found indicating the binary that should
94   ///   be loaded, regardless of whether the specified binary could be found.
95   ///   False if no metadata were present.
96   bool LoadBinariesViaMetadata();
97 
98   void LoadBinariesViaExhaustiveSearch();
99   void LoadBinariesAndSetDYLD();
100   void CleanupMemoryRegionPermissions();
101 
102   bool CheckAddressForDyldOrKernel(lldb::addr_t addr, lldb::addr_t &dyld,
103                                    lldb::addr_t &kernel);
104 
105   enum CorefilePreference { eUserProcessCorefile, eKernelCorefile };
106 
107   /// If a core file can be interpreted multiple ways, this establishes
108   /// which style wins.
109   ///
110   /// If a core file contains both a kernel binary and a user-process
111   /// dynamic loader, lldb needs to pick one over the other.  This could
112   /// be a kernel corefile that happens to have a copy of dyld in its
113   /// memory.  Or it could be a user process coredump of lldb while doing
114   /// kernel debugging - so a copy of the kernel is in its heap.  This
115   /// should become a setting so it can be over-ridden when necessary.
GetCorefilePreference()116   CorefilePreference GetCorefilePreference() {
117     // For now, if both user process and kernel binaries a present,
118     // assume this is a kernel coredump which has a copy of a user
119     // process dyld in one of its pages.
120     return eKernelCorefile;
121   }
122 
123   // For ProcessMachCore only
124   typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
125   typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange>
126       VMRangeToFileOffset;
127   typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
128       VMRangeToPermissions;
129 
130   VMRangeToFileOffset m_core_aranges;
131   VMRangeToPermissions m_core_range_infos;
132   lldb::ModuleSP m_core_module_sp;
133   lldb::addr_t m_dyld_addr;
134   lldb::addr_t m_mach_kernel_addr;
135   llvm::StringRef m_dyld_plugin_name;
136 };
137 
138 #endif // LLDB_SOURCE_PLUGINS_PROCESS_MACH_CORE_PROCESSMACHCORE_H
139