1 //===-- ProcessElfCore.cpp ------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Target/ABI.h"
19 #include "lldb/Target/DynamicLoader.h"
20 #include "lldb/Target/MemoryRegionInfo.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/UnixSignals.h"
23 #include "lldb/Utility/DataBufferHeap.h"
24 #include "lldb/Utility/LLDBLog.h"
25 #include "lldb/Utility/Log.h"
26 #include "lldb/Utility/State.h"
28 #include "llvm/BinaryFormat/ELF.h"
29 #include "llvm/Support/Threading.h"
31 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
32 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
33 #include "Plugins/Process/elf-core/RegisterUtilities.h"
34 #include "ProcessElfCore.h"
35 #include "ThreadElfCore.h"
37 using namespace lldb_private
;
38 namespace ELF
= llvm::ELF
;
40 LLDB_PLUGIN_DEFINE(ProcessElfCore
)
42 llvm::StringRef
ProcessElfCore::GetPluginDescriptionStatic() {
43 return "ELF core dump plug-in.";
46 void ProcessElfCore::Terminate() {
47 PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance
);
50 lldb::ProcessSP
ProcessElfCore::CreateInstance(lldb::TargetSP target_sp
,
51 lldb::ListenerSP listener_sp
,
52 const FileSpec
*crash_file
,
54 lldb::ProcessSP process_sp
;
55 if (crash_file
&& !can_connect
) {
56 // Read enough data for an ELF32 header or ELF64 header Note: Here we care
57 // about e_type field only, so it is safe to ignore possible presence of
58 // the header extension.
59 const size_t header_size
= sizeof(llvm::ELF::Elf64_Ehdr
);
61 auto data_sp
= FileSystem::Instance().CreateDataBuffer(
62 crash_file
->GetPath(), header_size
, 0);
63 if (data_sp
&& data_sp
->GetByteSize() == header_size
&&
64 elf::ELFHeader::MagicBytesMatch(data_sp
->GetBytes())) {
65 elf::ELFHeader elf_header
;
66 DataExtractor
data(data_sp
, lldb::eByteOrderLittle
, 4);
67 lldb::offset_t data_offset
= 0;
68 if (elf_header
.Parse(data
, &data_offset
)) {
69 // Check whether we're dealing with a raw FreeBSD "full memory dump"
70 // ELF vmcore that needs to be handled via FreeBSDKernel plugin instead.
71 if (elf_header
.e_ident
[7] == 0xFF && elf_header
.e_version
== 0)
73 if (elf_header
.e_type
== llvm::ELF::ET_CORE
)
74 process_sp
= std::make_shared
<ProcessElfCore
>(target_sp
, listener_sp
,
82 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp
,
83 bool plugin_specified_by_name
) {
84 // For now we are just making sure the file exists for a given module
85 if (!m_core_module_sp
&& FileSystem::Instance().Exists(m_core_file
)) {
86 ModuleSpec
core_module_spec(m_core_file
, target_sp
->GetArchitecture());
87 Status
error(ModuleList::GetSharedModule(core_module_spec
, m_core_module_sp
,
88 nullptr, nullptr, nullptr));
89 if (m_core_module_sp
) {
90 ObjectFile
*core_objfile
= m_core_module_sp
->GetObjectFile();
91 if (core_objfile
&& core_objfile
->GetType() == ObjectFile::eTypeCoreFile
)
98 // ProcessElfCore constructor
99 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp
,
100 lldb::ListenerSP listener_sp
,
101 const FileSpec
&core_file
)
102 : PostMortemProcess(target_sp
, listener_sp
), m_core_file(core_file
) {}
105 ProcessElfCore::~ProcessElfCore() {
107 // We need to call finalize on the process before destroying ourselves to
108 // make sure all of the broadcaster cleanup goes as planned. If we destruct
109 // this class, then Process::~Process() might have problems trying to fully
110 // destroy the broadcaster.
114 lldb::addr_t
ProcessElfCore::AddAddressRangeFromLoadSegment(
115 const elf::ELFProgramHeader
&header
) {
116 const lldb::addr_t addr
= header
.p_vaddr
;
117 FileRange
file_range(header
.p_offset
, header
.p_filesz
);
118 VMRangeToFileOffset::Entry
range_entry(addr
, header
.p_memsz
, file_range
);
120 // Only add to m_core_aranges if the file size is non zero. Some core files
121 // have PT_LOAD segments for all address ranges, but set f_filesz to zero for
122 // the .text sections since they can be retrieved from the object files.
123 if (header
.p_filesz
> 0) {
124 VMRangeToFileOffset::Entry
*last_entry
= m_core_aranges
.Back();
125 if (last_entry
&& last_entry
->GetRangeEnd() == range_entry
.GetRangeBase() &&
126 last_entry
->data
.GetRangeEnd() == range_entry
.data
.GetRangeBase() &&
127 last_entry
->GetByteSize() == last_entry
->data
.GetByteSize()) {
128 last_entry
->SetRangeEnd(range_entry
.GetRangeEnd());
129 last_entry
->data
.SetRangeEnd(range_entry
.data
.GetRangeEnd());
131 m_core_aranges
.Append(range_entry
);
134 // Keep a separate map of permissions that isn't coalesced so all ranges
136 const uint32_t permissions
=
137 ((header
.p_flags
& llvm::ELF::PF_R
) ? lldb::ePermissionsReadable
: 0u) |
138 ((header
.p_flags
& llvm::ELF::PF_W
) ? lldb::ePermissionsWritable
: 0u) |
139 ((header
.p_flags
& llvm::ELF::PF_X
) ? lldb::ePermissionsExecutable
: 0u);
141 m_core_range_infos
.Append(
142 VMRangeToPermissions::Entry(addr
, header
.p_memsz
, permissions
));
147 lldb::addr_t
ProcessElfCore::AddAddressRangeFromMemoryTagSegment(
148 const elf::ELFProgramHeader
&header
) {
149 // If lldb understood multiple kinds of tag segments we would record the type
150 // of the segment here also. As long as there is only 1 type lldb looks for,
152 FileRange
file_range(header
.p_offset
, header
.p_filesz
);
153 m_core_tag_ranges
.Append(
154 VMRangeToFileOffset::Entry(header
.p_vaddr
, header
.p_memsz
, file_range
));
156 return header
.p_vaddr
;
160 Status
ProcessElfCore::DoLoadCore() {
162 if (!m_core_module_sp
) {
163 error
.SetErrorString("invalid core module");
167 ObjectFileELF
*core
= (ObjectFileELF
*)(m_core_module_sp
->GetObjectFile());
168 if (core
== nullptr) {
169 error
.SetErrorString("invalid core object file");
173 llvm::ArrayRef
<elf::ELFProgramHeader
> segments
= core
->ProgramHeaders();
174 if (segments
.size() == 0) {
175 error
.SetErrorString("core file has no segments");
181 m_thread_data_valid
= true;
183 bool ranges_are_sorted
= true;
184 lldb::addr_t vm_addr
= 0;
185 lldb::addr_t tag_addr
= 0;
186 /// Walk through segments and Thread and Address Map information.
187 /// PT_NOTE - Contains Thread and Register information
188 /// PT_LOAD - Contains a contiguous range of Process Address Space
189 /// PT_AARCH64_MEMTAG_MTE - Contains AArch64 MTE memory tags for a range of
190 /// Process Address Space.
191 for (const elf::ELFProgramHeader
&H
: segments
) {
192 DataExtractor data
= core
->GetSegmentData(H
);
194 // Parse thread contexts and auxv structure
195 if (H
.p_type
== llvm::ELF::PT_NOTE
) {
196 if (llvm::Error error
= ParseThreadContextsFromNoteSegment(H
, data
))
197 return Status(std::move(error
));
199 // PT_LOAD segments contains address map
200 if (H
.p_type
== llvm::ELF::PT_LOAD
) {
201 lldb::addr_t last_addr
= AddAddressRangeFromLoadSegment(H
);
202 if (vm_addr
> last_addr
)
203 ranges_are_sorted
= false;
205 } else if (H
.p_type
== llvm::ELF::PT_AARCH64_MEMTAG_MTE
) {
206 lldb::addr_t last_addr
= AddAddressRangeFromMemoryTagSegment(H
);
207 if (tag_addr
> last_addr
)
208 ranges_are_sorted
= false;
209 tag_addr
= last_addr
;
213 if (!ranges_are_sorted
) {
214 m_core_aranges
.Sort();
215 m_core_range_infos
.Sort();
216 m_core_tag_ranges
.Sort();
219 // Even if the architecture is set in the target, we need to override it to
220 // match the core file which is always single arch.
221 ArchSpec
arch(m_core_module_sp
->GetArchitecture());
223 ArchSpec target_arch
= GetTarget().GetArchitecture();
224 ArchSpec
core_arch(m_core_module_sp
->GetArchitecture());
225 target_arch
.MergeFrom(core_arch
);
226 GetTarget().SetArchitecture(target_arch
);
228 SetUnixSignals(UnixSignals::Create(GetArchitecture()));
230 // Ensure we found at least one thread that was stopped on a signal.
231 bool siginfo_signal_found
= false;
232 bool prstatus_signal_found
= false;
233 // Check we found a signal in a SIGINFO note.
234 for (const auto &thread_data
: m_thread_data
) {
235 if (thread_data
.signo
!= 0)
236 siginfo_signal_found
= true;
237 if (thread_data
.prstatus_sig
!= 0)
238 prstatus_signal_found
= true;
240 if (!siginfo_signal_found
) {
241 // If we don't have signal from SIGINFO use the signal from each threads
243 if (prstatus_signal_found
) {
244 for (auto &thread_data
: m_thread_data
)
245 thread_data
.signo
= thread_data
.prstatus_sig
;
246 } else if (m_thread_data
.size() > 0) {
247 // If all else fails force the first thread to be SIGSTOP
248 m_thread_data
.begin()->signo
=
249 GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
253 // Core files are useless without the main executable. See if we can locate
254 // the main executable using data we found in the core file notes.
255 lldb::ModuleSP exe_module_sp
= GetTarget().GetExecutableModule();
256 if (!exe_module_sp
) {
257 // The first entry in the NT_FILE might be our executable
258 if (!m_nt_file_entries
.empty()) {
259 ModuleSpec exe_module_spec
;
260 exe_module_spec
.GetArchitecture() = arch
;
261 exe_module_spec
.GetFileSpec().SetFile(m_nt_file_entries
[0].path
,
262 FileSpec::Style::native
);
263 if (exe_module_spec
.GetFileSpec()) {
264 exe_module_sp
= GetTarget().GetOrCreateModule(exe_module_spec
,
267 GetTarget().SetExecutableModule(exe_module_sp
, eLoadDependentsNo
);
274 lldb_private::DynamicLoader
*ProcessElfCore::GetDynamicLoader() {
275 if (m_dyld_up
.get() == nullptr)
276 m_dyld_up
.reset(DynamicLoader::FindPlugin(
277 this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic()));
278 return m_dyld_up
.get();
281 bool ProcessElfCore::DoUpdateThreadList(ThreadList
&old_thread_list
,
282 ThreadList
&new_thread_list
) {
283 const uint32_t num_threads
= GetNumThreadContexts();
284 if (!m_thread_data_valid
)
287 for (lldb::tid_t tid
= 0; tid
< num_threads
; ++tid
) {
288 const ThreadData
&td
= m_thread_data
[tid
];
289 lldb::ThreadSP
thread_sp(new ThreadElfCore(*this, td
));
290 new_thread_list
.AddThread(thread_sp
);
292 return new_thread_list
.GetSize(false) > 0;
295 void ProcessElfCore::RefreshStateAfterStop() {}
297 Status
ProcessElfCore::DoDestroy() { return Status(); }
301 bool ProcessElfCore::IsAlive() { return true; }
304 size_t ProcessElfCore::ReadMemory(lldb::addr_t addr
, void *buf
, size_t size
,
306 if (lldb::ABISP abi_sp
= GetABI())
307 addr
= abi_sp
->FixAnyAddress(addr
);
309 // Don't allow the caching that lldb_private::Process::ReadMemory does since
310 // in core files we have it all cached our our core file anyway.
311 return DoReadMemory(addr
, buf
, size
, error
);
314 Status
ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr
,
315 MemoryRegionInfo
®ion_info
) {
317 const VMRangeToPermissions::Entry
*permission_entry
=
318 m_core_range_infos
.FindEntryThatContainsOrFollows(load_addr
);
319 if (permission_entry
) {
320 if (permission_entry
->Contains(load_addr
)) {
321 region_info
.GetRange().SetRangeBase(permission_entry
->GetRangeBase());
322 region_info
.GetRange().SetRangeEnd(permission_entry
->GetRangeEnd());
323 const Flags
permissions(permission_entry
->data
);
324 region_info
.SetReadable(permissions
.Test(lldb::ePermissionsReadable
)
325 ? MemoryRegionInfo::eYes
326 : MemoryRegionInfo::eNo
);
327 region_info
.SetWritable(permissions
.Test(lldb::ePermissionsWritable
)
328 ? MemoryRegionInfo::eYes
329 : MemoryRegionInfo::eNo
);
330 region_info
.SetExecutable(permissions
.Test(lldb::ePermissionsExecutable
)
331 ? MemoryRegionInfo::eYes
332 : MemoryRegionInfo::eNo
);
333 region_info
.SetMapped(MemoryRegionInfo::eYes
);
335 // A region is memory tagged if there is a memory tag segment that covers
336 // the exact same range.
337 region_info
.SetMemoryTagged(MemoryRegionInfo::eNo
);
338 const VMRangeToFileOffset::Entry
*tag_entry
=
339 m_core_tag_ranges
.FindEntryStartsAt(permission_entry
->GetRangeBase());
341 tag_entry
->GetRangeEnd() == permission_entry
->GetRangeEnd())
342 region_info
.SetMemoryTagged(MemoryRegionInfo::eYes
);
343 } else if (load_addr
< permission_entry
->GetRangeBase()) {
344 region_info
.GetRange().SetRangeBase(load_addr
);
345 region_info
.GetRange().SetRangeEnd(permission_entry
->GetRangeBase());
346 region_info
.SetReadable(MemoryRegionInfo::eNo
);
347 region_info
.SetWritable(MemoryRegionInfo::eNo
);
348 region_info
.SetExecutable(MemoryRegionInfo::eNo
);
349 region_info
.SetMapped(MemoryRegionInfo::eNo
);
350 region_info
.SetMemoryTagged(MemoryRegionInfo::eNo
);
355 region_info
.GetRange().SetRangeBase(load_addr
);
356 region_info
.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS
);
357 region_info
.SetReadable(MemoryRegionInfo::eNo
);
358 region_info
.SetWritable(MemoryRegionInfo::eNo
);
359 region_info
.SetExecutable(MemoryRegionInfo::eNo
);
360 region_info
.SetMapped(MemoryRegionInfo::eNo
);
361 region_info
.SetMemoryTagged(MemoryRegionInfo::eNo
);
365 size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr
, void *buf
, size_t size
,
367 ObjectFile
*core_objfile
= m_core_module_sp
->GetObjectFile();
369 if (core_objfile
== nullptr)
372 // Get the address range
373 const VMRangeToFileOffset::Entry
*address_range
=
374 m_core_aranges
.FindEntryThatContains(addr
);
375 if (address_range
== nullptr || address_range
->GetRangeEnd() < addr
) {
376 error
.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64
,
381 // Convert the address into core file offset
382 const lldb::addr_t offset
= addr
- address_range
->GetRangeBase();
383 const lldb::addr_t file_start
= address_range
->data
.GetRangeBase();
384 const lldb::addr_t file_end
= address_range
->data
.GetRangeEnd();
385 size_t bytes_to_read
= size
; // Number of bytes to read from the core file
386 size_t bytes_copied
= 0; // Number of bytes actually read from the core file
387 lldb::addr_t bytes_left
=
388 0; // Number of bytes available in the core file from the given address
390 // Don't proceed if core file doesn't contain the actual data for this
392 if (file_start
== file_end
)
395 // Figure out how many on-disk bytes remain in this segment starting at the
397 if (file_end
> file_start
+ offset
)
398 bytes_left
= file_end
- (file_start
+ offset
);
400 if (bytes_to_read
> bytes_left
)
401 bytes_to_read
= bytes_left
;
403 // If there is data available on the core file read it
406 core_objfile
->CopyData(offset
+ file_start
, bytes_to_read
, buf
);
411 llvm::Expected
<std::vector
<lldb::addr_t
>>
412 ProcessElfCore::ReadMemoryTags(lldb::addr_t addr
, size_t len
) {
413 ObjectFile
*core_objfile
= m_core_module_sp
->GetObjectFile();
414 if (core_objfile
== nullptr)
415 return llvm::createStringError(llvm::inconvertibleErrorCode(),
416 "No core object file.");
418 llvm::Expected
<const MemoryTagManager
*> tag_manager_or_err
=
419 GetMemoryTagManager();
420 if (!tag_manager_or_err
)
421 return tag_manager_or_err
.takeError();
423 // LLDB only supports AArch64 MTE tag segments so we do not need to worry
424 // about the segment type here. If you got here then you must have a tag
425 // manager (meaning you are debugging AArch64) and all the segments in this
426 // list will have had type PT_AARCH64_MEMTAG_MTE.
427 const VMRangeToFileOffset::Entry
*tag_entry
=
428 m_core_tag_ranges
.FindEntryThatContains(addr
);
429 // If we don't have a tag segment or the range asked for extends outside the
431 if (!tag_entry
|| (addr
+ len
) >= tag_entry
->GetRangeEnd())
432 return llvm::createStringError(llvm::inconvertibleErrorCode(),
433 "No tag segment that covers this range.");
435 const MemoryTagManager
*tag_manager
= *tag_manager_or_err
;
436 return tag_manager
->UnpackTagsFromCoreFileSegment(
437 [core_objfile
](lldb::offset_t offset
, size_t length
, void *dst
) {
438 return core_objfile
->CopyData(offset
, length
, dst
);
440 tag_entry
->GetRangeBase(), tag_entry
->data
.GetRangeBase(), addr
, len
);
443 void ProcessElfCore::Clear() {
444 m_thread_list
.Clear();
446 SetUnixSignals(std::make_shared
<UnixSignals
>());
449 void ProcessElfCore::Initialize() {
450 static llvm::once_flag g_once_flag
;
452 llvm::call_once(g_once_flag
, []() {
453 PluginManager::RegisterPlugin(GetPluginNameStatic(),
454 GetPluginDescriptionStatic(), CreateInstance
);
458 lldb::addr_t
ProcessElfCore::GetImageInfoAddress() {
459 ObjectFile
*obj_file
= GetTarget().GetExecutableModule()->GetObjectFile();
460 Address addr
= obj_file
->GetImageInfoAddress(&GetTarget());
463 return addr
.GetLoadAddress(&GetTarget());
464 return LLDB_INVALID_ADDRESS
;
467 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
468 static void ParseFreeBSDPrStatus(ThreadData
&thread_data
,
469 const DataExtractor
&data
,
471 lldb::offset_t offset
= 0;
472 int pr_version
= data
.GetU32(&offset
);
474 Log
*log
= GetLog(LLDBLog::Process
);
477 LLDB_LOGF(log
, "FreeBSD PRSTATUS unexpected version %d", pr_version
);
480 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
486 thread_data
.signo
= data
.GetU32(&offset
); // pr_cursig
487 thread_data
.tid
= data
.GetU32(&offset
); // pr_pid
491 size_t len
= data
.GetByteSize() - offset
;
492 thread_data
.gpregset
= DataExtractor(data
, offset
, len
);
495 // Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details.
496 static void ParseFreeBSDPrPsInfo(ProcessElfCore
&process
,
497 const DataExtractor
&data
,
499 lldb::offset_t offset
= 0;
500 int pr_version
= data
.GetU32(&offset
);
502 Log
*log
= GetLog(LLDBLog::Process
);
505 LLDB_LOGF(log
, "FreeBSD PRPSINFO unexpected version %d", pr_version
);
508 // Skip pr_psinfosz, pr_fname, pr_psargs
513 process
.SetID(data
.GetU32(&offset
)); // pr_pid
516 static llvm::Error
ParseNetBSDProcInfo(const DataExtractor
&data
,
519 uint32_t &cpi_siglwp
,
521 lldb::offset_t offset
= 0;
523 uint32_t version
= data
.GetU32(&offset
);
525 return llvm::make_error
<llvm::StringError
>(
526 "Error parsing NetBSD core(5) notes: Unsupported procinfo version",
527 llvm::inconvertibleErrorCode());
529 uint32_t cpisize
= data
.GetU32(&offset
);
530 if (cpisize
!= NETBSD::NT_PROCINFO_SIZE
)
531 return llvm::make_error
<llvm::StringError
>(
532 "Error parsing NetBSD core(5) notes: Unsupported procinfo size",
533 llvm::inconvertibleErrorCode());
535 cpi_signo
= data
.GetU32(&offset
); /* killing signal */
537 offset
+= NETBSD::NT_PROCINFO_CPI_SIGCODE_SIZE
;
538 offset
+= NETBSD::NT_PROCINFO_CPI_SIGPEND_SIZE
;
539 offset
+= NETBSD::NT_PROCINFO_CPI_SIGMASK_SIZE
;
540 offset
+= NETBSD::NT_PROCINFO_CPI_SIGIGNORE_SIZE
;
541 offset
+= NETBSD::NT_PROCINFO_CPI_SIGCATCH_SIZE
;
542 cpi_pid
= data
.GetU32(&offset
);
543 offset
+= NETBSD::NT_PROCINFO_CPI_PPID_SIZE
;
544 offset
+= NETBSD::NT_PROCINFO_CPI_PGRP_SIZE
;
545 offset
+= NETBSD::NT_PROCINFO_CPI_SID_SIZE
;
546 offset
+= NETBSD::NT_PROCINFO_CPI_RUID_SIZE
;
547 offset
+= NETBSD::NT_PROCINFO_CPI_EUID_SIZE
;
548 offset
+= NETBSD::NT_PROCINFO_CPI_SVUID_SIZE
;
549 offset
+= NETBSD::NT_PROCINFO_CPI_RGID_SIZE
;
550 offset
+= NETBSD::NT_PROCINFO_CPI_EGID_SIZE
;
551 offset
+= NETBSD::NT_PROCINFO_CPI_SVGID_SIZE
;
552 cpi_nlwps
= data
.GetU32(&offset
); /* number of LWPs */
554 offset
+= NETBSD::NT_PROCINFO_CPI_NAME_SIZE
;
555 cpi_siglwp
= data
.GetU32(&offset
); /* LWP target of killing signal */
557 return llvm::Error::success();
560 static void ParseOpenBSDProcInfo(ThreadData
&thread_data
,
561 const DataExtractor
&data
) {
562 lldb::offset_t offset
= 0;
564 int version
= data
.GetU32(&offset
);
569 thread_data
.signo
= data
.GetU32(&offset
);
572 llvm::Expected
<std::vector
<CoreNote
>>
573 ProcessElfCore::parseSegment(const DataExtractor
&segment
) {
574 lldb::offset_t offset
= 0;
575 std::vector
<CoreNote
> result
;
577 while (offset
< segment
.GetByteSize()) {
578 ELFNote note
= ELFNote();
579 if (!note
.Parse(segment
, &offset
))
580 return llvm::make_error
<llvm::StringError
>(
581 "Unable to parse note segment", llvm::inconvertibleErrorCode());
583 size_t note_start
= offset
;
584 size_t note_size
= llvm::alignTo(note
.n_descsz
, 4);
586 result
.push_back({note
, DataExtractor(segment
, note_start
, note_size
)});
590 return std::move(result
);
593 llvm::Error
ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef
<CoreNote
> notes
) {
594 ArchSpec arch
= GetArchitecture();
595 bool lp64
= (arch
.GetMachine() == llvm::Triple::aarch64
||
596 arch
.GetMachine() == llvm::Triple::mips64
||
597 arch
.GetMachine() == llvm::Triple::ppc64
||
598 arch
.GetMachine() == llvm::Triple::x86_64
);
599 bool have_prstatus
= false;
600 bool have_prpsinfo
= false;
601 ThreadData thread_data
;
602 for (const auto ¬e
: notes
) {
603 if (note
.info
.n_name
!= "FreeBSD")
606 if ((note
.info
.n_type
== ELF::NT_PRSTATUS
&& have_prstatus
) ||
607 (note
.info
.n_type
== ELF::NT_PRPSINFO
&& have_prpsinfo
)) {
608 assert(thread_data
.gpregset
.GetByteSize() > 0);
609 // Add the new thread to thread list
610 m_thread_data
.push_back(thread_data
);
611 thread_data
= ThreadData();
612 have_prstatus
= false;
613 have_prpsinfo
= false;
616 switch (note
.info
.n_type
) {
617 case ELF::NT_PRSTATUS
:
618 have_prstatus
= true;
619 ParseFreeBSDPrStatus(thread_data
, note
.data
, lp64
);
621 case ELF::NT_PRPSINFO
:
622 have_prpsinfo
= true;
623 ParseFreeBSDPrPsInfo(*this, note
.data
, lp64
);
625 case ELF::NT_FREEBSD_THRMISC
: {
626 lldb::offset_t offset
= 0;
627 thread_data
.name
= note
.data
.GetCStr(&offset
, 20);
630 case ELF::NT_FREEBSD_PROCSTAT_AUXV
:
631 // FIXME: FreeBSD sticks an int at the beginning of the note
632 m_auxv
= DataExtractor(note
.data
, 4, note
.data
.GetByteSize() - 4);
635 thread_data
.notes
.push_back(note
);
639 if (!have_prstatus
) {
640 return llvm::make_error
<llvm::StringError
>(
641 "Could not find NT_PRSTATUS note in core file.",
642 llvm::inconvertibleErrorCode());
644 m_thread_data
.push_back(thread_data
);
645 return llvm::Error::success();
648 /// NetBSD specific Thread context from PT_NOTE segment
650 /// NetBSD ELF core files use notes to provide information about
651 /// the process's state. The note name is "NetBSD-CORE" for
652 /// information that is global to the process, and "NetBSD-CORE@nn",
653 /// where "nn" is the lwpid of the LWP that the information belongs
654 /// to (such as register state).
656 /// NetBSD uses the following note identifiers:
658 /// ELF_NOTE_NETBSD_CORE_PROCINFO (value 1)
659 /// Note is a "netbsd_elfcore_procinfo" structure.
660 /// ELF_NOTE_NETBSD_CORE_AUXV (value 2; since NetBSD 8.0)
661 /// Note is an array of AuxInfo structures.
663 /// NetBSD also uses ptrace(2) request numbers (the ones that exist in
664 /// machine-dependent space) to identify register info notes. The
665 /// info in such notes is in the same format that ptrace(2) would
666 /// export that information.
668 /// For more information see /usr/include/sys/exec_elf.h
670 llvm::Error
ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef
<CoreNote
> notes
) {
671 ThreadData thread_data
;
672 bool had_nt_regs
= false;
674 // To be extracted from struct netbsd_elfcore_procinfo
675 // Used to sanity check of the LWPs of the process
677 uint32_t signo
= 0; // killing signal
678 uint32_t siglwp
= 0; // LWP target of killing signal
681 for (const auto ¬e
: notes
) {
682 llvm::StringRef name
= note
.info
.n_name
;
684 if (name
== "NetBSD-CORE") {
685 if (note
.info
.n_type
== NETBSD::NT_PROCINFO
) {
686 llvm::Error error
= ParseNetBSDProcInfo(note
.data
, nlwps
, signo
,
691 } else if (note
.info
.n_type
== NETBSD::NT_AUXV
) {
694 } else if (name
.consume_front("NetBSD-CORE@")) {
696 if (name
.getAsInteger(10, tid
))
697 return llvm::make_error
<llvm::StringError
>(
698 "Error parsing NetBSD core(5) notes: Cannot convert LWP ID "
700 llvm::inconvertibleErrorCode());
702 switch (GetArchitecture().GetMachine()) {
703 case llvm::Triple::aarch64
: {
704 // Assume order PT_GETREGS, PT_GETFPREGS
705 if (note
.info
.n_type
== NETBSD::AARCH64::NT_REGS
) {
706 // If this is the next thread, push the previous one first.
708 m_thread_data
.push_back(thread_data
);
709 thread_data
= ThreadData();
713 thread_data
.gpregset
= note
.data
;
714 thread_data
.tid
= tid
;
715 if (thread_data
.gpregset
.GetByteSize() == 0)
716 return llvm::make_error
<llvm::StringError
>(
717 "Could not find general purpose registers note in core file.",
718 llvm::inconvertibleErrorCode());
720 } else if (note
.info
.n_type
== NETBSD::AARCH64::NT_FPREGS
) {
721 if (!had_nt_regs
|| tid
!= thread_data
.tid
)
722 return llvm::make_error
<llvm::StringError
>(
723 "Error parsing NetBSD core(5) notes: Unexpected order "
724 "of NOTEs PT_GETFPREG before PT_GETREG",
725 llvm::inconvertibleErrorCode());
726 thread_data
.notes
.push_back(note
);
729 case llvm::Triple::x86
: {
730 // Assume order PT_GETREGS, PT_GETFPREGS
731 if (note
.info
.n_type
== NETBSD::I386::NT_REGS
) {
732 // If this is the next thread, push the previous one first.
734 m_thread_data
.push_back(thread_data
);
735 thread_data
= ThreadData();
739 thread_data
.gpregset
= note
.data
;
740 thread_data
.tid
= tid
;
741 if (thread_data
.gpregset
.GetByteSize() == 0)
742 return llvm::make_error
<llvm::StringError
>(
743 "Could not find general purpose registers note in core file.",
744 llvm::inconvertibleErrorCode());
746 } else if (note
.info
.n_type
== NETBSD::I386::NT_FPREGS
) {
747 if (!had_nt_regs
|| tid
!= thread_data
.tid
)
748 return llvm::make_error
<llvm::StringError
>(
749 "Error parsing NetBSD core(5) notes: Unexpected order "
750 "of NOTEs PT_GETFPREG before PT_GETREG",
751 llvm::inconvertibleErrorCode());
752 thread_data
.notes
.push_back(note
);
755 case llvm::Triple::x86_64
: {
756 // Assume order PT_GETREGS, PT_GETFPREGS
757 if (note
.info
.n_type
== NETBSD::AMD64::NT_REGS
) {
758 // If this is the next thread, push the previous one first.
760 m_thread_data
.push_back(thread_data
);
761 thread_data
= ThreadData();
765 thread_data
.gpregset
= note
.data
;
766 thread_data
.tid
= tid
;
767 if (thread_data
.gpregset
.GetByteSize() == 0)
768 return llvm::make_error
<llvm::StringError
>(
769 "Could not find general purpose registers note in core file.",
770 llvm::inconvertibleErrorCode());
772 } else if (note
.info
.n_type
== NETBSD::AMD64::NT_FPREGS
) {
773 if (!had_nt_regs
|| tid
!= thread_data
.tid
)
774 return llvm::make_error
<llvm::StringError
>(
775 "Error parsing NetBSD core(5) notes: Unexpected order "
776 "of NOTEs PT_GETFPREG before PT_GETREG",
777 llvm::inconvertibleErrorCode());
778 thread_data
.notes
.push_back(note
);
787 // Push the last thread.
789 m_thread_data
.push_back(thread_data
);
791 if (m_thread_data
.empty())
792 return llvm::make_error
<llvm::StringError
>(
793 "Error parsing NetBSD core(5) notes: No threads information "
794 "specified in notes",
795 llvm::inconvertibleErrorCode());
797 if (m_thread_data
.size() != nlwps
)
798 return llvm::make_error
<llvm::StringError
>(
799 "Error parsing NetBSD core(5) notes: Mismatch between the number "
800 "of LWPs in netbsd_elfcore_procinfo and the number of LWPs specified "
802 llvm::inconvertibleErrorCode());
804 // Signal targeted at the whole process.
806 for (auto &data
: m_thread_data
)
809 // Signal destined for a particular LWP.
813 for (auto &data
: m_thread_data
) {
814 if (data
.tid
== siglwp
) {
822 return llvm::make_error
<llvm::StringError
>(
823 "Error parsing NetBSD core(5) notes: Signal passed to unknown LWP",
824 llvm::inconvertibleErrorCode());
827 return llvm::Error::success();
830 llvm::Error
ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef
<CoreNote
> notes
) {
831 ThreadData thread_data
= {};
832 for (const auto ¬e
: notes
) {
833 // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so
834 // match on the initial part of the string.
835 if (!llvm::StringRef(note
.info
.n_name
).startswith("OpenBSD"))
838 switch (note
.info
.n_type
) {
839 case OPENBSD::NT_PROCINFO
:
840 ParseOpenBSDProcInfo(thread_data
, note
.data
);
842 case OPENBSD::NT_AUXV
:
845 case OPENBSD::NT_REGS
:
846 thread_data
.gpregset
= note
.data
;
849 thread_data
.notes
.push_back(note
);
853 if (thread_data
.gpregset
.GetByteSize() == 0) {
854 return llvm::make_error
<llvm::StringError
>(
855 "Could not find general purpose registers note in core file.",
856 llvm::inconvertibleErrorCode());
858 m_thread_data
.push_back(thread_data
);
859 return llvm::Error::success();
862 /// A description of a linux process usually contains the following NOTE
864 /// - NT_PRPSINFO - General process information like pid, uid, name, ...
865 /// - NT_SIGINFO - Information about the signal that terminated the process
866 /// - NT_AUXV - Process auxiliary vector
867 /// - NT_FILE - Files mapped into memory
869 /// Additionally, for each thread in the process the core file will contain at
870 /// least the NT_PRSTATUS note, containing the thread id and general purpose
871 /// registers. It may include additional notes for other register sets (floating
872 /// point and vector registers, ...). The tricky part here is that some of these
873 /// notes have "CORE" in their owner fields, while other set it to "LINUX".
874 llvm::Error
ProcessElfCore::parseLinuxNotes(llvm::ArrayRef
<CoreNote
> notes
) {
875 const ArchSpec
&arch
= GetArchitecture();
876 bool have_prstatus
= false;
877 bool have_prpsinfo
= false;
878 ThreadData thread_data
;
879 for (const auto ¬e
: notes
) {
880 if (note
.info
.n_name
!= "CORE" && note
.info
.n_name
!= "LINUX")
883 if ((note
.info
.n_type
== ELF::NT_PRSTATUS
&& have_prstatus
) ||
884 (note
.info
.n_type
== ELF::NT_PRPSINFO
&& have_prpsinfo
)) {
885 assert(thread_data
.gpregset
.GetByteSize() > 0);
886 // Add the new thread to thread list
887 m_thread_data
.push_back(thread_data
);
888 thread_data
= ThreadData();
889 have_prstatus
= false;
890 have_prpsinfo
= false;
893 switch (note
.info
.n_type
) {
894 case ELF::NT_PRSTATUS
: {
895 have_prstatus
= true;
896 ELFLinuxPrStatus prstatus
;
897 Status status
= prstatus
.Parse(note
.data
, arch
);
899 return status
.ToError();
900 thread_data
.prstatus_sig
= prstatus
.pr_cursig
;
901 thread_data
.tid
= prstatus
.pr_pid
;
902 uint32_t header_size
= ELFLinuxPrStatus::GetSize(arch
);
903 size_t len
= note
.data
.GetByteSize() - header_size
;
904 thread_data
.gpregset
= DataExtractor(note
.data
, header_size
, len
);
907 case ELF::NT_PRPSINFO
: {
908 have_prpsinfo
= true;
909 ELFLinuxPrPsInfo prpsinfo
;
910 Status status
= prpsinfo
.Parse(note
.data
, arch
);
912 return status
.ToError();
913 thread_data
.name
.assign (prpsinfo
.pr_fname
, strnlen (prpsinfo
.pr_fname
, sizeof (prpsinfo
.pr_fname
)));
914 SetID(prpsinfo
.pr_pid
);
917 case ELF::NT_SIGINFO
: {
918 ELFLinuxSigInfo siginfo
;
919 Status status
= siginfo
.Parse(note
.data
, arch
);
921 return status
.ToError();
922 thread_data
.signo
= siginfo
.si_signo
;
923 thread_data
.code
= siginfo
.si_code
;
927 m_nt_file_entries
.clear();
928 lldb::offset_t offset
= 0;
929 const uint64_t count
= note
.data
.GetAddress(&offset
);
930 note
.data
.GetAddress(&offset
); // Skip page size
931 for (uint64_t i
= 0; i
< count
; ++i
) {
933 entry
.start
= note
.data
.GetAddress(&offset
);
934 entry
.end
= note
.data
.GetAddress(&offset
);
935 entry
.file_ofs
= note
.data
.GetAddress(&offset
);
936 m_nt_file_entries
.push_back(entry
);
938 for (uint64_t i
= 0; i
< count
; ++i
) {
939 const char *path
= note
.data
.GetCStr(&offset
);
941 m_nt_file_entries
[i
].path
.assign(path
);
949 thread_data
.notes
.push_back(note
);
953 // Add last entry in the note section
955 m_thread_data
.push_back(thread_data
);
956 return llvm::Error::success();
959 /// Parse Thread context from PT_NOTE segment and store it in the thread list
960 /// A note segment consists of one or more NOTE entries, but their types and
961 /// meaning differ depending on the OS.
962 llvm::Error
ProcessElfCore::ParseThreadContextsFromNoteSegment(
963 const elf::ELFProgramHeader
&segment_header
,
964 const DataExtractor
&segment_data
) {
965 assert(segment_header
.p_type
== llvm::ELF::PT_NOTE
);
967 auto notes_or_error
= parseSegment(segment_data
);
969 return notes_or_error
.takeError();
970 switch (GetArchitecture().GetTriple().getOS()) {
971 case llvm::Triple::FreeBSD
:
972 return parseFreeBSDNotes(*notes_or_error
);
973 case llvm::Triple::Linux
:
974 return parseLinuxNotes(*notes_or_error
);
975 case llvm::Triple::NetBSD
:
976 return parseNetBSDNotes(*notes_or_error
);
977 case llvm::Triple::OpenBSD
:
978 return parseOpenBSDNotes(*notes_or_error
);
980 return llvm::make_error
<llvm::StringError
>(
981 "Don't know how to parse core file. Unsupported OS.",
982 llvm::inconvertibleErrorCode());
986 uint32_t ProcessElfCore::GetNumThreadContexts() {
987 if (!m_thread_data_valid
)
989 return m_thread_data
.size();
992 ArchSpec
ProcessElfCore::GetArchitecture() {
993 ArchSpec arch
= m_core_module_sp
->GetObjectFile()->GetArchitecture();
995 ArchSpec target_arch
= GetTarget().GetArchitecture();
996 arch
.MergeFrom(target_arch
);
998 // On MIPS there is no way to differentiate betwenn 32bit and 64bit core
999 // files and this information can't be merged in from the target arch so we
1000 // fail back to unconditionally returning the target arch in this config.
1001 if (target_arch
.IsMIPS()) {
1008 DataExtractor
ProcessElfCore::GetAuxvData() {
1009 const uint8_t *start
= m_auxv
.GetDataStart();
1010 size_t len
= m_auxv
.GetByteSize();
1011 lldb::DataBufferSP
buffer(new lldb_private::DataBufferHeap(start
, len
));
1012 return DataExtractor(buffer
, GetByteOrder(), GetAddressByteSize());
1015 bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo
&info
) {
1017 info
.SetProcessID(GetID());
1018 info
.SetArchitecture(GetArchitecture());
1019 lldb::ModuleSP module_sp
= GetTarget().GetExecutableModule();
1021 const bool add_exe_file_as_first_arg
= false;
1022 info
.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
1023 add_exe_file_as_first_arg
);