1 //===-- ProcessElfCore.h ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 // Notes about Linux Process core dumps:
9 //  1) Linux core dump is stored as ELF file.
10 //  2) The ELF file's PT_NOTE and PT_LOAD segments describes the program's
11 //     address space and thread contexts.
12 //  3) PT_NOTE segment contains note entries which describes a thread context.
13 //  4) PT_LOAD segment describes a valid contiguous range of process address
14 //     space.
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef liblldb_ProcessElfCore_h_
18 #define liblldb_ProcessElfCore_h_
19 
20 #include <list>
21 #include <vector>
22 
23 #include "lldb/Target/Process.h"
24 #include "lldb/Utility/ConstString.h"
25 #include "lldb/Utility/Status.h"
26 
27 #include "Plugins/ObjectFile/ELF/ELFHeader.h"
28 #include "Plugins/Process/elf-core/RegisterUtilities.h"
29 
30 struct ThreadData;
31 
32 class ProcessElfCore : public lldb_private::Process {
33 public:
34   //------------------------------------------------------------------
35   // Constructors and Destructors
36   //------------------------------------------------------------------
37   static lldb::ProcessSP
38   CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
39                  const lldb_private::FileSpec *crash_file_path);
40 
41   static void Initialize();
42 
43   static void Terminate();
44 
45   static lldb_private::ConstString GetPluginNameStatic();
46 
47   static const char *GetPluginDescriptionStatic();
48 
49   //------------------------------------------------------------------
50   // Constructors and Destructors
51   //------------------------------------------------------------------
52   ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
53                  const lldb_private::FileSpec &core_file);
54 
55   ~ProcessElfCore() override;
56 
57   //------------------------------------------------------------------
58   // Check if a given Process
59   //------------------------------------------------------------------
60   bool CanDebug(lldb::TargetSP target_sp,
61                 bool plugin_specified_by_name) override;
62 
63   //------------------------------------------------------------------
64   // Creating a new process, or attaching to an existing one
65   //------------------------------------------------------------------
66   lldb_private::Status DoLoadCore() override;
67 
68   lldb_private::DynamicLoader *GetDynamicLoader() override;
69 
70   //------------------------------------------------------------------
71   // PluginInterface protocol
72   //------------------------------------------------------------------
73   lldb_private::ConstString GetPluginName() override;
74 
75   uint32_t GetPluginVersion() override;
76 
77   //------------------------------------------------------------------
78   // Process Control
79   //------------------------------------------------------------------
80   lldb_private::Status DoDestroy() override;
81 
82   void RefreshStateAfterStop() override;
83 
84   lldb_private::Status WillResume() override {
85     lldb_private::Status error;
86     error.SetErrorStringWithFormat(
87         "error: %s does not support resuming processes",
88         GetPluginName().GetCString());
89     return error;
90   }
91 
92   //------------------------------------------------------------------
93   // Process Queries
94   //------------------------------------------------------------------
95   bool IsAlive() override;
96 
97   bool WarnBeforeDetach() const override { return false; }
98 
99   //------------------------------------------------------------------
100   // Process Memory
101   //------------------------------------------------------------------
102   size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
103                     lldb_private::Status &error) override;
104 
105   size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
106                       lldb_private::Status &error) override;
107 
108   lldb_private::Status
109   GetMemoryRegionInfo(lldb::addr_t load_addr,
110                       lldb_private::MemoryRegionInfo &region_info) override;
111 
112   lldb::addr_t GetImageInfoAddress() override;
113 
114   lldb_private::ArchSpec GetArchitecture();
115 
116   // Returns AUXV structure found in the core file
117   const lldb::DataBufferSP GetAuxvData() override;
118 
119   bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
120 
121 protected:
122   void Clear();
123 
124   bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
125                         lldb_private::ThreadList &new_thread_list) override;
126 
127 private:
128   struct NT_FILE_Entry {
129     lldb::addr_t start;
130     lldb::addr_t end;
131     lldb::addr_t file_ofs;
132     lldb_private::ConstString path;
133   };
134 
135   //------------------------------------------------------------------
136   // For ProcessElfCore only
137   //------------------------------------------------------------------
138   typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
139   typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1>
140       VMRangeToFileOffset;
141   typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
142       VMRangeToPermissions;
143 
144   lldb::ModuleSP m_core_module_sp;
145   lldb_private::FileSpec m_core_file;
146   std::string m_dyld_plugin_name;
147   DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);
148 
149   // True if m_thread_contexts contains valid entries
150   bool m_thread_data_valid = false;
151 
152   // Contain thread data read from NOTE segments
153   std::vector<ThreadData> m_thread_data;
154 
155   // AUXV structure found from the NOTE segment
156   lldb_private::DataExtractor m_auxv;
157 
158   // Address ranges found in the core
159   VMRangeToFileOffset m_core_aranges;
160 
161   // Permissions for all ranges
162   VMRangeToPermissions m_core_range_infos;
163 
164   // NT_FILE entries found from the NOTE segment
165   std::vector<NT_FILE_Entry> m_nt_file_entries;
166 
167   // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
168   llvm::Error ParseThreadContextsFromNoteSegment(
169       const elf::ELFProgramHeader *segment_header,
170       lldb_private::DataExtractor segment_data);
171 
172   // Returns number of thread contexts stored in the core file
173   uint32_t GetNumThreadContexts();
174 
175   // Parse a contiguous address range of the process from LOAD segment
176   lldb::addr_t
177   AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
178 
179   llvm::Expected<std::vector<lldb_private::CoreNote>>
180   parseSegment(const lldb_private::DataExtractor &segment);
181   llvm::Error parseFreeBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
182   llvm::Error parseNetBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
183   llvm::Error parseOpenBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
184   llvm::Error parseLinuxNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
185 };
186 
187 #endif // liblldb_ProcessElfCore_h_
188