1 //===-- ProcessElfCore.cpp ------------------------------------------------===//
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 #include <stdlib.h>
10
11 #include <memory>
12 #include <mutex>
13
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/DynamicLoader.h"
19 #include "lldb/Target/MemoryRegionInfo.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Target/UnixSignals.h"
22 #include "lldb/Utility/DataBufferHeap.h"
23 #include "lldb/Utility/Log.h"
24 #include "lldb/Utility/State.h"
25
26 #include "llvm/BinaryFormat/ELF.h"
27 #include "llvm/Support/Threading.h"
28
29 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
30 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
31 #include "Plugins/Process/elf-core/RegisterUtilities.h"
32 #include "ProcessElfCore.h"
33 #include "ThreadElfCore.h"
34
35 using namespace lldb_private;
36 namespace ELF = llvm::ELF;
37
LLDB_PLUGIN_DEFINE(ProcessElfCore)38 LLDB_PLUGIN_DEFINE(ProcessElfCore)
39
40 ConstString ProcessElfCore::GetPluginNameStatic() {
41 static ConstString g_name("elf-core");
42 return g_name;
43 }
44
GetPluginDescriptionStatic()45 const char *ProcessElfCore::GetPluginDescriptionStatic() {
46 return "ELF core dump plug-in.";
47 }
48
Terminate()49 void ProcessElfCore::Terminate() {
50 PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance);
51 }
52
CreateInstance(lldb::TargetSP target_sp,lldb::ListenerSP listener_sp,const FileSpec * crash_file)53 lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
54 lldb::ListenerSP listener_sp,
55 const FileSpec *crash_file) {
56 lldb::ProcessSP process_sp;
57 if (crash_file) {
58 // Read enough data for a ELF32 header or ELF64 header Note: Here we care
59 // about e_type field only, so it is safe to ignore possible presence of
60 // the header extension.
61 const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
62
63 auto data_sp = FileSystem::Instance().CreateDataBuffer(
64 crash_file->GetPath(), header_size, 0);
65 if (data_sp && data_sp->GetByteSize() == header_size &&
66 elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
67 elf::ELFHeader elf_header;
68 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
69 lldb::offset_t data_offset = 0;
70 if (elf_header.Parse(data, &data_offset)) {
71 if (elf_header.e_type == llvm::ELF::ET_CORE)
72 process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp,
73 *crash_file);
74 }
75 }
76 }
77 return process_sp;
78 }
79
CanDebug(lldb::TargetSP target_sp,bool plugin_specified_by_name)80 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
81 bool plugin_specified_by_name) {
82 // For now we are just making sure the file exists for a given module
83 if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
84 ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
85 Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
86 nullptr, nullptr, nullptr));
87 if (m_core_module_sp) {
88 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
89 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
90 return true;
91 }
92 }
93 return false;
94 }
95
96 // ProcessElfCore constructor
ProcessElfCore(lldb::TargetSP target_sp,lldb::ListenerSP listener_sp,const FileSpec & core_file)97 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
98 lldb::ListenerSP listener_sp,
99 const FileSpec &core_file)
100 : Process(target_sp, listener_sp), m_core_file(core_file) {}
101
102 // Destructor
~ProcessElfCore()103 ProcessElfCore::~ProcessElfCore() {
104 Clear();
105 // We need to call finalize on the process before destroying ourselves to
106 // make sure all of the broadcaster cleanup goes as planned. If we destruct
107 // this class, then Process::~Process() might have problems trying to fully
108 // destroy the broadcaster.
109 Finalize();
110 }
111
112 // PluginInterface
GetPluginName()113 ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); }
114
GetPluginVersion()115 uint32_t ProcessElfCore::GetPluginVersion() { return 1; }
116
AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader & header)117 lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
118 const elf::ELFProgramHeader &header) {
119 const lldb::addr_t addr = header.p_vaddr;
120 FileRange file_range(header.p_offset, header.p_filesz);
121 VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range);
122
123 // Only add to m_core_aranges if the file size is non zero. Some core files
124 // have PT_LOAD segments for all address ranges, but set f_filesz to zero for
125 // the .text sections since they can be retrieved from the object files.
126 if (header.p_filesz > 0) {
127 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
128 if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
129 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
130 last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
131 last_entry->SetRangeEnd(range_entry.GetRangeEnd());
132 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
133 } else {
134 m_core_aranges.Append(range_entry);
135 }
136 }
137 // Keep a separate map of permissions that that isn't coalesced so all ranges
138 // are maintained.
139 const uint32_t permissions =
140 ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
141 ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
142 ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
143
144 m_core_range_infos.Append(
145 VMRangeToPermissions::Entry(addr, header.p_memsz, permissions));
146
147 return addr;
148 }
149
150 // Process Control
DoLoadCore()151 Status ProcessElfCore::DoLoadCore() {
152 Status error;
153 if (!m_core_module_sp) {
154 error.SetErrorString("invalid core module");
155 return error;
156 }
157
158 ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
159 if (core == nullptr) {
160 error.SetErrorString("invalid core object file");
161 return error;
162 }
163
164 llvm::ArrayRef<elf::ELFProgramHeader> segments = core->ProgramHeaders();
165 if (segments.size() == 0) {
166 error.SetErrorString("core file has no segments");
167 return error;
168 }
169
170 SetCanJIT(false);
171
172 m_thread_data_valid = true;
173
174 bool ranges_are_sorted = true;
175 lldb::addr_t vm_addr = 0;
176 /// Walk through segments and Thread and Address Map information.
177 /// PT_NOTE - Contains Thread and Register information
178 /// PT_LOAD - Contains a contiguous range of Process Address Space
179 for (const elf::ELFProgramHeader &H : segments) {
180 DataExtractor data = core->GetSegmentData(H);
181
182 // Parse thread contexts and auxv structure
183 if (H.p_type == llvm::ELF::PT_NOTE) {
184 if (llvm::Error error = ParseThreadContextsFromNoteSegment(H, data))
185 return Status(std::move(error));
186 }
187 // PT_LOAD segments contains address map
188 if (H.p_type == llvm::ELF::PT_LOAD) {
189 lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(H);
190 if (vm_addr > last_addr)
191 ranges_are_sorted = false;
192 vm_addr = last_addr;
193 }
194 }
195
196 if (!ranges_are_sorted) {
197 m_core_aranges.Sort();
198 m_core_range_infos.Sort();
199 }
200
201 // Even if the architecture is set in the target, we need to override it to
202 // match the core file which is always single arch.
203 ArchSpec arch(m_core_module_sp->GetArchitecture());
204
205 ArchSpec target_arch = GetTarget().GetArchitecture();
206 ArchSpec core_arch(m_core_module_sp->GetArchitecture());
207 target_arch.MergeFrom(core_arch);
208 GetTarget().SetArchitecture(target_arch);
209
210 SetUnixSignals(UnixSignals::Create(GetArchitecture()));
211
212 // Ensure we found at least one thread that was stopped on a signal.
213 bool siginfo_signal_found = false;
214 bool prstatus_signal_found = false;
215 // Check we found a signal in a SIGINFO note.
216 for (const auto &thread_data : m_thread_data) {
217 if (thread_data.signo != 0)
218 siginfo_signal_found = true;
219 if (thread_data.prstatus_sig != 0)
220 prstatus_signal_found = true;
221 }
222 if (!siginfo_signal_found) {
223 // If we don't have signal from SIGINFO use the signal from each threads
224 // PRSTATUS note.
225 if (prstatus_signal_found) {
226 for (auto &thread_data : m_thread_data)
227 thread_data.signo = thread_data.prstatus_sig;
228 } else if (m_thread_data.size() > 0) {
229 // If all else fails force the first thread to be SIGSTOP
230 m_thread_data.begin()->signo =
231 GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
232 }
233 }
234
235 // Core files are useless without the main executable. See if we can locate
236 // the main executable using data we found in the core file notes.
237 lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
238 if (!exe_module_sp) {
239 // The first entry in the NT_FILE might be our executable
240 if (!m_nt_file_entries.empty()) {
241 ModuleSpec exe_module_spec;
242 exe_module_spec.GetArchitecture() = arch;
243 exe_module_spec.GetFileSpec().SetFile(
244 m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native);
245 if (exe_module_spec.GetFileSpec()) {
246 exe_module_sp = GetTarget().GetOrCreateModule(exe_module_spec,
247 true /* notify */);
248 if (exe_module_sp)
249 GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo);
250 }
251 }
252 }
253 return error;
254 }
255
GetDynamicLoader()256 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
257 if (m_dyld_up.get() == nullptr)
258 m_dyld_up.reset(DynamicLoader::FindPlugin(
259 this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
260 return m_dyld_up.get();
261 }
262
UpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)263 bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list,
264 ThreadList &new_thread_list) {
265 const uint32_t num_threads = GetNumThreadContexts();
266 if (!m_thread_data_valid)
267 return false;
268
269 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
270 const ThreadData &td = m_thread_data[tid];
271 lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td));
272 new_thread_list.AddThread(thread_sp);
273 }
274 return new_thread_list.GetSize(false) > 0;
275 }
276
RefreshStateAfterStop()277 void ProcessElfCore::RefreshStateAfterStop() {}
278
DoDestroy()279 Status ProcessElfCore::DoDestroy() { return Status(); }
280
281 // Process Queries
282
IsAlive()283 bool ProcessElfCore::IsAlive() { return true; }
284
285 // Process Memory
ReadMemory(lldb::addr_t addr,void * buf,size_t size,Status & error)286 size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
287 Status &error) {
288 // Don't allow the caching that lldb_private::Process::ReadMemory does since
289 // in core files we have it all cached our our core file anyway.
290 return DoReadMemory(addr, buf, size, error);
291 }
292
GetMemoryRegionInfo(lldb::addr_t load_addr,MemoryRegionInfo & region_info)293 Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
294 MemoryRegionInfo ®ion_info) {
295 region_info.Clear();
296 const VMRangeToPermissions::Entry *permission_entry =
297 m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
298 if (permission_entry) {
299 if (permission_entry->Contains(load_addr)) {
300 region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
301 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
302 const Flags permissions(permission_entry->data);
303 region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable)
304 ? MemoryRegionInfo::eYes
305 : MemoryRegionInfo::eNo);
306 region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable)
307 ? MemoryRegionInfo::eYes
308 : MemoryRegionInfo::eNo);
309 region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable)
310 ? MemoryRegionInfo::eYes
311 : MemoryRegionInfo::eNo);
312 region_info.SetMapped(MemoryRegionInfo::eYes);
313 } else if (load_addr < permission_entry->GetRangeBase()) {
314 region_info.GetRange().SetRangeBase(load_addr);
315 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
316 region_info.SetReadable(MemoryRegionInfo::eNo);
317 region_info.SetWritable(MemoryRegionInfo::eNo);
318 region_info.SetExecutable(MemoryRegionInfo::eNo);
319 region_info.SetMapped(MemoryRegionInfo::eNo);
320 }
321 return Status();
322 }
323
324 region_info.GetRange().SetRangeBase(load_addr);
325 region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
326 region_info.SetReadable(MemoryRegionInfo::eNo);
327 region_info.SetWritable(MemoryRegionInfo::eNo);
328 region_info.SetExecutable(MemoryRegionInfo::eNo);
329 region_info.SetMapped(MemoryRegionInfo::eNo);
330 return Status();
331 }
332
DoReadMemory(lldb::addr_t addr,void * buf,size_t size,Status & error)333 size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
334 Status &error) {
335 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
336
337 if (core_objfile == nullptr)
338 return 0;
339
340 // Get the address range
341 const VMRangeToFileOffset::Entry *address_range =
342 m_core_aranges.FindEntryThatContains(addr);
343 if (address_range == nullptr || address_range->GetRangeEnd() < addr) {
344 error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64,
345 addr);
346 return 0;
347 }
348
349 // Convert the address into core file offset
350 const lldb::addr_t offset = addr - address_range->GetRangeBase();
351 const lldb::addr_t file_start = address_range->data.GetRangeBase();
352 const lldb::addr_t file_end = address_range->data.GetRangeEnd();
353 size_t bytes_to_read = size; // Number of bytes to read from the core file
354 size_t bytes_copied = 0; // Number of bytes actually read from the core file
355 size_t zero_fill_size = 0; // Padding
356 lldb::addr_t bytes_left =
357 0; // Number of bytes available in the core file from the given address
358
359 // Don't proceed if core file doesn't contain the actual data for this
360 // address range.
361 if (file_start == file_end)
362 return 0;
363
364 // Figure out how many on-disk bytes remain in this segment starting at the
365 // given offset
366 if (file_end > file_start + offset)
367 bytes_left = file_end - (file_start + offset);
368
369 // Figure out how many bytes we need to zero-fill if we are reading more
370 // bytes than available in the on-disk segment
371 if (bytes_to_read > bytes_left) {
372 zero_fill_size = bytes_to_read - bytes_left;
373 bytes_to_read = bytes_left;
374 }
375
376 // If there is data available on the core file read it
377 if (bytes_to_read)
378 bytes_copied =
379 core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
380
381 assert(zero_fill_size <= size);
382 // Pad remaining bytes
383 if (zero_fill_size)
384 memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
385
386 return bytes_copied + zero_fill_size;
387 }
388
Clear()389 void ProcessElfCore::Clear() {
390 m_thread_list.Clear();
391
392 SetUnixSignals(std::make_shared<UnixSignals>());
393 }
394
Initialize()395 void ProcessElfCore::Initialize() {
396 static llvm::once_flag g_once_flag;
397
398 llvm::call_once(g_once_flag, []() {
399 PluginManager::RegisterPlugin(GetPluginNameStatic(),
400 GetPluginDescriptionStatic(), CreateInstance);
401 });
402 }
403
GetImageInfoAddress()404 lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
405 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
406 Address addr = obj_file->GetImageInfoAddress(&GetTarget());
407
408 if (addr.IsValid())
409 return addr.GetLoadAddress(&GetTarget());
410 return LLDB_INVALID_ADDRESS;
411 }
412
413 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
ParseFreeBSDPrStatus(ThreadData & thread_data,const DataExtractor & data,const ArchSpec & arch)414 static void ParseFreeBSDPrStatus(ThreadData &thread_data,
415 const DataExtractor &data,
416 const ArchSpec &arch) {
417 lldb::offset_t offset = 0;
418 bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
419 arch.GetMachine() == llvm::Triple::mips64 ||
420 arch.GetMachine() == llvm::Triple::ppc64 ||
421 arch.GetMachine() == llvm::Triple::x86_64);
422 int pr_version = data.GetU32(&offset);
423
424 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
425 if (log) {
426 if (pr_version > 1)
427 LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version);
428 }
429
430 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
431 if (lp64)
432 offset += 32;
433 else
434 offset += 16;
435
436 thread_data.signo = data.GetU32(&offset); // pr_cursig
437 thread_data.tid = data.GetU32(&offset); // pr_pid
438 if (lp64)
439 offset += 4;
440
441 size_t len = data.GetByteSize() - offset;
442 thread_data.gpregset = DataExtractor(data, offset, len);
443 }
444
ParseNetBSDProcInfo(const DataExtractor & data,uint32_t & cpi_nlwps,uint32_t & cpi_signo,uint32_t & cpi_siglwp,uint32_t & cpi_pid)445 static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data,
446 uint32_t &cpi_nlwps,
447 uint32_t &cpi_signo,
448 uint32_t &cpi_siglwp,
449 uint32_t &cpi_pid) {
450 lldb::offset_t offset = 0;
451
452 uint32_t version = data.GetU32(&offset);
453 if (version != 1)
454 return llvm::make_error<llvm::StringError>(
455 "Error parsing NetBSD core(5) notes: Unsupported procinfo version",
456 llvm::inconvertibleErrorCode());
457
458 uint32_t cpisize = data.GetU32(&offset);
459 if (cpisize != NETBSD::NT_PROCINFO_SIZE)
460 return llvm::make_error<llvm::StringError>(
461 "Error parsing NetBSD core(5) notes: Unsupported procinfo size",
462 llvm::inconvertibleErrorCode());
463
464 cpi_signo = data.GetU32(&offset); /* killing signal */
465
466 offset += NETBSD::NT_PROCINFO_CPI_SIGCODE_SIZE;
467 offset += NETBSD::NT_PROCINFO_CPI_SIGPEND_SIZE;
468 offset += NETBSD::NT_PROCINFO_CPI_SIGMASK_SIZE;
469 offset += NETBSD::NT_PROCINFO_CPI_SIGIGNORE_SIZE;
470 offset += NETBSD::NT_PROCINFO_CPI_SIGCATCH_SIZE;
471 cpi_pid = data.GetU32(&offset);
472 offset += NETBSD::NT_PROCINFO_CPI_PPID_SIZE;
473 offset += NETBSD::NT_PROCINFO_CPI_PGRP_SIZE;
474 offset += NETBSD::NT_PROCINFO_CPI_SID_SIZE;
475 offset += NETBSD::NT_PROCINFO_CPI_RUID_SIZE;
476 offset += NETBSD::NT_PROCINFO_CPI_EUID_SIZE;
477 offset += NETBSD::NT_PROCINFO_CPI_SVUID_SIZE;
478 offset += NETBSD::NT_PROCINFO_CPI_RGID_SIZE;
479 offset += NETBSD::NT_PROCINFO_CPI_EGID_SIZE;
480 offset += NETBSD::NT_PROCINFO_CPI_SVGID_SIZE;
481 cpi_nlwps = data.GetU32(&offset); /* number of LWPs */
482
483 offset += NETBSD::NT_PROCINFO_CPI_NAME_SIZE;
484 cpi_siglwp = data.GetU32(&offset); /* LWP target of killing signal */
485
486 return llvm::Error::success();
487 }
488
ParseOpenBSDProcInfo(ThreadData & thread_data,const DataExtractor & data)489 static void ParseOpenBSDProcInfo(ThreadData &thread_data,
490 const DataExtractor &data) {
491 lldb::offset_t offset = 0;
492
493 int version = data.GetU32(&offset);
494 if (version != 1)
495 return;
496
497 offset += 4;
498 thread_data.signo = data.GetU32(&offset);
499 }
500
501 llvm::Expected<std::vector<CoreNote>>
parseSegment(const DataExtractor & segment)502 ProcessElfCore::parseSegment(const DataExtractor &segment) {
503 lldb::offset_t offset = 0;
504 std::vector<CoreNote> result;
505
506 while (offset < segment.GetByteSize()) {
507 ELFNote note = ELFNote();
508 if (!note.Parse(segment, &offset))
509 return llvm::make_error<llvm::StringError>(
510 "Unable to parse note segment", llvm::inconvertibleErrorCode());
511
512 size_t note_start = offset;
513 size_t note_size = llvm::alignTo(note.n_descsz, 4);
514 DataExtractor note_data(segment, note_start, note_size);
515
516 result.push_back({note, note_data});
517 offset += note_size;
518 }
519
520 return std::move(result);
521 }
522
parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes)523 llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
524 bool have_prstatus = false;
525 bool have_prpsinfo = false;
526 ThreadData thread_data;
527 for (const auto ¬e : notes) {
528 if (note.info.n_name != "FreeBSD")
529 continue;
530
531 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
532 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
533 assert(thread_data.gpregset.GetByteSize() > 0);
534 // Add the new thread to thread list
535 m_thread_data.push_back(thread_data);
536 thread_data = ThreadData();
537 have_prstatus = false;
538 have_prpsinfo = false;
539 }
540
541 switch (note.info.n_type) {
542 case ELF::NT_PRSTATUS:
543 have_prstatus = true;
544 ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
545 break;
546 case ELF::NT_PRPSINFO:
547 have_prpsinfo = true;
548 break;
549 case ELF::NT_FREEBSD_THRMISC: {
550 lldb::offset_t offset = 0;
551 thread_data.name = note.data.GetCStr(&offset, 20);
552 break;
553 }
554 case ELF::NT_FREEBSD_PROCSTAT_AUXV:
555 // FIXME: FreeBSD sticks an int at the beginning of the note
556 m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
557 break;
558 default:
559 thread_data.notes.push_back(note);
560 break;
561 }
562 }
563 if (!have_prstatus) {
564 return llvm::make_error<llvm::StringError>(
565 "Could not find NT_PRSTATUS note in core file.",
566 llvm::inconvertibleErrorCode());
567 }
568 m_thread_data.push_back(thread_data);
569 return llvm::Error::success();
570 }
571
572 /// NetBSD specific Thread context from PT_NOTE segment
573 ///
574 /// NetBSD ELF core files use notes to provide information about
575 /// the process's state. The note name is "NetBSD-CORE" for
576 /// information that is global to the process, and "NetBSD-CORE@nn",
577 /// where "nn" is the lwpid of the LWP that the information belongs
578 /// to (such as register state).
579 ///
580 /// NetBSD uses the following note identifiers:
581 ///
582 /// ELF_NOTE_NETBSD_CORE_PROCINFO (value 1)
583 /// Note is a "netbsd_elfcore_procinfo" structure.
584 /// ELF_NOTE_NETBSD_CORE_AUXV (value 2; since NetBSD 8.0)
585 /// Note is an array of AuxInfo structures.
586 ///
587 /// NetBSD also uses ptrace(2) request numbers (the ones that exist in
588 /// machine-dependent space) to identify register info notes. The
589 /// info in such notes is in the same format that ptrace(2) would
590 /// export that information.
591 ///
592 /// For more information see /usr/include/sys/exec_elf.h
593 ///
parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes)594 llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
595 ThreadData thread_data;
596 bool had_nt_regs = false;
597
598 // To be extracted from struct netbsd_elfcore_procinfo
599 // Used to sanity check of the LWPs of the process
600 uint32_t nlwps = 0;
601 uint32_t signo; // killing signal
602 uint32_t siglwp; // LWP target of killing signal
603 uint32_t pr_pid;
604
605 for (const auto ¬e : notes) {
606 llvm::StringRef name = note.info.n_name;
607
608 if (name == "NetBSD-CORE") {
609 if (note.info.n_type == NETBSD::NT_PROCINFO) {
610 llvm::Error error = ParseNetBSDProcInfo(note.data, nlwps, signo,
611 siglwp, pr_pid);
612 if (error)
613 return error;
614 SetID(pr_pid);
615 } else if (note.info.n_type == NETBSD::NT_AUXV) {
616 m_auxv = note.data;
617 }
618 } else if (name.consume_front("NetBSD-CORE@")) {
619 lldb::tid_t tid;
620 if (name.getAsInteger(10, tid))
621 return llvm::make_error<llvm::StringError>(
622 "Error parsing NetBSD core(5) notes: Cannot convert LWP ID "
623 "to integer",
624 llvm::inconvertibleErrorCode());
625
626 switch (GetArchitecture().GetMachine()) {
627 case llvm::Triple::aarch64: {
628 // Assume order PT_GETREGS, PT_GETFPREGS
629 if (note.info.n_type == NETBSD::AARCH64::NT_REGS) {
630 // If this is the next thread, push the previous one first.
631 if (had_nt_regs) {
632 m_thread_data.push_back(thread_data);
633 thread_data = ThreadData();
634 had_nt_regs = false;
635 }
636
637 thread_data.gpregset = note.data;
638 thread_data.tid = tid;
639 if (thread_data.gpregset.GetByteSize() == 0)
640 return llvm::make_error<llvm::StringError>(
641 "Could not find general purpose registers note in core file.",
642 llvm::inconvertibleErrorCode());
643 had_nt_regs = true;
644 } else if (note.info.n_type == NETBSD::AARCH64::NT_FPREGS) {
645 if (!had_nt_regs || tid != thread_data.tid)
646 return llvm::make_error<llvm::StringError>(
647 "Error parsing NetBSD core(5) notes: Unexpected order "
648 "of NOTEs PT_GETFPREG before PT_GETREG",
649 llvm::inconvertibleErrorCode());
650 thread_data.notes.push_back(note);
651 }
652 } break;
653 case llvm::Triple::x86_64: {
654 // Assume order PT_GETREGS, PT_GETFPREGS
655 if (note.info.n_type == NETBSD::AMD64::NT_REGS) {
656 // If this is the next thread, push the previous one first.
657 if (had_nt_regs) {
658 m_thread_data.push_back(thread_data);
659 thread_data = ThreadData();
660 had_nt_regs = false;
661 }
662
663 thread_data.gpregset = note.data;
664 thread_data.tid = tid;
665 if (thread_data.gpregset.GetByteSize() == 0)
666 return llvm::make_error<llvm::StringError>(
667 "Could not find general purpose registers note in core file.",
668 llvm::inconvertibleErrorCode());
669 had_nt_regs = true;
670 } else if (note.info.n_type == NETBSD::AMD64::NT_FPREGS) {
671 if (!had_nt_regs || tid != thread_data.tid)
672 return llvm::make_error<llvm::StringError>(
673 "Error parsing NetBSD core(5) notes: Unexpected order "
674 "of NOTEs PT_GETFPREG before PT_GETREG",
675 llvm::inconvertibleErrorCode());
676 thread_data.notes.push_back(note);
677 }
678 } break;
679 default:
680 break;
681 }
682 }
683 }
684
685 // Push the last thread.
686 if (had_nt_regs)
687 m_thread_data.push_back(thread_data);
688
689 if (m_thread_data.empty())
690 return llvm::make_error<llvm::StringError>(
691 "Error parsing NetBSD core(5) notes: No threads information "
692 "specified in notes",
693 llvm::inconvertibleErrorCode());
694
695 if (m_thread_data.size() != nlwps)
696 return llvm::make_error<llvm::StringError>(
697 "Error parsing NetBSD core(5) notes: Mismatch between the number "
698 "of LWPs in netbsd_elfcore_procinfo and the number of LWPs specified "
699 "by MD notes",
700 llvm::inconvertibleErrorCode());
701
702 // Signal targeted at the whole process.
703 if (siglwp == 0) {
704 for (auto &data : m_thread_data)
705 data.signo = signo;
706 }
707 // Signal destined for a particular LWP.
708 else {
709 bool passed = false;
710
711 for (auto &data : m_thread_data) {
712 if (data.tid == siglwp) {
713 data.signo = signo;
714 passed = true;
715 break;
716 }
717 }
718
719 if (!passed)
720 return llvm::make_error<llvm::StringError>(
721 "Error parsing NetBSD core(5) notes: Signal passed to unknown LWP",
722 llvm::inconvertibleErrorCode());
723 }
724
725 return llvm::Error::success();
726 }
727
parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes)728 llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
729 ThreadData thread_data;
730 for (const auto ¬e : notes) {
731 // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so
732 // match on the initial part of the string.
733 if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD"))
734 continue;
735
736 switch (note.info.n_type) {
737 case OPENBSD::NT_PROCINFO:
738 ParseOpenBSDProcInfo(thread_data, note.data);
739 break;
740 case OPENBSD::NT_AUXV:
741 m_auxv = note.data;
742 break;
743 case OPENBSD::NT_REGS:
744 thread_data.gpregset = note.data;
745 break;
746 default:
747 thread_data.notes.push_back(note);
748 break;
749 }
750 }
751 if (thread_data.gpregset.GetByteSize() == 0) {
752 return llvm::make_error<llvm::StringError>(
753 "Could not find general purpose registers note in core file.",
754 llvm::inconvertibleErrorCode());
755 }
756 m_thread_data.push_back(thread_data);
757 return llvm::Error::success();
758 }
759
760 /// A description of a linux process usually contains the following NOTE
761 /// entries:
762 /// - NT_PRPSINFO - General process information like pid, uid, name, ...
763 /// - NT_SIGINFO - Information about the signal that terminated the process
764 /// - NT_AUXV - Process auxiliary vector
765 /// - NT_FILE - Files mapped into memory
766 ///
767 /// Additionally, for each thread in the process the core file will contain at
768 /// least the NT_PRSTATUS note, containing the thread id and general purpose
769 /// registers. It may include additional notes for other register sets (floating
770 /// point and vector registers, ...). The tricky part here is that some of these
771 /// notes have "CORE" in their owner fields, while other set it to "LINUX".
parseLinuxNotes(llvm::ArrayRef<CoreNote> notes)772 llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
773 const ArchSpec &arch = GetArchitecture();
774 bool have_prstatus = false;
775 bool have_prpsinfo = false;
776 ThreadData thread_data;
777 for (const auto ¬e : notes) {
778 if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
779 continue;
780
781 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
782 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
783 assert(thread_data.gpregset.GetByteSize() > 0);
784 // Add the new thread to thread list
785 m_thread_data.push_back(thread_data);
786 thread_data = ThreadData();
787 have_prstatus = false;
788 have_prpsinfo = false;
789 }
790
791 switch (note.info.n_type) {
792 case ELF::NT_PRSTATUS: {
793 have_prstatus = true;
794 ELFLinuxPrStatus prstatus;
795 Status status = prstatus.Parse(note.data, arch);
796 if (status.Fail())
797 return status.ToError();
798 thread_data.prstatus_sig = prstatus.pr_cursig;
799 thread_data.tid = prstatus.pr_pid;
800 uint32_t header_size = ELFLinuxPrStatus::GetSize(arch);
801 size_t len = note.data.GetByteSize() - header_size;
802 thread_data.gpregset = DataExtractor(note.data, header_size, len);
803 break;
804 }
805 case ELF::NT_PRPSINFO: {
806 have_prpsinfo = true;
807 ELFLinuxPrPsInfo prpsinfo;
808 Status status = prpsinfo.Parse(note.data, arch);
809 if (status.Fail())
810 return status.ToError();
811 thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
812 SetID(prpsinfo.pr_pid);
813 break;
814 }
815 case ELF::NT_SIGINFO: {
816 ELFLinuxSigInfo siginfo;
817 Status status = siginfo.Parse(note.data, arch);
818 if (status.Fail())
819 return status.ToError();
820 thread_data.signo = siginfo.si_signo;
821 break;
822 }
823 case ELF::NT_FILE: {
824 m_nt_file_entries.clear();
825 lldb::offset_t offset = 0;
826 const uint64_t count = note.data.GetAddress(&offset);
827 note.data.GetAddress(&offset); // Skip page size
828 for (uint64_t i = 0; i < count; ++i) {
829 NT_FILE_Entry entry;
830 entry.start = note.data.GetAddress(&offset);
831 entry.end = note.data.GetAddress(&offset);
832 entry.file_ofs = note.data.GetAddress(&offset);
833 m_nt_file_entries.push_back(entry);
834 }
835 for (uint64_t i = 0; i < count; ++i) {
836 const char *path = note.data.GetCStr(&offset);
837 if (path && path[0])
838 m_nt_file_entries[i].path.SetCString(path);
839 }
840 break;
841 }
842 case ELF::NT_AUXV:
843 m_auxv = note.data;
844 break;
845 default:
846 thread_data.notes.push_back(note);
847 break;
848 }
849 }
850 // Add last entry in the note section
851 if (have_prstatus)
852 m_thread_data.push_back(thread_data);
853 return llvm::Error::success();
854 }
855
856 /// Parse Thread context from PT_NOTE segment and store it in the thread list
857 /// A note segment consists of one or more NOTE entries, but their types and
858 /// meaning differ depending on the OS.
ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader & segment_header,DataExtractor segment_data)859 llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
860 const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) {
861 assert(segment_header.p_type == llvm::ELF::PT_NOTE);
862
863 auto notes_or_error = parseSegment(segment_data);
864 if(!notes_or_error)
865 return notes_or_error.takeError();
866 switch (GetArchitecture().GetTriple().getOS()) {
867 case llvm::Triple::FreeBSD:
868 return parseFreeBSDNotes(*notes_or_error);
869 case llvm::Triple::Linux:
870 return parseLinuxNotes(*notes_or_error);
871 case llvm::Triple::NetBSD:
872 return parseNetBSDNotes(*notes_or_error);
873 case llvm::Triple::OpenBSD:
874 return parseOpenBSDNotes(*notes_or_error);
875 default:
876 return llvm::make_error<llvm::StringError>(
877 "Don't know how to parse core file. Unsupported OS.",
878 llvm::inconvertibleErrorCode());
879 }
880 }
881
GetNumThreadContexts()882 uint32_t ProcessElfCore::GetNumThreadContexts() {
883 if (!m_thread_data_valid)
884 DoLoadCore();
885 return m_thread_data.size();
886 }
887
GetArchitecture()888 ArchSpec ProcessElfCore::GetArchitecture() {
889 ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture();
890
891 ArchSpec target_arch = GetTarget().GetArchitecture();
892 arch.MergeFrom(target_arch);
893
894 // On MIPS there is no way to differentiate betwenn 32bit and 64bit core
895 // files and this information can't be merged in from the target arch so we
896 // fail back to unconditionally returning the target arch in this config.
897 if (target_arch.IsMIPS()) {
898 return target_arch;
899 }
900
901 return arch;
902 }
903
GetAuxvData()904 DataExtractor ProcessElfCore::GetAuxvData() {
905 const uint8_t *start = m_auxv.GetDataStart();
906 size_t len = m_auxv.GetByteSize();
907 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
908 return DataExtractor(buffer, GetByteOrder(), GetAddressByteSize());
909 }
910
GetProcessInfo(ProcessInstanceInfo & info)911 bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
912 info.Clear();
913 info.SetProcessID(GetID());
914 info.SetArchitecture(GetArchitecture());
915 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
916 if (module_sp) {
917 const bool add_exe_file_as_first_arg = false;
918 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
919 add_exe_file_as_first_arg);
920 }
921 return true;
922 }
923