1 //===-- ProcessElfCore.cpp --------------------------------------*- 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 #include <stdlib.h>
10 
11 #include <mutex>
12 
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Target/DynamicLoader.h"
18 #include "lldb/Target/MemoryRegionInfo.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/UnixSignals.h"
21 #include "lldb/Utility/DataBufferHeap.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/State.h"
24 
25 #include "llvm/BinaryFormat/ELF.h"
26 #include "llvm/Support/Threading.h"
27 
28 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
29 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
30 #include "Plugins/Process/elf-core/RegisterUtilities.h"
31 #include "ProcessElfCore.h"
32 #include "ThreadElfCore.h"
33 
34 using namespace lldb_private;
35 
36 ConstString ProcessElfCore::GetPluginNameStatic() {
37   static ConstString g_name("elf-core");
38   return g_name;
39 }
40 
41 const char *ProcessElfCore::GetPluginDescriptionStatic() {
42   return "ELF core dump plug-in.";
43 }
44 
45 void ProcessElfCore::Terminate() {
46   PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance);
47 }
48 
49 lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
50                                                lldb::ListenerSP listener_sp,
51                                                const FileSpec *crash_file) {
52   lldb::ProcessSP process_sp;
53   if (crash_file) {
54     // Read enough data for a ELF32 header or ELF64 header Note: Here we care
55     // about e_type field only, so it is safe to ignore possible presence of
56     // the header extension.
57     const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
58 
59     auto data_sp = FileSystem::Instance().CreateDataBuffer(
60         crash_file->GetPath(), header_size, 0);
61     if (data_sp && data_sp->GetByteSize() == header_size &&
62         elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
63       elf::ELFHeader elf_header;
64       DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
65       lldb::offset_t data_offset = 0;
66       if (elf_header.Parse(data, &data_offset)) {
67         if (elf_header.e_type == llvm::ELF::ET_CORE)
68           process_sp.reset(
69               new ProcessElfCore(target_sp, listener_sp, *crash_file));
70       }
71     }
72   }
73   return process_sp;
74 }
75 
76 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
77                               bool plugin_specified_by_name) {
78   // For now we are just making sure the file exists for a given module
79   if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
80     ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
81     Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
82                                              NULL, NULL, NULL));
83     if (m_core_module_sp) {
84       ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
85       if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
86         return true;
87     }
88   }
89   return false;
90 }
91 
92 //----------------------------------------------------------------------
93 // ProcessElfCore constructor
94 //----------------------------------------------------------------------
95 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
96                                lldb::ListenerSP listener_sp,
97                                const FileSpec &core_file)
98     : Process(target_sp, listener_sp), m_core_file(core_file) {}
99 
100 //----------------------------------------------------------------------
101 // Destructor
102 //----------------------------------------------------------------------
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 //----------------------------------------------------------------------
113 // PluginInterface
114 //----------------------------------------------------------------------
115 ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); }
116 
117 uint32_t ProcessElfCore::GetPluginVersion() { return 1; }
118 
119 lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
120     const elf::ELFProgramHeader &header) {
121   const lldb::addr_t addr = header.p_vaddr;
122   FileRange file_range(header.p_offset, header.p_filesz);
123   VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range);
124 
125   VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
126   if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
127       last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
128       last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
129     last_entry->SetRangeEnd(range_entry.GetRangeEnd());
130     last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
131   } else {
132     m_core_aranges.Append(range_entry);
133   }
134 
135   // Keep a separate map of permissions that that isn't coalesced so all ranges
136   // are maintained.
137   const uint32_t permissions =
138       ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
139       ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
140       ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
141 
142   m_core_range_infos.Append(
143       VMRangeToPermissions::Entry(addr, header.p_memsz, permissions));
144 
145   return addr;
146 }
147 
148 //----------------------------------------------------------------------
149 // Process Control
150 //----------------------------------------------------------------------
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 == NULL) {
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().GetSharedModule(exe_module_spec);
247         if (exe_module_sp)
248           GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo);
249       }
250     }
251   }
252   return error;
253 }
254 
255 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
256   if (m_dyld_ap.get() == NULL)
257     m_dyld_ap.reset(DynamicLoader::FindPlugin(
258         this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
259   return m_dyld_ap.get();
260 }
261 
262 bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list,
263                                       ThreadList &new_thread_list) {
264   const uint32_t num_threads = GetNumThreadContexts();
265   if (!m_thread_data_valid)
266     return false;
267 
268   for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
269     const ThreadData &td = m_thread_data[tid];
270     lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td));
271     new_thread_list.AddThread(thread_sp);
272   }
273   return new_thread_list.GetSize(false) > 0;
274 }
275 
276 void ProcessElfCore::RefreshStateAfterStop() {}
277 
278 Status ProcessElfCore::DoDestroy() { return Status(); }
279 
280 //------------------------------------------------------------------
281 // Process Queries
282 //------------------------------------------------------------------
283 
284 bool ProcessElfCore::IsAlive() { return true; }
285 
286 //------------------------------------------------------------------
287 // Process Memory
288 //------------------------------------------------------------------
289 size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
290                                   Status &error) {
291   // Don't allow the caching that lldb_private::Process::ReadMemory does since
292   // in core files we have it all cached our our core file anyway.
293   return DoReadMemory(addr, buf, size, error);
294 }
295 
296 Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
297                                            MemoryRegionInfo &region_info) {
298   region_info.Clear();
299   const VMRangeToPermissions::Entry *permission_entry =
300       m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
301   if (permission_entry) {
302     if (permission_entry->Contains(load_addr)) {
303       region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
304       region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
305       const Flags permissions(permission_entry->data);
306       region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable)
307                                   ? MemoryRegionInfo::eYes
308                                   : MemoryRegionInfo::eNo);
309       region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable)
310                                   ? MemoryRegionInfo::eYes
311                                   : MemoryRegionInfo::eNo);
312       region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable)
313                                     ? MemoryRegionInfo::eYes
314                                     : MemoryRegionInfo::eNo);
315       region_info.SetMapped(MemoryRegionInfo::eYes);
316     } else if (load_addr < permission_entry->GetRangeBase()) {
317       region_info.GetRange().SetRangeBase(load_addr);
318       region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
319       region_info.SetReadable(MemoryRegionInfo::eNo);
320       region_info.SetWritable(MemoryRegionInfo::eNo);
321       region_info.SetExecutable(MemoryRegionInfo::eNo);
322       region_info.SetMapped(MemoryRegionInfo::eNo);
323     }
324     return Status();
325   }
326 
327   region_info.GetRange().SetRangeBase(load_addr);
328   region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
329   region_info.SetReadable(MemoryRegionInfo::eNo);
330   region_info.SetWritable(MemoryRegionInfo::eNo);
331   region_info.SetExecutable(MemoryRegionInfo::eNo);
332   region_info.SetMapped(MemoryRegionInfo::eNo);
333   return Status();
334 }
335 
336 size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
337                                     Status &error) {
338   ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
339 
340   if (core_objfile == NULL)
341     return 0;
342 
343   // Get the address range
344   const VMRangeToFileOffset::Entry *address_range =
345       m_core_aranges.FindEntryThatContains(addr);
346   if (address_range == NULL || address_range->GetRangeEnd() < addr) {
347     error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64,
348                                    addr);
349     return 0;
350   }
351 
352   // Convert the address into core file offset
353   const lldb::addr_t offset = addr - address_range->GetRangeBase();
354   const lldb::addr_t file_start = address_range->data.GetRangeBase();
355   const lldb::addr_t file_end = address_range->data.GetRangeEnd();
356   size_t bytes_to_read = size; // Number of bytes to read from the core file
357   size_t bytes_copied = 0;   // Number of bytes actually read from the core file
358   size_t zero_fill_size = 0; // Padding
359   lldb::addr_t bytes_left =
360       0; // Number of bytes available in the core file from the given address
361 
362   // Don't proceed if core file doesn't contain the actual data for this
363   // address range.
364   if (file_start == file_end)
365     return 0;
366 
367   // Figure out how many on-disk bytes remain in this segment starting at the
368   // given offset
369   if (file_end > file_start + offset)
370     bytes_left = file_end - (file_start + offset);
371 
372   // Figure out how many bytes we need to zero-fill if we are reading more
373   // bytes than available in the on-disk segment
374   if (bytes_to_read > bytes_left) {
375     zero_fill_size = bytes_to_read - bytes_left;
376     bytes_to_read = bytes_left;
377   }
378 
379   // If there is data available on the core file read it
380   if (bytes_to_read)
381     bytes_copied =
382         core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
383 
384   assert(zero_fill_size <= size);
385   // Pad remaining bytes
386   if (zero_fill_size)
387     memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
388 
389   return bytes_copied + zero_fill_size;
390 }
391 
392 void ProcessElfCore::Clear() {
393   m_thread_list.Clear();
394 
395   SetUnixSignals(std::make_shared<UnixSignals>());
396 }
397 
398 void ProcessElfCore::Initialize() {
399   static llvm::once_flag g_once_flag;
400 
401   llvm::call_once(g_once_flag, []() {
402     PluginManager::RegisterPlugin(GetPluginNameStatic(),
403                                   GetPluginDescriptionStatic(), CreateInstance);
404   });
405 }
406 
407 lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
408   ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
409   Address addr = obj_file->GetImageInfoAddress(&GetTarget());
410 
411   if (addr.IsValid())
412     return addr.GetLoadAddress(&GetTarget());
413   return LLDB_INVALID_ADDRESS;
414 }
415 
416 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
417 static void ParseFreeBSDPrStatus(ThreadData &thread_data,
418                                  const DataExtractor &data,
419                                  const ArchSpec &arch) {
420   lldb::offset_t offset = 0;
421   bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
422                arch.GetMachine() == llvm::Triple::mips64 ||
423                arch.GetMachine() == llvm::Triple::ppc64 ||
424                arch.GetMachine() == llvm::Triple::x86_64);
425   int pr_version = data.GetU32(&offset);
426 
427   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
428   if (log) {
429     if (pr_version > 1)
430       log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
431   }
432 
433   // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
434   if (lp64)
435     offset += 32;
436   else
437     offset += 16;
438 
439   thread_data.signo = data.GetU32(&offset); // pr_cursig
440   thread_data.tid = data.GetU32(&offset);   // pr_pid
441   if (lp64)
442     offset += 4;
443 
444   size_t len = data.GetByteSize() - offset;
445   thread_data.gpregset = DataExtractor(data, offset, len);
446 }
447 
448 static void ParseNetBSDProcInfo(ThreadData &thread_data,
449                                 const DataExtractor &data) {
450   lldb::offset_t offset = 0;
451 
452   int version = data.GetU32(&offset);
453   if (version != 1)
454     return;
455 
456   offset += 4;
457   thread_data.signo = data.GetU32(&offset);
458 }
459 
460 static void ParseOpenBSDProcInfo(ThreadData &thread_data,
461                                  const DataExtractor &data) {
462   lldb::offset_t offset = 0;
463 
464   int version = data.GetU32(&offset);
465   if (version != 1)
466     return;
467 
468   offset += 4;
469   thread_data.signo = data.GetU32(&offset);
470 }
471 
472 llvm::Expected<std::vector<CoreNote>>
473 ProcessElfCore::parseSegment(const DataExtractor &segment) {
474   lldb::offset_t offset = 0;
475   std::vector<CoreNote> result;
476 
477   while (offset < segment.GetByteSize()) {
478     ELFNote note = ELFNote();
479     if (!note.Parse(segment, &offset))
480       return llvm::make_error<llvm::StringError>(
481           "Unable to parse note segment", llvm::inconvertibleErrorCode());
482 
483     size_t note_start = offset;
484     size_t note_size = llvm::alignTo(note.n_descsz, 4);
485     DataExtractor note_data(segment, note_start, note_size);
486 
487     result.push_back({note, note_data});
488     offset += note_size;
489   }
490 
491   return std::move(result);
492 }
493 
494 llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
495   bool have_prstatus = false;
496   bool have_prpsinfo = false;
497   ThreadData thread_data;
498   for (const auto &note : notes) {
499     if (note.info.n_name != "FreeBSD")
500       continue;
501 
502     if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) ||
503         (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) {
504       assert(thread_data.gpregset.GetByteSize() > 0);
505       // Add the new thread to thread list
506       m_thread_data.push_back(thread_data);
507       thread_data = ThreadData();
508       have_prstatus = false;
509       have_prpsinfo = false;
510     }
511 
512     switch (note.info.n_type) {
513     case FREEBSD::NT_PRSTATUS:
514       have_prstatus = true;
515       ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
516       break;
517     case FREEBSD::NT_PRPSINFO:
518       have_prpsinfo = true;
519       break;
520     case FREEBSD::NT_THRMISC: {
521       lldb::offset_t offset = 0;
522       thread_data.name = note.data.GetCStr(&offset, 20);
523       break;
524     }
525     case FREEBSD::NT_PROCSTAT_AUXV:
526       // FIXME: FreeBSD sticks an int at the beginning of the note
527       m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
528       break;
529     default:
530       thread_data.notes.push_back(note);
531       break;
532     }
533   }
534   if (!have_prstatus) {
535     return llvm::make_error<llvm::StringError>(
536         "Could not find NT_PRSTATUS note in core file.",
537         llvm::inconvertibleErrorCode());
538   }
539   m_thread_data.push_back(thread_data);
540   return llvm::Error::success();
541 }
542 
543 llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
544   ThreadData thread_data;
545   for (const auto &note : notes) {
546     // NetBSD per-thread information is stored in notes named "NetBSD-CORE@nnn"
547     // so match on the initial part of the string.
548     if (!llvm::StringRef(note.info.n_name).startswith("NetBSD-CORE"))
549       continue;
550 
551     switch (note.info.n_type) {
552     case NETBSD::NT_PROCINFO:
553       ParseNetBSDProcInfo(thread_data, note.data);
554       break;
555     case NETBSD::NT_AUXV:
556       m_auxv = note.data;
557       break;
558 
559     case NETBSD::NT_AMD64_REGS:
560       if (GetArchitecture().GetMachine() == llvm::Triple::x86_64)
561         thread_data.gpregset = note.data;
562       break;
563     default:
564       thread_data.notes.push_back(note);
565       break;
566     }
567   }
568   if (thread_data.gpregset.GetByteSize() == 0) {
569     return llvm::make_error<llvm::StringError>(
570         "Could not find general purpose registers note in core file.",
571         llvm::inconvertibleErrorCode());
572   }
573   m_thread_data.push_back(thread_data);
574   return llvm::Error::success();
575 }
576 
577 llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
578   ThreadData thread_data;
579   for (const auto &note : notes) {
580     // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so
581     // match on the initial part of the string.
582     if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD"))
583       continue;
584 
585     switch (note.info.n_type) {
586     case OPENBSD::NT_PROCINFO:
587       ParseOpenBSDProcInfo(thread_data, note.data);
588       break;
589     case OPENBSD::NT_AUXV:
590       m_auxv = note.data;
591       break;
592     case OPENBSD::NT_REGS:
593       thread_data.gpregset = note.data;
594       break;
595     default:
596       thread_data.notes.push_back(note);
597       break;
598     }
599   }
600   if (thread_data.gpregset.GetByteSize() == 0) {
601     return llvm::make_error<llvm::StringError>(
602         "Could not find general purpose registers note in core file.",
603         llvm::inconvertibleErrorCode());
604   }
605   m_thread_data.push_back(thread_data);
606   return llvm::Error::success();
607 }
608 
609 /// A description of a linux process usually contains the following NOTE
610 /// entries:
611 /// - NT_PRPSINFO - General process information like pid, uid, name, ...
612 /// - NT_SIGINFO - Information about the signal that terminated the process
613 /// - NT_AUXV - Process auxiliary vector
614 /// - NT_FILE - Files mapped into memory
615 ///
616 /// Additionally, for each thread in the process the core file will contain at
617 /// least the NT_PRSTATUS note, containing the thread id and general purpose
618 /// registers. It may include additional notes for other register sets (floating
619 /// point and vector registers, ...). The tricky part here is that some of these
620 /// notes have "CORE" in their owner fields, while other set it to "LINUX".
621 llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
622   const ArchSpec &arch = GetArchitecture();
623   bool have_prstatus = false;
624   bool have_prpsinfo = false;
625   ThreadData thread_data;
626   for (const auto &note : notes) {
627     if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
628       continue;
629 
630     if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) ||
631         (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) {
632       assert(thread_data.gpregset.GetByteSize() > 0);
633       // Add the new thread to thread list
634       m_thread_data.push_back(thread_data);
635       thread_data = ThreadData();
636       have_prstatus = false;
637       have_prpsinfo = false;
638     }
639 
640     switch (note.info.n_type) {
641     case LINUX::NT_PRSTATUS: {
642       have_prstatus = true;
643       ELFLinuxPrStatus prstatus;
644       Status status = prstatus.Parse(note.data, arch);
645       if (status.Fail())
646         return status.ToError();
647       thread_data.prstatus_sig = prstatus.pr_cursig;
648       thread_data.tid = prstatus.pr_pid;
649       uint32_t header_size = ELFLinuxPrStatus::GetSize(arch);
650       size_t len = note.data.GetByteSize() - header_size;
651       thread_data.gpregset = DataExtractor(note.data, header_size, len);
652       break;
653     }
654     case LINUX::NT_PRPSINFO: {
655       have_prpsinfo = true;
656       ELFLinuxPrPsInfo prpsinfo;
657       Status status = prpsinfo.Parse(note.data, arch);
658       if (status.Fail())
659         return status.ToError();
660       thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
661       SetID(prpsinfo.pr_pid);
662       break;
663     }
664     case LINUX::NT_SIGINFO: {
665       ELFLinuxSigInfo siginfo;
666       Status status = siginfo.Parse(note.data, arch);
667       if (status.Fail())
668         return status.ToError();
669       thread_data.signo = siginfo.si_signo;
670       break;
671     }
672     case LINUX::NT_FILE: {
673       m_nt_file_entries.clear();
674       lldb::offset_t offset = 0;
675       const uint64_t count = note.data.GetAddress(&offset);
676       note.data.GetAddress(&offset); // Skip page size
677       for (uint64_t i = 0; i < count; ++i) {
678         NT_FILE_Entry entry;
679         entry.start = note.data.GetAddress(&offset);
680         entry.end = note.data.GetAddress(&offset);
681         entry.file_ofs = note.data.GetAddress(&offset);
682         m_nt_file_entries.push_back(entry);
683       }
684       for (uint64_t i = 0; i < count; ++i) {
685         const char *path = note.data.GetCStr(&offset);
686         if (path && path[0])
687           m_nt_file_entries[i].path.SetCString(path);
688       }
689       break;
690     }
691     case LINUX::NT_AUXV:
692       m_auxv = note.data;
693       break;
694     default:
695       thread_data.notes.push_back(note);
696       break;
697     }
698   }
699   // Add last entry in the note section
700   if (have_prstatus)
701     m_thread_data.push_back(thread_data);
702   return llvm::Error::success();
703 }
704 
705 /// Parse Thread context from PT_NOTE segment and store it in the thread list
706 /// A note segment consists of one or more NOTE entries, but their types and
707 /// meaning differ depending on the OS.
708 llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
709     const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) {
710   assert(segment_header.p_type == llvm::ELF::PT_NOTE);
711 
712   auto notes_or_error = parseSegment(segment_data);
713   if(!notes_or_error)
714     return notes_or_error.takeError();
715   switch (GetArchitecture().GetTriple().getOS()) {
716   case llvm::Triple::FreeBSD:
717     return parseFreeBSDNotes(*notes_or_error);
718   case llvm::Triple::Linux:
719     return parseLinuxNotes(*notes_or_error);
720   case llvm::Triple::NetBSD:
721     return parseNetBSDNotes(*notes_or_error);
722   case llvm::Triple::OpenBSD:
723     return parseOpenBSDNotes(*notes_or_error);
724   default:
725     return llvm::make_error<llvm::StringError>(
726         "Don't know how to parse core file. Unsupported OS.",
727         llvm::inconvertibleErrorCode());
728   }
729 }
730 
731 uint32_t ProcessElfCore::GetNumThreadContexts() {
732   if (!m_thread_data_valid)
733     DoLoadCore();
734   return m_thread_data.size();
735 }
736 
737 ArchSpec ProcessElfCore::GetArchitecture() {
738   ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture();
739 
740   ArchSpec target_arch = GetTarget().GetArchitecture();
741   arch.MergeFrom(target_arch);
742 
743   // On MIPS there is no way to differentiate betwenn 32bit and 64bit core
744   // files and this information can't be merged in from the target arch so we
745   // fail back to unconditionally returning the target arch in this config.
746   if (target_arch.IsMIPS()) {
747     return target_arch;
748   }
749 
750   return arch;
751 }
752 
753 const lldb::DataBufferSP ProcessElfCore::GetAuxvData() {
754   const uint8_t *start = m_auxv.GetDataStart();
755   size_t len = m_auxv.GetByteSize();
756   lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
757   return buffer;
758 }
759 
760 bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
761   info.Clear();
762   info.SetProcessID(GetID());
763   info.SetArchitecture(GetArchitecture());
764   lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
765   if (module_sp) {
766     const bool add_exe_file_as_first_arg = false;
767     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
768                            add_exe_file_as_first_arg);
769   }
770   return true;
771 }
772