1 //===-- ProcessElfCore.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 #include <stdlib.h>
12 
13 // C++ Includes
14 #include <mutex>
15 
16 // Other libraries and framework includes
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/Section.h"
21 #include "lldb/Core/State.h"
22 #include "lldb/Target/DynamicLoader.h"
23 #include "lldb/Target/MemoryRegionInfo.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/UnixSignals.h"
26 #include "lldb/Utility/DataBufferHeap.h"
27 #include "lldb/Utility/DataBufferLLVM.h"
28 #include "lldb/Utility/Log.h"
29 
30 #include "llvm/BinaryFormat/ELF.h"
31 #include "llvm/Support/Threading.h"
32 
33 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
34 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
35 
36 // Project includes
37 #include "ProcessElfCore.h"
38 #include "ThreadElfCore.h"
39 #include "elf-core-enums.h"
40 
41 using namespace lldb_private;
42 
43 ConstString ProcessElfCore::GetPluginNameStatic() {
44   static ConstString g_name("elf-core");
45   return g_name;
46 }
47 
48 const char *ProcessElfCore::GetPluginDescriptionStatic() {
49   return "ELF core dump plug-in.";
50 }
51 
52 void ProcessElfCore::Terminate() {
53   PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance);
54 }
55 
56 lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
57                                                lldb::ListenerSP listener_sp,
58                                                const FileSpec *crash_file) {
59   lldb::ProcessSP process_sp;
60   if (crash_file) {
61     // Read enough data for a ELF32 header or ELF64 header
62     // Note: Here we care about e_type field only, so it is safe
63     // to ignore possible presence of the header extension.
64     const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
65 
66     auto data_sp = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(),
67                                                        header_size, 0);
68     if (data_sp && data_sp->GetByteSize() == header_size &&
69         elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
70       elf::ELFHeader elf_header;
71       DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
72       lldb::offset_t data_offset = 0;
73       if (elf_header.Parse(data, &data_offset)) {
74         if (elf_header.e_type == llvm::ELF::ET_CORE)
75           process_sp.reset(
76               new ProcessElfCore(target_sp, listener_sp, *crash_file));
77       }
78     }
79   }
80   return process_sp;
81 }
82 
83 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
84                               bool plugin_specified_by_name) {
85   // For now we are just making sure the file exists for a given module
86   if (!m_core_module_sp && m_core_file.Exists()) {
87     ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
88     Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
89                                              NULL, NULL, NULL));
90     if (m_core_module_sp) {
91       ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
92       if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
93         return true;
94     }
95   }
96   return false;
97 }
98 
99 //----------------------------------------------------------------------
100 // ProcessElfCore constructor
101 //----------------------------------------------------------------------
102 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
103                                lldb::ListenerSP listener_sp,
104                                const FileSpec &core_file)
105     : Process(target_sp, listener_sp), m_core_module_sp(),
106       m_core_file(core_file), m_dyld_plugin_name(),
107       m_os(llvm::Triple::UnknownOS), m_thread_data_valid(false),
108       m_thread_data(), m_core_aranges() {}
109 
110 //----------------------------------------------------------------------
111 // Destructor
112 //----------------------------------------------------------------------
113 ProcessElfCore::~ProcessElfCore() {
114   Clear();
115   // We need to call finalize on the process before destroying ourselves
116   // to make sure all of the broadcaster cleanup goes as planned. If we
117   // destruct this class, then Process::~Process() might have problems
118   // trying to fully destroy the broadcaster.
119   Finalize();
120 }
121 
122 //----------------------------------------------------------------------
123 // PluginInterface
124 //----------------------------------------------------------------------
125 ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); }
126 
127 uint32_t ProcessElfCore::GetPluginVersion() { return 1; }
128 
129 lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
130     const elf::ELFProgramHeader *header) {
131   const lldb::addr_t addr = header->p_vaddr;
132   FileRange file_range(header->p_offset, header->p_filesz);
133   VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
134 
135   VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
136   if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
137       last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
138       last_entry->GetByteSize() == last_entry->data.GetByteSize()) {
139     last_entry->SetRangeEnd(range_entry.GetRangeEnd());
140     last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
141   } else {
142     m_core_aranges.Append(range_entry);
143   }
144 
145   // Keep a separate map of permissions that that isn't coalesced so all ranges
146   // are maintained.
147   const uint32_t permissions =
148       ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
149       ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
150       ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
151 
152   m_core_range_infos.Append(
153       VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
154 
155   return addr;
156 }
157 
158 //----------------------------------------------------------------------
159 // Process Control
160 //----------------------------------------------------------------------
161 Status ProcessElfCore::DoLoadCore() {
162   Status error;
163   if (!m_core_module_sp) {
164     error.SetErrorString("invalid core module");
165     return error;
166   }
167 
168   ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
169   if (core == NULL) {
170     error.SetErrorString("invalid core object file");
171     return error;
172   }
173 
174   const uint32_t num_segments = core->GetProgramHeaderCount();
175   if (num_segments == 0) {
176     error.SetErrorString("core file has no segments");
177     return error;
178   }
179 
180   SetCanJIT(false);
181 
182   m_thread_data_valid = true;
183 
184   bool ranges_are_sorted = true;
185   lldb::addr_t vm_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   for (uint32_t i = 1; i <= num_segments; i++) {
190     const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
191     assert(header != NULL);
192 
193     DataExtractor data = core->GetSegmentDataByIndex(i);
194 
195     // Parse thread contexts and auxv structure
196     if (header->p_type == llvm::ELF::PT_NOTE) {
197       error = ParseThreadContextsFromNoteSegment(header, data);
198       if (error.Fail())
199         return error;
200     }
201     // PT_LOAD segments contains address map
202     if (header->p_type == llvm::ELF::PT_LOAD) {
203       lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
204       if (vm_addr > last_addr)
205         ranges_are_sorted = false;
206       vm_addr = last_addr;
207     }
208   }
209 
210   if (!ranges_are_sorted) {
211     m_core_aranges.Sort();
212     m_core_range_infos.Sort();
213   }
214 
215   // Even if the architecture is set in the target, we need to override
216   // it to match the core file which is always single arch.
217   ArchSpec arch(m_core_module_sp->GetArchitecture());
218 
219   ArchSpec target_arch = GetTarget().GetArchitecture();
220   ArchSpec core_arch(m_core_module_sp->GetArchitecture());
221   target_arch.MergeFrom(core_arch);
222   GetTarget().SetArchitecture(target_arch);
223 
224   SetUnixSignals(UnixSignals::Create(GetArchitecture()));
225 
226   // Ensure we found at least one thread that was stopped on a signal.
227   bool siginfo_signal_found = false;
228   bool prstatus_signal_found = false;
229   // Check we found a signal in a SIGINFO note.
230   for (const auto &thread_data : m_thread_data) {
231     if (thread_data.signo != 0)
232       siginfo_signal_found = true;
233     if (thread_data.prstatus_sig != 0)
234       prstatus_signal_found = true;
235   }
236   if (!siginfo_signal_found) {
237     // If we don't have signal from SIGINFO use the signal from each threads
238     // PRSTATUS note.
239     if (prstatus_signal_found) {
240       for (auto &thread_data : m_thread_data)
241         thread_data.signo = thread_data.prstatus_sig;
242     } else if (m_thread_data.size() > 0) {
243       // If all else fails force the first thread to be SIGSTOP
244       m_thread_data.begin()->signo =
245           GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
246     }
247   }
248 
249   // Core files are useless without the main executable. See if we can locate
250   // the main
251   // executable using data we found in the core file notes.
252   lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
253   if (!exe_module_sp) {
254     // The first entry in the NT_FILE might be our executable
255     if (!m_nt_file_entries.empty()) {
256       ModuleSpec exe_module_spec;
257       exe_module_spec.GetArchitecture() = arch;
258       exe_module_spec.GetFileSpec().SetFile(
259           m_nt_file_entries[0].path.GetCString(), false);
260       if (exe_module_spec.GetFileSpec()) {
261         exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
262         if (exe_module_sp)
263           GetTarget().SetExecutableModule(exe_module_sp, false);
264       }
265     }
266   }
267   return error;
268 }
269 
270 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
271   if (m_dyld_ap.get() == NULL)
272     m_dyld_ap.reset(DynamicLoader::FindPlugin(
273         this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
274   return m_dyld_ap.get();
275 }
276 
277 bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list,
278                                       ThreadList &new_thread_list) {
279   const uint32_t num_threads = GetNumThreadContexts();
280   if (!m_thread_data_valid)
281     return false;
282 
283   for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
284     const ThreadData &td = m_thread_data[tid];
285     lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td));
286     new_thread_list.AddThread(thread_sp);
287   }
288   return new_thread_list.GetSize(false) > 0;
289 }
290 
291 void ProcessElfCore::RefreshStateAfterStop() {}
292 
293 Status ProcessElfCore::DoDestroy() { return Status(); }
294 
295 //------------------------------------------------------------------
296 // Process Queries
297 //------------------------------------------------------------------
298 
299 bool ProcessElfCore::IsAlive() { return true; }
300 
301 //------------------------------------------------------------------
302 // Process Memory
303 //------------------------------------------------------------------
304 size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
305                                   Status &error) {
306   // Don't allow the caching that lldb_private::Process::ReadMemory does
307   // since in core files we have it all cached our our core file anyway.
308   return DoReadMemory(addr, buf, size, error);
309 }
310 
311 Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
312                                            MemoryRegionInfo &region_info) {
313   region_info.Clear();
314   const VMRangeToPermissions::Entry *permission_entry =
315       m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
316   if (permission_entry) {
317     if (permission_entry->Contains(load_addr)) {
318       region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
319       region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
320       const Flags permissions(permission_entry->data);
321       region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable)
322                                   ? MemoryRegionInfo::eYes
323                                   : MemoryRegionInfo::eNo);
324       region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable)
325                                   ? MemoryRegionInfo::eYes
326                                   : MemoryRegionInfo::eNo);
327       region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable)
328                                     ? MemoryRegionInfo::eYes
329                                     : MemoryRegionInfo::eNo);
330       region_info.SetMapped(MemoryRegionInfo::eYes);
331     } else if (load_addr < permission_entry->GetRangeBase()) {
332       region_info.GetRange().SetRangeBase(load_addr);
333       region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
334       region_info.SetReadable(MemoryRegionInfo::eNo);
335       region_info.SetWritable(MemoryRegionInfo::eNo);
336       region_info.SetExecutable(MemoryRegionInfo::eNo);
337       region_info.SetMapped(MemoryRegionInfo::eNo);
338     }
339     return Status();
340   }
341 
342   region_info.GetRange().SetRangeBase(load_addr);
343   region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
344   region_info.SetReadable(MemoryRegionInfo::eNo);
345   region_info.SetWritable(MemoryRegionInfo::eNo);
346   region_info.SetExecutable(MemoryRegionInfo::eNo);
347   region_info.SetMapped(MemoryRegionInfo::eNo);
348   return Status();
349 }
350 
351 size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
352                                     Status &error) {
353   ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
354 
355   if (core_objfile == NULL)
356     return 0;
357 
358   // Get the address range
359   const VMRangeToFileOffset::Entry *address_range =
360       m_core_aranges.FindEntryThatContains(addr);
361   if (address_range == NULL || address_range->GetRangeEnd() < addr) {
362     error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64,
363                                    addr);
364     return 0;
365   }
366 
367   // Convert the address into core file offset
368   const lldb::addr_t offset = addr - address_range->GetRangeBase();
369   const lldb::addr_t file_start = address_range->data.GetRangeBase();
370   const lldb::addr_t file_end = address_range->data.GetRangeEnd();
371   size_t bytes_to_read = size; // Number of bytes to read from the core file
372   size_t bytes_copied = 0;   // Number of bytes actually read from the core file
373   size_t zero_fill_size = 0; // Padding
374   lldb::addr_t bytes_left =
375       0; // Number of bytes available in the core file from the given address
376 
377   // Don't proceed if core file doesn't contain the actual data for this address range.
378   if (file_start == file_end)
379     return 0;
380 
381   // Figure out how many on-disk bytes remain in this segment
382   // starting at the given offset
383   if (file_end > file_start + offset)
384     bytes_left = file_end - (file_start + offset);
385 
386   // Figure out how many bytes we need to zero-fill if we are
387   // reading more bytes than available in the on-disk segment
388   if (bytes_to_read > bytes_left) {
389     zero_fill_size = bytes_to_read - bytes_left;
390     bytes_to_read = bytes_left;
391   }
392 
393   // If there is data available on the core file read it
394   if (bytes_to_read)
395     bytes_copied =
396         core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
397 
398   assert(zero_fill_size <= size);
399   // Pad remaining bytes
400   if (zero_fill_size)
401     memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
402 
403   return bytes_copied + zero_fill_size;
404 }
405 
406 void ProcessElfCore::Clear() {
407   m_thread_list.Clear();
408   m_os = llvm::Triple::UnknownOS;
409 
410   SetUnixSignals(std::make_shared<UnixSignals>());
411 }
412 
413 void ProcessElfCore::Initialize() {
414   static llvm::once_flag g_once_flag;
415 
416   llvm::call_once(g_once_flag, []() {
417     PluginManager::RegisterPlugin(GetPluginNameStatic(),
418                                   GetPluginDescriptionStatic(), CreateInstance);
419   });
420 }
421 
422 lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
423   ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
424   Address addr = obj_file->GetImageInfoAddress(&GetTarget());
425 
426   if (addr.IsValid())
427     return addr.GetLoadAddress(&GetTarget());
428   return LLDB_INVALID_ADDRESS;
429 }
430 
431 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
432 static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
433                                  ArchSpec &arch) {
434   lldb::offset_t offset = 0;
435   bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
436                arch.GetMachine() == llvm::Triple::mips64 ||
437                arch.GetMachine() == llvm::Triple::ppc64 ||
438                arch.GetMachine() == llvm::Triple::x86_64);
439   int pr_version = data.GetU32(&offset);
440 
441   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
442   if (log) {
443     if (pr_version > 1)
444       log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
445   }
446 
447   // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
448   if (lp64)
449     offset += 32;
450   else
451     offset += 16;
452 
453   thread_data.signo = data.GetU32(&offset); // pr_cursig
454   thread_data.tid = data.GetU32(&offset);   // pr_pid
455   if (lp64)
456     offset += 4;
457 
458   size_t len = data.GetByteSize() - offset;
459   thread_data.gpregset = DataExtractor(data, offset, len);
460 }
461 
462 static void ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) {
463   lldb::offset_t offset = 0;
464   thread_data.name = data.GetCStr(&offset, 20);
465 }
466 
467 static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
468   lldb::offset_t offset = 0;
469 
470   int version = data.GetU32(&offset);
471   if (version != 1)
472     return;
473 
474   offset += 4;
475   thread_data.signo = data.GetU32(&offset);
476 }
477 
478 static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
479   lldb::offset_t offset = 0;
480 
481   int version = data.GetU32(&offset);
482   if (version != 1)
483     return;
484 
485   offset += 4;
486   thread_data.signo = data.GetU32(&offset);
487 }
488 
489 /// Parse Thread context from PT_NOTE segment and store it in the thread list
490 /// Notes:
491 /// 1) A PT_NOTE segment is composed of one or more NOTE entries.
492 /// 2) NOTE Entry contains a standard header followed by variable size data.
493 ///   (see ELFNote structure)
494 /// 3) A Thread Context in a core file usually described by 3 NOTE entries.
495 ///    a) NT_PRSTATUS - Register context
496 ///    b) NT_PRPSINFO - Process info(pid..)
497 ///    c) NT_FPREGSET - Floating point registers
498 /// 4) The NOTE entries can be in any order
499 /// 5) If a core file contains multiple thread contexts then there is two data
500 /// forms
501 ///    a) Each thread context(2 or more NOTE entries) contained in its own
502 ///    segment (PT_NOTE)
503 ///    b) All thread context is stored in a single segment(PT_NOTE).
504 ///        This case is little tricker since while parsing we have to find where
505 ///        the
506 ///        new thread starts. The current implementation marks beginning of
507 ///        new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
508 ///    For case (b) there may be either one NT_PRPSINFO per thread, or a single
509 ///    one that applies to all threads (depending on the platform type).
510 Status ProcessElfCore::ParseThreadContextsFromNoteSegment(
511     const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
512   assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
513 
514   lldb::offset_t offset = 0;
515   std::unique_ptr<ThreadData> thread_data(new ThreadData);
516   bool have_prstatus = false;
517   bool have_prpsinfo = false;
518 
519   ArchSpec arch = GetArchitecture();
520   ELFLinuxPrPsInfo prpsinfo;
521   ELFLinuxPrStatus prstatus;
522   ELFLinuxSigInfo siginfo;
523   size_t header_size;
524   size_t len;
525   Status error;
526 
527   // Loop through the NOTE entires in the segment
528   while (offset < segment_header->p_filesz) {
529     ELFNote note = ELFNote();
530     note.Parse(segment_data, &offset);
531 
532     // Beginning of new thread
533     if (((note.n_type == LINUX::NT_PRSTATUS ||
534           note.n_type == FREEBSD::NT_PRSTATUS) &&
535          have_prstatus) ||
536         ((note.n_type == LINUX::NT_PRPSINFO ||
537           note.n_type == FREEBSD::NT_PRPSINFO) &&
538          have_prpsinfo)) {
539       assert(thread_data->gpregset.GetByteSize() > 0);
540       // Add the new thread to thread list
541       m_thread_data.push_back(*thread_data);
542       *thread_data = ThreadData();
543       have_prstatus = false;
544       have_prpsinfo = false;
545     }
546 
547     size_t note_start, note_size;
548     note_start = offset;
549     note_size = llvm::alignTo(note.n_descsz, 4);
550 
551     // Store the NOTE information in the current thread
552     DataExtractor note_data(segment_data, note_start, note_size);
553     note_data.SetAddressByteSize(
554         m_core_module_sp->GetArchitecture().GetAddressByteSize());
555     if (note.n_name == "FreeBSD") {
556       m_os = llvm::Triple::FreeBSD;
557       switch (note.n_type) {
558       case FREEBSD::NT_PRSTATUS:
559         have_prstatus = true;
560         ParseFreeBSDPrStatus(*thread_data, note_data, arch);
561         break;
562       case FREEBSD::NT_FPREGSET:
563         thread_data->fpregset = note_data;
564         break;
565       case FREEBSD::NT_PRPSINFO:
566         have_prpsinfo = true;
567         break;
568       case FREEBSD::NT_THRMISC:
569         ParseFreeBSDThrMisc(*thread_data, note_data);
570         break;
571       case FREEBSD::NT_PROCSTAT_AUXV:
572         // FIXME: FreeBSD sticks an int at the beginning of the note
573         m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
574         break;
575       case FREEBSD::NT_PPC_VMX:
576         thread_data->vregset = note_data;
577         break;
578       default:
579         break;
580       }
581     } else if (note.n_name.substr(0, 11) == "NetBSD-CORE") {
582       // NetBSD per-thread information is stored in notes named
583       // "NetBSD-CORE@nnn" so match on the initial part of the string.
584       m_os = llvm::Triple::NetBSD;
585       if (note.n_type == NETBSD::NT_PROCINFO) {
586         ParseNetBSDProcInfo(*thread_data, note_data);
587       } else if (note.n_type == NETBSD::NT_AUXV) {
588         m_auxv = DataExtractor(note_data);
589       } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
590                  note.n_type == NETBSD::NT_AMD64_REGS) {
591         thread_data->gpregset = note_data;
592       } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
593                  note.n_type == NETBSD::NT_AMD64_FPREGS) {
594         thread_data->fpregset = note_data;
595       }
596     } else if (note.n_name.substr(0, 7) == "OpenBSD") {
597       // OpenBSD per-thread information is stored in notes named
598       // "OpenBSD@nnn" so match on the initial part of the string.
599       m_os = llvm::Triple::OpenBSD;
600       switch (note.n_type) {
601       case OPENBSD::NT_PROCINFO:
602         ParseOpenBSDProcInfo(*thread_data, note_data);
603         break;
604       case OPENBSD::NT_AUXV:
605         m_auxv = DataExtractor(note_data);
606         break;
607       case OPENBSD::NT_REGS:
608         thread_data->gpregset = note_data;
609         break;
610       case OPENBSD::NT_FPREGS:
611         thread_data->fpregset = note_data;
612         break;
613       }
614     } else if (note.n_name == "CORE") {
615       switch (note.n_type) {
616       case LINUX::NT_PRSTATUS:
617         have_prstatus = true;
618         error = prstatus.Parse(note_data, arch);
619         if (error.Fail())
620           return error;
621         thread_data->prstatus_sig = prstatus.pr_cursig;
622         thread_data->tid = prstatus.pr_pid;
623         header_size = ELFLinuxPrStatus::GetSize(arch);
624         len = note_data.GetByteSize() - header_size;
625         thread_data->gpregset = DataExtractor(note_data, header_size, len);
626 
627         if (arch.GetCore() == ArchSpec::eCore_ppc64le_generic)
628           thread_data->regsets.insert(
629               std::make_pair(note.n_type, thread_data->gpregset));
630         break;
631       case LINUX::NT_FPREGSET:
632         // In a i386 core file NT_FPREGSET is present, but it's not the result
633         // of the FXSAVE instruction like in 64 bit files.
634         // The result from FXSAVE is in NT_PRXFPREG for i386 core files
635         if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64 || arch.IsMIPS())
636           thread_data->fpregset = note_data;
637         else if (arch.GetCore() == ArchSpec::eCore_ppc64le_generic) {
638           thread_data->regsets.insert(std::make_pair(note.n_type, note_data));
639         }
640         break;
641       case LINUX::NT_PRPSINFO:
642         have_prpsinfo = true;
643         error = prpsinfo.Parse(note_data, arch);
644         if (error.Fail())
645           return error;
646         thread_data->name = prpsinfo.pr_fname;
647         SetID(prpsinfo.pr_pid);
648         break;
649       case LINUX::NT_AUXV:
650         m_auxv = DataExtractor(note_data);
651         break;
652       case LINUX::NT_FILE: {
653         m_nt_file_entries.clear();
654         lldb::offset_t offset = 0;
655         const uint64_t count = note_data.GetAddress(&offset);
656         note_data.GetAddress(&offset); // Skip page size
657         for (uint64_t i = 0; i < count; ++i) {
658           NT_FILE_Entry entry;
659           entry.start = note_data.GetAddress(&offset);
660           entry.end = note_data.GetAddress(&offset);
661           entry.file_ofs = note_data.GetAddress(&offset);
662           m_nt_file_entries.push_back(entry);
663         }
664         for (uint64_t i = 0; i < count; ++i) {
665           const char *path = note_data.GetCStr(&offset);
666           if (path && path[0])
667             m_nt_file_entries[i].path.SetCString(path);
668         }
669       } break;
670       case LINUX::NT_SIGINFO: {
671         error = siginfo.Parse(note_data, arch);
672         if (error.Fail())
673           return error;
674         thread_data->signo = siginfo.si_signo;
675       } break;
676       default:
677         break;
678       }
679     } else if (note.n_name == "LINUX") {
680       switch (note.n_type) {
681       case LINUX::NT_PRXFPREG:
682         thread_data->fpregset = note_data;
683         break;
684       case LINUX::NT_PPC_VMX:
685       case LINUX::NT_PPC_VSX:
686         if (arch.GetCore() == ArchSpec::eCore_ppc64le_generic)
687           thread_data->regsets.insert(std::make_pair(note.n_type, note_data));
688         break;
689       }
690     }
691 
692     offset += note_size;
693   }
694   // Add last entry in the note section
695   if (thread_data && thread_data->gpregset.GetByteSize() > 0) {
696     m_thread_data.push_back(*thread_data);
697   }
698 
699   return error;
700 }
701 
702 uint32_t ProcessElfCore::GetNumThreadContexts() {
703   if (!m_thread_data_valid)
704     DoLoadCore();
705   return m_thread_data.size();
706 }
707 
708 ArchSpec ProcessElfCore::GetArchitecture() {
709   ArchSpec arch;
710   m_core_module_sp->GetObjectFile()->GetArchitecture(arch);
711 
712   ArchSpec target_arch = GetTarget().GetArchitecture();
713   arch.MergeFrom(target_arch);
714 
715   // On MIPS there is no way to differentiate betwenn 32bit and 64bit core files
716   // and this information can't be merged in from the target arch so we fail
717   // back to unconditionally returning the target arch in this config.
718   if (target_arch.IsMIPS()) {
719     return target_arch;
720   }
721 
722   return arch;
723 }
724 
725 const lldb::DataBufferSP ProcessElfCore::GetAuxvData() {
726   const uint8_t *start = m_auxv.GetDataStart();
727   size_t len = m_auxv.GetByteSize();
728   lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
729   return buffer;
730 }
731 
732 bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) {
733   info.Clear();
734   info.SetProcessID(GetID());
735   info.SetArchitecture(GetArchitecture());
736   lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
737   if (module_sp) {
738     const bool add_exe_file_as_first_arg = false;
739     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
740                            add_exe_file_as_first_arg);
741   }
742   return true;
743 }
744