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/PluginManager.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/ModuleSpec.h"
20 #include "lldb/Core/Section.h"
21 #include "lldb/Core/State.h"
22 #include "lldb/Core/DataBufferHeap.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/DynamicLoader.h"
26 #include "lldb/Target/UnixSignals.h"
27
28 #include "llvm/Support/ELF.h"
29
30 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
31 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
32
33 // Project includes
34 #include "ProcessElfCore.h"
35 #include "ThreadElfCore.h"
36
37 using namespace lldb_private;
38
39 ConstString
GetPluginNameStatic()40 ProcessElfCore::GetPluginNameStatic()
41 {
42 static ConstString g_name("elf-core");
43 return g_name;
44 }
45
46 const char *
GetPluginDescriptionStatic()47 ProcessElfCore::GetPluginDescriptionStatic()
48 {
49 return "ELF core dump plug-in.";
50 }
51
52 void
Terminate()53 ProcessElfCore::Terminate()
54 {
55 PluginManager::UnregisterPlugin (ProcessElfCore::CreateInstance);
56 }
57
58
59 lldb::ProcessSP
CreateInstance(Target & target,Listener & listener,const FileSpec * crash_file)60 ProcessElfCore::CreateInstance (Target &target, Listener &listener, const FileSpec *crash_file)
61 {
62 lldb::ProcessSP process_sp;
63 if (crash_file)
64 {
65 // Read enough data for a ELF32 header or ELF64 header
66 const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
67
68 lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
69 if (data_sp && data_sp->GetByteSize() == header_size &&
70 elf::ELFHeader::MagicBytesMatch (data_sp->GetBytes()))
71 {
72 elf::ELFHeader elf_header;
73 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
74 lldb::offset_t data_offset = 0;
75 if (elf_header.Parse(data, &data_offset))
76 {
77 if (elf_header.e_type == llvm::ELF::ET_CORE)
78 process_sp.reset(new ProcessElfCore (target, listener, *crash_file));
79 }
80 }
81 }
82 return process_sp;
83 }
84
85 bool
CanDebug(Target & target,bool plugin_specified_by_name)86 ProcessElfCore::CanDebug(Target &target, bool plugin_specified_by_name)
87 {
88 // For now we are just making sure the file exists for a given module
89 if (!m_core_module_sp && m_core_file.Exists())
90 {
91 ModuleSpec core_module_spec(m_core_file, target.GetArchitecture());
92 Error error (ModuleList::GetSharedModule (core_module_spec, m_core_module_sp,
93 NULL, NULL, NULL));
94 if (m_core_module_sp)
95 {
96 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
97 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
98 return true;
99 }
100 }
101 return false;
102 }
103
104 //----------------------------------------------------------------------
105 // ProcessElfCore constructor
106 //----------------------------------------------------------------------
ProcessElfCore(Target & target,Listener & listener,const FileSpec & core_file)107 ProcessElfCore::ProcessElfCore(Target& target, Listener &listener,
108 const FileSpec &core_file) :
109 Process (target, listener),
110 m_core_module_sp (),
111 m_core_file (core_file),
112 m_dyld_plugin_name (),
113 m_os(llvm::Triple::UnknownOS),
114 m_thread_data_valid(false),
115 m_thread_data(),
116 m_core_aranges ()
117 {
118 }
119
120 //----------------------------------------------------------------------
121 // Destructor
122 //----------------------------------------------------------------------
~ProcessElfCore()123 ProcessElfCore::~ProcessElfCore()
124 {
125 Clear();
126 // We need to call finalize on the process before destroying ourselves
127 // to make sure all of the broadcaster cleanup goes as planned. If we
128 // destruct this class, then Process::~Process() might have problems
129 // trying to fully destroy the broadcaster.
130 Finalize();
131 }
132
133 //----------------------------------------------------------------------
134 // PluginInterface
135 //----------------------------------------------------------------------
136 ConstString
GetPluginName()137 ProcessElfCore::GetPluginName()
138 {
139 return GetPluginNameStatic();
140 }
141
142 uint32_t
GetPluginVersion()143 ProcessElfCore::GetPluginVersion()
144 {
145 return 1;
146 }
147
148 lldb::addr_t
AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader * header)149 ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header)
150 {
151 lldb::addr_t addr = header->p_vaddr;
152 FileRange file_range (header->p_offset, header->p_filesz);
153 VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
154
155 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
156 if (last_entry &&
157 last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
158 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
159 last_entry->GetByteSize() == last_entry->data.GetByteSize())
160 {
161 last_entry->SetRangeEnd (range_entry.GetRangeEnd());
162 last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
163 }
164 else
165 {
166 m_core_aranges.Append(range_entry);
167 }
168
169 return addr;
170 }
171
172 //----------------------------------------------------------------------
173 // Process Control
174 //----------------------------------------------------------------------
175 Error
DoLoadCore()176 ProcessElfCore::DoLoadCore ()
177 {
178 Error error;
179 if (!m_core_module_sp)
180 {
181 error.SetErrorString ("invalid core module");
182 return error;
183 }
184
185 ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
186 if (core == NULL)
187 {
188 error.SetErrorString ("invalid core object file");
189 return error;
190 }
191
192 const uint32_t num_segments = core->GetProgramHeaderCount();
193 if (num_segments == 0)
194 {
195 error.SetErrorString ("core file has no segments");
196 return error;
197 }
198
199 SetCanJIT(false);
200
201 m_thread_data_valid = true;
202
203 bool ranges_are_sorted = true;
204 lldb::addr_t vm_addr = 0;
205 /// Walk through segments and Thread and Address Map information.
206 /// PT_NOTE - Contains Thread and Register information
207 /// PT_LOAD - Contains a contiguous range of Process Address Space
208 for(uint32_t i = 1; i <= num_segments; i++)
209 {
210 const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
211 assert(header != NULL);
212
213 DataExtractor data = core->GetSegmentDataByIndex(i);
214
215 // Parse thread contexts and auxv structure
216 if (header->p_type == llvm::ELF::PT_NOTE)
217 ParseThreadContextsFromNoteSegment(header, data);
218
219 // PT_LOAD segments contains address map
220 if (header->p_type == llvm::ELF::PT_LOAD)
221 {
222 lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
223 if (vm_addr > last_addr)
224 ranges_are_sorted = false;
225 vm_addr = last_addr;
226 }
227 }
228
229 if (!ranges_are_sorted)
230 m_core_aranges.Sort();
231
232 // Even if the architecture is set in the target, we need to override
233 // it to match the core file which is always single arch.
234 ArchSpec arch (m_core_module_sp->GetArchitecture());
235 if (arch.IsValid())
236 m_target.SetArchitecture(arch);
237
238 SetUnixSignals(UnixSignals::Create(GetArchitecture()));
239
240 return error;
241 }
242
243 lldb_private::DynamicLoader *
GetDynamicLoader()244 ProcessElfCore::GetDynamicLoader ()
245 {
246 if (m_dyld_ap.get() == NULL)
247 m_dyld_ap.reset (DynamicLoader::FindPlugin(this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
248 return m_dyld_ap.get();
249 }
250
251 bool
UpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)252 ProcessElfCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
253 {
254 const uint32_t num_threads = GetNumThreadContexts ();
255 if (!m_thread_data_valid)
256 return false;
257
258 for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
259 {
260 const ThreadData &td = m_thread_data[tid];
261 lldb::ThreadSP thread_sp(new ThreadElfCore (*this, tid, td));
262 new_thread_list.AddThread (thread_sp);
263 }
264 return new_thread_list.GetSize(false) > 0;
265 }
266
267 void
RefreshStateAfterStop()268 ProcessElfCore::RefreshStateAfterStop ()
269 {
270 }
271
272 Error
DoDestroy()273 ProcessElfCore::DoDestroy ()
274 {
275 return Error();
276 }
277
278 //------------------------------------------------------------------
279 // Process Queries
280 //------------------------------------------------------------------
281
282 bool
IsAlive()283 ProcessElfCore::IsAlive ()
284 {
285 return true;
286 }
287
288 //------------------------------------------------------------------
289 // Process Memory
290 //------------------------------------------------------------------
291 size_t
ReadMemory(lldb::addr_t addr,void * buf,size_t size,Error & error)292 ProcessElfCore::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
293 {
294 // Don't allow the caching that lldb_private::Process::ReadMemory does
295 // since in core files we have it all cached our our core file anyway.
296 return DoReadMemory (addr, buf, size, error);
297 }
298
299 size_t
DoReadMemory(lldb::addr_t addr,void * buf,size_t size,Error & error)300 ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
301 {
302 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
303
304 if (core_objfile == NULL)
305 return 0;
306
307 // Get the address range
308 const VMRangeToFileOffset::Entry *address_range = m_core_aranges.FindEntryThatContains (addr);
309 if (address_range == NULL || address_range->GetRangeEnd() < addr)
310 {
311 error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
312 return 0;
313 }
314
315 // Convert the address into core file offset
316 const lldb::addr_t offset = addr - address_range->GetRangeBase();
317 const lldb::addr_t file_start = address_range->data.GetRangeBase();
318 const lldb::addr_t file_end = address_range->data.GetRangeEnd();
319 size_t bytes_to_read = size; // Number of bytes to read from the core file
320 size_t bytes_copied = 0; // Number of bytes actually read from the core file
321 size_t zero_fill_size = 0; // Padding
322 lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address
323
324 // Figure out how many on-disk bytes remain in this segment
325 // starting at the given offset
326 if (file_end > file_start + offset)
327 bytes_left = file_end - (file_start + offset);
328
329 // Figure out how many bytes we need to zero-fill if we are
330 // reading more bytes than available in the on-disk segment
331 if (bytes_to_read > bytes_left)
332 {
333 zero_fill_size = bytes_to_read - bytes_left;
334 bytes_to_read = bytes_left;
335 }
336
337 // If there is data available on the core file read it
338 if (bytes_to_read)
339 bytes_copied = core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
340
341 assert(zero_fill_size <= size);
342 // Pad remaining bytes
343 if (zero_fill_size)
344 memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
345
346 return bytes_copied + zero_fill_size;
347 }
348
349 void
Clear()350 ProcessElfCore::Clear()
351 {
352 m_thread_list.Clear();
353 m_os = llvm::Triple::UnknownOS;
354
355 static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>();
356 SetUnixSignals(s_default_unix_signals_sp);
357 }
358
359 void
Initialize()360 ProcessElfCore::Initialize()
361 {
362 static std::once_flag g_once_flag;
363
364 std::call_once(g_once_flag, []()
365 {
366 PluginManager::RegisterPlugin (GetPluginNameStatic(),
367 GetPluginDescriptionStatic(), CreateInstance);
368 });
369 }
370
371 lldb::addr_t
GetImageInfoAddress()372 ProcessElfCore::GetImageInfoAddress()
373 {
374 Target *target = &GetTarget();
375 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
376 Address addr = obj_file->GetImageInfoAddress(target);
377
378 if (addr.IsValid())
379 return addr.GetLoadAddress(target);
380 return LLDB_INVALID_ADDRESS;
381 }
382
383 /// Core files PT_NOTE segment descriptor types
384 enum {
385 NT_PRSTATUS = 1,
386 NT_FPREGSET,
387 NT_PRPSINFO,
388 NT_TASKSTRUCT,
389 NT_PLATFORM,
390 NT_AUXV
391 };
392
393 namespace FREEBSD {
394
395 enum {
396 NT_PRSTATUS = 1,
397 NT_FPREGSET,
398 NT_PRPSINFO,
399 NT_THRMISC = 7,
400 NT_PROCSTAT_AUXV = 16,
401 NT_PPC_VMX = 0x100
402 };
403
404 }
405
406 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
407 static void
ParseFreeBSDPrStatus(ThreadData & thread_data,DataExtractor & data,ArchSpec & arch)408 ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
409 ArchSpec &arch)
410 {
411 lldb::offset_t offset = 0;
412 bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
413 arch.GetMachine() == llvm::Triple::mips64 ||
414 arch.GetMachine() == llvm::Triple::ppc64 ||
415 arch.GetMachine() == llvm::Triple::x86_64);
416 int pr_version = data.GetU32(&offset);
417
418 Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
419 if (log)
420 {
421 if (pr_version > 1)
422 log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
423 }
424
425 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
426 if (lp64)
427 offset += 32;
428 else
429 offset += 16;
430
431 thread_data.signo = data.GetU32(&offset); // pr_cursig
432 offset += 4; // pr_pid
433 if (lp64)
434 offset += 4;
435
436 size_t len = data.GetByteSize() - offset;
437 thread_data.gpregset = DataExtractor(data, offset, len);
438 }
439
440 static void
ParseFreeBSDThrMisc(ThreadData & thread_data,DataExtractor & data)441 ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data)
442 {
443 lldb::offset_t offset = 0;
444 thread_data.name = data.GetCStr(&offset, 20);
445 }
446
447 /// Parse Thread context from PT_NOTE segment and store it in the thread list
448 /// Notes:
449 /// 1) A PT_NOTE segment is composed of one or more NOTE entries.
450 /// 2) NOTE Entry contains a standard header followed by variable size data.
451 /// (see ELFNote structure)
452 /// 3) A Thread Context in a core file usually described by 3 NOTE entries.
453 /// a) NT_PRSTATUS - Register context
454 /// b) NT_PRPSINFO - Process info(pid..)
455 /// c) NT_FPREGSET - Floating point registers
456 /// 4) The NOTE entries can be in any order
457 /// 5) If a core file contains multiple thread contexts then there is two data forms
458 /// a) Each thread context(2 or more NOTE entries) contained in its own segment (PT_NOTE)
459 /// b) All thread context is stored in a single segment(PT_NOTE).
460 /// This case is little tricker since while parsing we have to find where the
461 /// new thread starts. The current implementation marks beginning of
462 /// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
463 /// For case (b) there may be either one NT_PRPSINFO per thread, or a single
464 /// one that applies to all threads (depending on the platform type).
465 void
ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader * segment_header,DataExtractor segment_data)466 ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *segment_header,
467 DataExtractor segment_data)
468 {
469 assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
470
471 lldb::offset_t offset = 0;
472 std::unique_ptr<ThreadData> thread_data(new ThreadData);
473 bool have_prstatus = false;
474 bool have_prpsinfo = false;
475
476 ArchSpec arch = GetArchitecture();
477 ELFLinuxPrPsInfo prpsinfo;
478 ELFLinuxPrStatus prstatus;
479 size_t header_size;
480 size_t len;
481
482 // Loop through the NOTE entires in the segment
483 while (offset < segment_header->p_filesz)
484 {
485 ELFNote note = ELFNote();
486 note.Parse(segment_data, &offset);
487
488 // Beginning of new thread
489 if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
490 (note.n_type == NT_PRPSINFO && have_prpsinfo))
491 {
492 assert(thread_data->gpregset.GetByteSize() > 0);
493 // Add the new thread to thread list
494 m_thread_data.push_back(*thread_data);
495 *thread_data = ThreadData();
496 have_prstatus = false;
497 have_prpsinfo = false;
498 }
499
500 size_t note_start, note_size;
501 note_start = offset;
502 note_size = llvm::RoundUpToAlignment(note.n_descsz, 4);
503
504 // Store the NOTE information in the current thread
505 DataExtractor note_data (segment_data, note_start, note_size);
506 if (note.n_name == "FreeBSD")
507 {
508 m_os = llvm::Triple::FreeBSD;
509 switch (note.n_type)
510 {
511 case FREEBSD::NT_PRSTATUS:
512 have_prstatus = true;
513 ParseFreeBSDPrStatus(*thread_data, note_data, arch);
514 break;
515 case FREEBSD::NT_FPREGSET:
516 thread_data->fpregset = note_data;
517 break;
518 case FREEBSD::NT_PRPSINFO:
519 have_prpsinfo = true;
520 break;
521 case FREEBSD::NT_THRMISC:
522 ParseFreeBSDThrMisc(*thread_data, note_data);
523 break;
524 case FREEBSD::NT_PROCSTAT_AUXV:
525 // FIXME: FreeBSD sticks an int at the beginning of the note
526 m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
527 break;
528 case FREEBSD::NT_PPC_VMX:
529 thread_data->vregset = note_data;
530 break;
531 default:
532 break;
533 }
534 }
535 else
536 {
537 switch (note.n_type)
538 {
539 case NT_PRSTATUS:
540 have_prstatus = true;
541 prstatus.Parse(note_data, arch);
542 thread_data->signo = prstatus.pr_cursig;
543 header_size = ELFLinuxPrStatus::GetSize(arch);
544 len = note_data.GetByteSize() - header_size;
545 thread_data->gpregset = DataExtractor(note_data, header_size, len);
546 break;
547 case NT_FPREGSET:
548 thread_data->fpregset = note_data;
549 break;
550 case NT_PRPSINFO:
551 have_prpsinfo = true;
552 prpsinfo.Parse(note_data, arch);
553 thread_data->name = prpsinfo.pr_fname;
554 break;
555 case NT_AUXV:
556 m_auxv = DataExtractor(note_data);
557 break;
558 default:
559 break;
560 }
561 }
562
563 offset += note_size;
564 }
565 // Add last entry in the note section
566 if (thread_data && thread_data->gpregset.GetByteSize() > 0)
567 {
568 m_thread_data.push_back(*thread_data);
569 }
570 }
571
572 uint32_t
GetNumThreadContexts()573 ProcessElfCore::GetNumThreadContexts ()
574 {
575 if (!m_thread_data_valid)
576 DoLoadCore();
577 return m_thread_data.size();
578 }
579
580 ArchSpec
GetArchitecture()581 ProcessElfCore::GetArchitecture()
582 {
583 ObjectFileELF *core_file = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
584 ArchSpec arch;
585 core_file->GetArchitecture(arch);
586 return arch;
587 }
588
589 const lldb::DataBufferSP
GetAuxvData()590 ProcessElfCore::GetAuxvData()
591 {
592 const uint8_t *start = m_auxv.GetDataStart();
593 size_t len = m_auxv.GetByteSize();
594 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
595 return buffer;
596 }
597