1 //===-- ProcessElfCore.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
13 // Other libraries and framework includes
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleSpec.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Core/DataBufferHeap.h"
20 #include "lldb/Core/Log.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/DynamicLoader.h"
23 #include "lldb/Target/UnixSignals.h"
25 #include "llvm/Support/ELF.h"
27 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
28 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
29 #include "Plugins/Process/Utility/FreeBSDSignals.h"
30 #include "Plugins/Process/Utility/LinuxSignals.h"
33 #include "ProcessElfCore.h"
34 #include "ThreadElfCore.h"
36 using namespace lldb_private;
39 ProcessElfCore::GetPluginNameStatic()
41 static ConstString g_name("elf-core");
46 ProcessElfCore::GetPluginDescriptionStatic()
48 return "ELF core dump plug-in.";
52 ProcessElfCore::Terminate()
54 PluginManager::UnregisterPlugin (ProcessElfCore::CreateInstance);
59 ProcessElfCore::CreateInstance (Target &target, Listener &listener, const FileSpec *crash_file)
61 lldb::ProcessSP process_sp;
64 // Read enough data for a ELF32 header or ELF64 header
65 const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
67 lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
68 if (data_sp && data_sp->GetByteSize() == header_size &&
69 elf::ELFHeader::MagicBytesMatch (data_sp->GetBytes()))
71 elf::ELFHeader elf_header;
72 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
73 lldb::offset_t data_offset = 0;
74 if (elf_header.Parse(data, &data_offset))
76 if (elf_header.e_type == llvm::ELF::ET_CORE)
77 process_sp.reset(new ProcessElfCore (target, listener, *crash_file));
85 ProcessElfCore::CanDebug(Target &target, bool plugin_specified_by_name)
87 // For now we are just making sure the file exists for a given module
88 if (!m_core_module_sp && m_core_file.Exists())
90 ModuleSpec core_module_spec(m_core_file, target.GetArchitecture());
91 Error error (ModuleList::GetSharedModule (core_module_spec, m_core_module_sp,
95 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
96 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
103 //----------------------------------------------------------------------
104 // ProcessElfCore constructor
105 //----------------------------------------------------------------------
106 ProcessElfCore::ProcessElfCore(Target& target, Listener &listener,
107 const FileSpec &core_file) :
108 Process (target, listener),
110 m_core_file (core_file),
111 m_dyld_plugin_name (),
112 m_os(llvm::Triple::UnknownOS),
113 m_thread_data_valid(false),
119 //----------------------------------------------------------------------
121 //----------------------------------------------------------------------
122 ProcessElfCore::~ProcessElfCore()
125 // We need to call finalize on the process before destroying ourselves
126 // to make sure all of the broadcaster cleanup goes as planned. If we
127 // destruct this class, then Process::~Process() might have problems
128 // trying to fully destroy the broadcaster.
132 //----------------------------------------------------------------------
134 //----------------------------------------------------------------------
136 ProcessElfCore::GetPluginName()
138 return GetPluginNameStatic();
142 ProcessElfCore::GetPluginVersion()
148 ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header)
150 lldb::addr_t addr = header->p_vaddr;
151 FileRange file_range (header->p_offset, header->p_filesz);
152 VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
154 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
156 last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
157 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() &&
158 last_entry->GetByteSize() == last_entry->data.GetByteSize())
160 last_entry->SetRangeEnd (range_entry.GetRangeEnd());
161 last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
165 m_core_aranges.Append(range_entry);
171 //----------------------------------------------------------------------
173 //----------------------------------------------------------------------
175 ProcessElfCore::DoLoadCore ()
178 if (!m_core_module_sp)
180 error.SetErrorString ("invalid core module");
184 ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
187 error.SetErrorString ("invalid core object file");
191 const uint32_t num_segments = core->GetProgramHeaderCount();
192 if (num_segments == 0)
194 error.SetErrorString ("core file has no sections");
200 m_thread_data_valid = true;
202 bool ranges_are_sorted = true;
203 lldb::addr_t vm_addr = 0;
204 /// Walk through segments and Thread and Address Map information.
205 /// PT_NOTE - Contains Thread and Register information
206 /// PT_LOAD - Contains a contiguous range of Process Address Space
207 for(uint32_t i = 1; i <= num_segments; i++)
209 const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
210 assert(header != NULL);
212 DataExtractor data = core->GetSegmentDataByIndex(i);
214 // Parse thread contexts and auxv structure
215 if (header->p_type == llvm::ELF::PT_NOTE)
216 ParseThreadContextsFromNoteSegment(header, data);
218 // PT_LOAD segments contains address map
219 if (header->p_type == llvm::ELF::PT_LOAD)
221 lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
222 if (vm_addr > last_addr)
223 ranges_are_sorted = false;
228 if (!ranges_are_sorted)
229 m_core_aranges.Sort();
231 // Even if the architecture is set in the target, we need to override
232 // it to match the core file which is always single arch.
233 ArchSpec arch (m_core_module_sp->GetArchitecture());
235 m_target.SetArchitecture(arch);
239 case llvm::Triple::FreeBSD:
241 static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals ());
242 SetUnixSignals(s_freebsd_signals_sp);
245 case llvm::Triple::Linux:
247 static UnixSignalsSP s_linux_signals_sp(new process_linux::LinuxSignals ());
248 SetUnixSignals(s_linux_signals_sp);
258 lldb_private::DynamicLoader *
259 ProcessElfCore::GetDynamicLoader ()
261 if (m_dyld_ap.get() == NULL)
262 m_dyld_ap.reset (DynamicLoader::FindPlugin(this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString()));
263 return m_dyld_ap.get();
267 ProcessElfCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
269 const uint32_t num_threads = GetNumThreadContexts ();
270 if (!m_thread_data_valid)
273 for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
275 const ThreadData &td = m_thread_data[tid];
276 lldb::ThreadSP thread_sp(new ThreadElfCore (*this, tid, td));
277 new_thread_list.AddThread (thread_sp);
279 return new_thread_list.GetSize(false) > 0;
283 ProcessElfCore::RefreshStateAfterStop ()
288 ProcessElfCore::DoDestroy ()
293 //------------------------------------------------------------------
295 //------------------------------------------------------------------
298 ProcessElfCore::IsAlive ()
303 //------------------------------------------------------------------
305 //------------------------------------------------------------------
307 ProcessElfCore::ReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
309 // Don't allow the caching that lldb_private::Process::ReadMemory does
310 // since in core files we have it all cached our our core file anyway.
311 return DoReadMemory (addr, buf, size, error);
315 ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
317 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
319 if (core_objfile == NULL)
322 // Get the address range
323 const VMRangeToFileOffset::Entry *address_range = m_core_aranges.FindEntryThatContains (addr);
324 if (address_range == NULL || address_range->GetRangeEnd() < addr)
326 error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
330 // Convert the address into core file offset
331 const lldb::addr_t offset = addr - address_range->GetRangeBase();
332 const lldb::addr_t file_start = address_range->data.GetRangeBase();
333 const lldb::addr_t file_end = address_range->data.GetRangeEnd();
334 size_t bytes_to_read = size; // Number of bytes to read from the core file
335 size_t bytes_copied = 0; // Number of bytes actually read from the core file
336 size_t zero_fill_size = 0; // Padding
337 lldb::addr_t bytes_left = 0; // Number of bytes available in the core file from the given address
339 // Figure out how many on-disk bytes remain in this segment
340 // starting at the given offset
341 if (file_end > file_start + offset)
342 bytes_left = file_end - (file_start + offset);
344 // Figure out how many bytes we need to zero-fill if we are
345 // reading more bytes than available in the on-disk segment
346 if (bytes_to_read > bytes_left)
348 zero_fill_size = bytes_to_read - bytes_left;
349 bytes_to_read = bytes_left;
352 // If there is data available on the core file read it
354 bytes_copied = core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
356 assert(zero_fill_size <= size);
357 // Pad remaining bytes
359 memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
361 return bytes_copied + zero_fill_size;
365 ProcessElfCore::Clear()
367 m_thread_list.Clear();
368 m_os = llvm::Triple::UnknownOS;
370 static UnixSignalsSP s_default_unix_signals_sp(new UnixSignals());
371 SetUnixSignals(s_default_unix_signals_sp);
375 ProcessElfCore::Initialize()
377 static bool g_initialized = false;
379 if (g_initialized == false)
381 g_initialized = true;
382 PluginManager::RegisterPlugin (GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
387 ProcessElfCore::GetImageInfoAddress()
389 Target *target = &GetTarget();
390 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
391 Address addr = obj_file->GetImageInfoAddress(target);
394 return addr.GetLoadAddress(target);
395 return LLDB_INVALID_ADDRESS;
398 /// Core files PT_NOTE segment descriptor types
409 NT_FREEBSD_PRSTATUS = 1,
412 NT_FREEBSD_THRMISC = 7,
413 NT_FREEBSD_PROCSTAT_AUXV = 16
416 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
418 ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
421 lldb::offset_t offset = 0;
422 bool lp64 = (arch.GetMachine() == llvm::Triple::mips64 ||
423 arch.GetMachine() == llvm::Triple::x86_64);
424 int pr_version = data.GetU32(&offset);
426 Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
430 log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version);
433 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate
439 thread_data.signo = data.GetU32(&offset); // pr_cursig
440 offset += 4; // pr_pid
444 size_t len = data.GetByteSize() - offset;
445 thread_data.gpregset = DataExtractor(data, offset, len);
449 ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data)
451 lldb::offset_t offset = 0;
452 thread_data.name = data.GetCStr(&offset, 20);
455 /// Parse Thread context from PT_NOTE segment and store it in the thread list
457 /// 1) A PT_NOTE segment is composed of one or more NOTE entries.
458 /// 2) NOTE Entry contains a standard header followed by variable size data.
459 /// (see ELFNote structure)
460 /// 3) A Thread Context in a core file usually described by 3 NOTE entries.
461 /// a) NT_PRSTATUS - Register context
462 /// b) NT_PRPSINFO - Process info(pid..)
463 /// c) NT_FPREGSET - Floating point registers
464 /// 4) The NOTE entries can be in any order
465 /// 5) If a core file contains multiple thread contexts then there is two data forms
466 /// a) Each thread context(2 or more NOTE entries) contained in its own segment (PT_NOTE)
467 /// b) All thread context is stored in a single segment(PT_NOTE).
468 /// This case is little tricker since while parsing we have to find where the
469 /// new thread starts. The current implementation marks beginning of
470 /// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
471 /// For case (b) there may be either one NT_PRPSINFO per thread, or a single
472 /// one that applies to all threads (depending on the platform type).
474 ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *segment_header,
475 DataExtractor segment_data)
477 assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
479 lldb::offset_t offset = 0;
480 std::unique_ptr<ThreadData> thread_data(new ThreadData);
481 bool have_prstatus = false;
482 bool have_prpsinfo = false;
484 ArchSpec arch = GetArchitecture();
485 ELFLinuxPrPsInfo prpsinfo;
486 ELFLinuxPrStatus prstatus;
490 // Loop through the NOTE entires in the segment
491 while (offset < segment_header->p_filesz)
493 ELFNote note = ELFNote();
494 note.Parse(segment_data, &offset);
496 // Beginning of new thread
497 if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
498 (note.n_type == NT_PRPSINFO && have_prpsinfo))
500 assert(thread_data->gpregset.GetByteSize() > 0);
501 // Add the new thread to thread list
502 m_thread_data.push_back(*thread_data);
503 *thread_data = ThreadData();
504 have_prstatus = false;
505 have_prpsinfo = false;
508 size_t note_start, note_size;
510 note_size = llvm::RoundUpToAlignment(note.n_descsz, 4);
512 // Store the NOTE information in the current thread
513 DataExtractor note_data (segment_data, note_start, note_size);
514 if (note.n_name == "FreeBSD")
516 m_os = llvm::Triple::FreeBSD;
519 case NT_FREEBSD_PRSTATUS:
520 have_prstatus = true;
521 ParseFreeBSDPrStatus(*thread_data, note_data, arch);
523 case NT_FREEBSD_FPREGSET:
524 thread_data->fpregset = note_data;
526 case NT_FREEBSD_PRPSINFO:
527 have_prpsinfo = true;
529 case NT_FREEBSD_THRMISC:
530 ParseFreeBSDThrMisc(*thread_data, note_data);
532 case NT_FREEBSD_PROCSTAT_AUXV:
533 // FIXME: FreeBSD sticks an int at the beginning of the note
534 m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
545 have_prstatus = true;
546 prstatus.Parse(note_data, arch);
547 thread_data->signo = prstatus.pr_cursig;
548 header_size = ELFLinuxPrStatus::GetSize(arch);
549 len = note_data.GetByteSize() - header_size;
550 thread_data->gpregset = DataExtractor(note_data, header_size, len);
553 thread_data->fpregset = note_data;
556 have_prpsinfo = true;
557 prpsinfo.Parse(note_data, arch);
558 thread_data->name = prpsinfo.pr_fname;
561 m_auxv = DataExtractor(note_data);
570 // Add last entry in the note section
571 if (thread_data && thread_data->gpregset.GetByteSize() > 0)
573 m_thread_data.push_back(*thread_data);
578 ProcessElfCore::GetNumThreadContexts ()
580 if (!m_thread_data_valid)
582 return m_thread_data.size();
586 ProcessElfCore::GetArchitecture()
588 ObjectFileELF *core_file = (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
590 core_file->GetArchitecture(arch);
594 const lldb::DataBufferSP
595 ProcessElfCore::GetAuxvData()
597 const uint8_t *start = m_auxv.GetDataStart();
598 size_t len = m_auxv.GetByteSize();
599 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));