1 //===-- ProcessElfCore.h ----------------------------------------*- C++ -*-===//
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
7 // Notes about Linux Process core dumps:
8 // 1) Linux core dump is stored as ELF file.
9 // 2) The ELF file's PT_NOTE and PT_LOAD segments describes the program's
10 // address space and thread contexts.
11 // 3) PT_NOTE segment contains note entries which describes a thread context.
12 // 4) PT_LOAD segment describes a valid contiguous range of process address
14 //===----------------------------------------------------------------------===//
16 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H
17 #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H
22 #include "lldb/Target/PostMortemProcess.h"
23 #include "lldb/Utility/Status.h"
25 #include "Plugins/ObjectFile/ELF/ELFHeader.h"
26 #include "Plugins/Process/elf-core/RegisterUtilities.h"
30 class ProcessElfCore
: public lldb_private::PostMortemProcess
{
32 // Constructors and Destructors
33 static lldb::ProcessSP
34 CreateInstance(lldb::TargetSP target_sp
, lldb::ListenerSP listener_sp
,
35 const lldb_private::FileSpec
*crash_file_path
,
38 static void Initialize();
40 static void Terminate();
42 static llvm::StringRef
GetPluginNameStatic() { return "elf-core"; }
44 static llvm::StringRef
GetPluginDescriptionStatic();
46 // Constructors and Destructors
47 ProcessElfCore(lldb::TargetSP target_sp
, lldb::ListenerSP listener_sp
,
48 const lldb_private::FileSpec
&core_file
);
50 ~ProcessElfCore() override
;
52 // Check if a given Process
53 bool CanDebug(lldb::TargetSP target_sp
,
54 bool plugin_specified_by_name
) override
;
56 // Creating a new process, or attaching to an existing one
57 lldb_private::Status
DoLoadCore() override
;
59 lldb_private::DynamicLoader
*GetDynamicLoader() override
;
61 // PluginInterface protocol
62 llvm::StringRef
GetPluginName() override
{ return GetPluginNameStatic(); }
65 lldb_private::Status
DoDestroy() override
;
67 void RefreshStateAfterStop() override
;
69 lldb_private::Status
WillResume() override
{
70 lldb_private::Status error
;
71 error
.SetErrorStringWithFormatv(
72 "error: {0} does not support resuming processes", GetPluginName());
77 bool IsAlive() override
;
79 bool WarnBeforeDetach() const override
{ return false; }
82 size_t ReadMemory(lldb::addr_t addr
, void *buf
, size_t size
,
83 lldb_private::Status
&error
) override
;
85 size_t DoReadMemory(lldb::addr_t addr
, void *buf
, size_t size
,
86 lldb_private::Status
&error
) override
;
88 // We do not implement DoReadMemoryTags. Instead all the work is done in
89 // ReadMemoryTags which avoids having to unpack and repack tags.
90 llvm::Expected
<std::vector
<lldb::addr_t
>> ReadMemoryTags(lldb::addr_t addr
,
93 lldb::addr_t
GetImageInfoAddress() override
;
95 lldb_private::ArchSpec
GetArchitecture();
97 // Returns AUXV structure found in the core file
98 lldb_private::DataExtractor
GetAuxvData() override
;
100 bool GetProcessInfo(lldb_private::ProcessInstanceInfo
&info
) override
;
105 bool DoUpdateThreadList(lldb_private::ThreadList
&old_thread_list
,
106 lldb_private::ThreadList
&new_thread_list
) override
;
109 DoGetMemoryRegionInfo(lldb::addr_t load_addr
,
110 lldb_private::MemoryRegionInfo
®ion_info
) override
;
112 bool SupportsMemoryTagging() override
{ return !m_core_tag_ranges
.IsEmpty(); }
115 struct NT_FILE_Entry
{
118 lldb::addr_t file_ofs
;
122 // For ProcessElfCore only
123 typedef lldb_private::Range
<lldb::addr_t
, lldb::addr_t
> FileRange
;
124 typedef lldb_private::RangeDataVector
<lldb::addr_t
, lldb::addr_t
, FileRange
>
126 typedef lldb_private::RangeDataVector
<lldb::addr_t
, lldb::addr_t
, uint32_t>
127 VMRangeToPermissions
;
129 lldb::ModuleSP m_core_module_sp
;
130 lldb_private::FileSpec m_core_file
;
131 std::string m_dyld_plugin_name
;
133 // True if m_thread_contexts contains valid entries
134 bool m_thread_data_valid
= false;
136 // Contain thread data read from NOTE segments
137 std::vector
<ThreadData
> m_thread_data
;
139 // AUXV structure found from the NOTE segment
140 lldb_private::DataExtractor m_auxv
;
142 // Address ranges found in the core
143 VMRangeToFileOffset m_core_aranges
;
145 // Permissions for all ranges
146 VMRangeToPermissions m_core_range_infos
;
148 // Memory tag ranges found in the core
149 VMRangeToFileOffset m_core_tag_ranges
;
151 // NT_FILE entries found from the NOTE segment
152 std::vector
<NT_FILE_Entry
> m_nt_file_entries
;
154 // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
155 llvm::Error
ParseThreadContextsFromNoteSegment(
156 const elf::ELFProgramHeader
&segment_header
,
157 const lldb_private::DataExtractor
&segment_data
);
159 // Returns number of thread contexts stored in the core file
160 uint32_t GetNumThreadContexts();
162 // Parse a contiguous address range of the process from LOAD segment
164 AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader
&header
);
166 // Parse a contiguous address range from a memory tag segment
168 AddAddressRangeFromMemoryTagSegment(const elf::ELFProgramHeader
&header
);
170 llvm::Expected
<std::vector
<lldb_private::CoreNote
>>
171 parseSegment(const lldb_private::DataExtractor
&segment
);
172 llvm::Error
parseFreeBSDNotes(llvm::ArrayRef
<lldb_private::CoreNote
> notes
);
173 llvm::Error
parseNetBSDNotes(llvm::ArrayRef
<lldb_private::CoreNote
> notes
);
174 llvm::Error
parseOpenBSDNotes(llvm::ArrayRef
<lldb_private::CoreNote
> notes
);
175 llvm::Error
parseLinuxNotes(llvm::ArrayRef
<lldb_private::CoreNote
> notes
);
178 #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H