1 //===-- ProcessMachCore.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 <errno.h>
12 #include <stdlib.h>
13 
14 // C++ Includes
15 #include "llvm/Support/MathExtras.h"
16 
17 // Other libraries and framework includes
18 #include "lldb/Core/DataBuffer.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/ModuleSpec.h"
23 #include "lldb/Core/Section.h"
24 #include "lldb/Core/State.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Symbol/ObjectFile.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 
30 // Project includes
31 #include "ProcessMachCore.h"
32 #include "ThreadMachCore.h"
33 #include "StopInfoMachException.h"
34 
35 // Needed for the plug-in names for the dynamic loaders.
36 #include "lldb/Utility/SafeMachO.h"
37 
38 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
39 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
40 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
41 
42 using namespace lldb;
43 using namespace lldb_private;
44 
45 ConstString
46 ProcessMachCore::GetPluginNameStatic()
47 {
48     static ConstString g_name("mach-o-core");
49     return g_name;
50 }
51 
52 const char *
53 ProcessMachCore::GetPluginDescriptionStatic()
54 {
55     return "Mach-O core file debugging plug-in.";
56 }
57 
58 void
59 ProcessMachCore::Terminate()
60 {
61     PluginManager::UnregisterPlugin (ProcessMachCore::CreateInstance);
62 }
63 
64 
65 lldb::ProcessSP
66 ProcessMachCore::CreateInstance (Target &target, Listener &listener, const FileSpec *crash_file)
67 {
68     lldb::ProcessSP process_sp;
69     if (crash_file)
70     {
71         const size_t header_size = sizeof(llvm::MachO::mach_header);
72         lldb::DataBufferSP data_sp (crash_file->ReadFileContents(0, header_size));
73         if (data_sp && data_sp->GetByteSize() == header_size)
74         {
75             DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
76 
77             lldb::offset_t data_offset = 0;
78             llvm::MachO::mach_header mach_header;
79             if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header))
80             {
81                 if (mach_header.filetype == llvm::MachO::MH_CORE)
82                     process_sp.reset(new ProcessMachCore (target, listener, *crash_file));
83             }
84         }
85 
86     }
87     return process_sp;
88 }
89 
90 bool
91 ProcessMachCore::CanDebug(Target &target, bool plugin_specified_by_name)
92 {
93     if (plugin_specified_by_name)
94         return true;
95 
96     // For now we are just making sure the file exists for a given module
97     if (!m_core_module_sp && m_core_file.Exists())
98     {
99         // Don't add the Target's architecture to the ModuleSpec - we may be working
100         // with a core file that doesn't have the correct cpusubtype in the header
101         // but we should still try to use it - ModuleSpecList::FindMatchingModuleSpec
102         // enforces a strict arch mach.
103         ModuleSpec core_module_spec(m_core_file);
104         Error error (ModuleList::GetSharedModule (core_module_spec,
105                                                   m_core_module_sp,
106                                                   NULL,
107                                                   NULL,
108                                                   NULL));
109 
110         if (m_core_module_sp)
111         {
112             const llvm::Triple &triple_ref = m_core_module_sp->GetArchitecture().GetTriple();
113             if (triple_ref.getVendor() == llvm::Triple::Apple)
114             {
115                 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
116                 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
117                     return true;
118             }
119         }
120     }
121     return false;
122 }
123 
124 //----------------------------------------------------------------------
125 // ProcessMachCore constructor
126 //----------------------------------------------------------------------
127 ProcessMachCore::ProcessMachCore(Target& target, Listener &listener, const FileSpec &core_file) :
128     Process (target, listener),
129     m_core_aranges (),
130     m_core_module_sp (),
131     m_core_file (core_file),
132     m_dyld_addr (LLDB_INVALID_ADDRESS),
133     m_mach_kernel_addr (LLDB_INVALID_ADDRESS),
134     m_dyld_plugin_name ()
135 {
136 }
137 
138 //----------------------------------------------------------------------
139 // Destructor
140 //----------------------------------------------------------------------
141 ProcessMachCore::~ProcessMachCore()
142 {
143     Clear();
144     // We need to call finalize on the process before destroying ourselves
145     // to make sure all of the broadcaster cleanup goes as planned. If we
146     // destruct this class, then Process::~Process() might have problems
147     // trying to fully destroy the broadcaster.
148     Finalize();
149 }
150 
151 //----------------------------------------------------------------------
152 // PluginInterface
153 //----------------------------------------------------------------------
154 ConstString
155 ProcessMachCore::GetPluginName()
156 {
157     return GetPluginNameStatic();
158 }
159 
160 uint32_t
161 ProcessMachCore::GetPluginVersion()
162 {
163     return 1;
164 }
165 
166 bool
167 ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
168 {
169     llvm::MachO::mach_header header;
170     Error error;
171     if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header))
172         return false;
173     if (header.magic == llvm::MachO::MH_CIGAM ||
174         header.magic == llvm::MachO::MH_CIGAM_64)
175     {
176         header.magic        = llvm::ByteSwap_32(header.magic);
177         header.cputype      = llvm::ByteSwap_32(header.cputype);
178         header.cpusubtype   = llvm::ByteSwap_32(header.cpusubtype);
179         header.filetype     = llvm::ByteSwap_32(header.filetype);
180         header.ncmds        = llvm::ByteSwap_32(header.ncmds);
181         header.sizeofcmds   = llvm::ByteSwap_32(header.sizeofcmds);
182         header.flags        = llvm::ByteSwap_32(header.flags);
183     }
184 
185     // TODO: swap header if needed...
186     //printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
187     if (header.magic == llvm::MachO::MH_MAGIC ||
188         header.magic == llvm::MachO::MH_MAGIC_64)
189     {
190         // Check MH_EXECUTABLE to see if we can find the mach image
191         // that contains the shared library list. The dynamic loader
192         // (dyld) is what contains the list for user applications,
193         // and the mach kernel contains a global that has the list
194         // of kexts to load
195         switch (header.filetype)
196         {
197         case llvm::MachO::MH_DYLINKER:
198             //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
199             // Address of dyld "struct mach_header" in the core file
200             m_dyld_addr = addr;
201             return true;
202 
203         case llvm::MachO::MH_EXECUTE:
204             //printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
205             // Check MH_EXECUTABLE file types to see if the dynamic link object flag
206             // is NOT set. If it isn't, then we have a mach_kernel.
207             if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0)
208             {
209                 // Address of the mach kernel "struct mach_header" in the core file.
210                 m_mach_kernel_addr = addr;
211                 return true;
212             }
213             break;
214         }
215     }
216     return false;
217 }
218 
219 //----------------------------------------------------------------------
220 // Process Control
221 //----------------------------------------------------------------------
222 Error
223 ProcessMachCore::DoLoadCore ()
224 {
225     Error error;
226     if (!m_core_module_sp)
227     {
228         error.SetErrorString ("invalid core module");
229         return error;
230     }
231 
232     ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
233     if (core_objfile == NULL)
234     {
235         error.SetErrorString ("invalid core object file");
236         return error;
237     }
238 
239     if (core_objfile->GetNumThreadContexts() == 0)
240     {
241         error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
242         return error;
243     }
244 
245     SectionList *section_list = core_objfile->GetSectionList();
246     if (section_list == NULL)
247     {
248         error.SetErrorString ("core file has no sections");
249         return error;
250     }
251 
252     const uint32_t num_sections = section_list->GetNumSections(0);
253     if (num_sections == 0)
254     {
255         error.SetErrorString ("core file has no sections");
256         return error;
257     }
258 
259     SetCanJIT(false);
260 
261     llvm::MachO::mach_header header;
262     DataExtractor data (&header,
263                         sizeof(header),
264                         m_core_module_sp->GetArchitecture().GetByteOrder(),
265                         m_core_module_sp->GetArchitecture().GetAddressByteSize());
266 
267     bool ranges_are_sorted = true;
268     addr_t vm_addr = 0;
269     for (uint32_t i=0; i<num_sections; ++i)
270     {
271         Section *section = section_list->GetSectionAtIndex (i).get();
272         if (section)
273         {
274             lldb::addr_t section_vm_addr = section->GetFileAddress();
275             FileRange file_range (section->GetFileOffset(), section->GetFileSize());
276             VMRangeToFileOffset::Entry range_entry (section_vm_addr,
277                                                     section->GetByteSize(),
278                                                     file_range);
279 
280             if (vm_addr > section_vm_addr)
281                 ranges_are_sorted = false;
282             vm_addr = section->GetFileAddress();
283             VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
284 //            printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
285 //                    i,
286 //                    range_entry.GetRangeBase(),
287 //                    range_entry.GetRangeEnd(),
288 //                    range_entry.data.GetRangeBase(),
289 //                    range_entry.data.GetRangeEnd());
290 
291             if (last_entry &&
292                 last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
293                 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
294             {
295                 last_entry->SetRangeEnd (range_entry.GetRangeEnd());
296                 last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
297                 //puts("combine");
298             }
299             else
300             {
301                 m_core_aranges.Append(range_entry);
302             }
303         }
304     }
305     if (!ranges_are_sorted)
306     {
307         m_core_aranges.Sort();
308     }
309 
310     if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)
311     {
312         // We need to locate the main executable in the memory ranges
313         // we have in the core file.  We need to search for both a user-process dyld binary
314         // and a kernel binary in memory; we must look at all the pages in the binary so
315         // we don't miss one or the other.  Step through all memory segments searching for
316         // a kernel binary and for a user process dyld -- we'll decide which to prefer
317         // later if both are present.
318 
319         const size_t num_core_aranges = m_core_aranges.GetSize();
320         for (size_t i = 0;
321              i < num_core_aranges && (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS);
322              ++i)
323         {
324             const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
325             lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
326             lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
327             for (lldb::addr_t section_vm_addr = section_vm_addr_start;
328                  section_vm_addr < section_vm_addr_end;
329                  section_vm_addr += 0x1000)
330             {
331                 GetDynamicLoaderAddress (section_vm_addr);
332             }
333         }
334     }
335 
336     // If we found both a user-process dyld and a kernel binary, we need to decide
337     // which to prefer.
338     if (GetCorefilePreference() == eKernelCorefile)
339     {
340         if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
341         {
342             m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
343         }
344         else if (m_dyld_addr != LLDB_INVALID_ADDRESS)
345         {
346             m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
347         }
348     }
349     else
350     {
351         if (m_dyld_addr != LLDB_INVALID_ADDRESS)
352         {
353             m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
354         }
355         else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
356         {
357             m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
358         }
359     }
360 
361     // Even if the architecture is set in the target, we need to override
362     // it to match the core file which is always single arch.
363     ArchSpec arch (m_core_module_sp->GetArchitecture());
364     if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
365     {
366         arch.SetTriple ("i386", m_target.GetPlatform().get());
367     }
368     if (arch.IsValid())
369         m_target.SetArchitecture(arch);
370 
371     return error;
372 }
373 
374 lldb_private::DynamicLoader *
375 ProcessMachCore::GetDynamicLoader ()
376 {
377     if (m_dyld_ap.get() == NULL)
378         m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
379     return m_dyld_ap.get();
380 }
381 
382 bool
383 ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
384 {
385     if (old_thread_list.GetSize(false) == 0)
386     {
387         // Make up the thread the first time this is called so we can setup our one and only
388         // core thread state.
389         ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
390 
391         if (core_objfile)
392         {
393             const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
394             for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
395             {
396                 ThreadSP thread_sp(new ThreadMachCore (*this, tid));
397                 new_thread_list.AddThread (thread_sp);
398             }
399         }
400     }
401     else
402     {
403         const uint32_t num_threads = old_thread_list.GetSize(false);
404         for (uint32_t i=0; i<num_threads; ++i)
405             new_thread_list.AddThread (old_thread_list.GetThreadAtIndex (i, false));
406     }
407     return new_thread_list.GetSize(false) > 0;
408 }
409 
410 void
411 ProcessMachCore::RefreshStateAfterStop ()
412 {
413     // Let all threads recover from stopping and do any clean up based
414     // on the previous thread state (if any).
415     m_thread_list.RefreshStateAfterStop();
416     //SetThreadStopInfo (m_last_stop_packet);
417 }
418 
419 Error
420 ProcessMachCore::DoDestroy ()
421 {
422     return Error();
423 }
424 
425 //------------------------------------------------------------------
426 // Process Queries
427 //------------------------------------------------------------------
428 
429 bool
430 ProcessMachCore::IsAlive ()
431 {
432     return true;
433 }
434 
435 bool
436 ProcessMachCore::WarnBeforeDetach () const
437 {
438     return false;
439 }
440 
441 //------------------------------------------------------------------
442 // Process Memory
443 //------------------------------------------------------------------
444 size_t
445 ProcessMachCore::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
446 {
447     // Don't allow the caching that lldb_private::Process::ReadMemory does
448     // since in core files we have it all cached our our core file anyway.
449     return DoReadMemory (addr, buf, size, error);
450 }
451 
452 size_t
453 ProcessMachCore::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
454 {
455     ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
456 
457     if (core_objfile)
458     {
459         const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains (addr);
460         if (core_memory_entry)
461         {
462             const addr_t offset = addr - core_memory_entry->GetRangeBase();
463             const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr;
464             size_t bytes_to_read = size;
465             if (bytes_to_read > bytes_left)
466                 bytes_to_read = bytes_left;
467             return core_objfile->CopyData (core_memory_entry->data.GetRangeBase() + offset, bytes_to_read, buf);
468         }
469         else
470         {
471             error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
472         }
473     }
474     return 0;
475 }
476 
477 void
478 ProcessMachCore::Clear()
479 {
480     m_thread_list.Clear();
481 }
482 
483 void
484 ProcessMachCore::Initialize()
485 {
486     static bool g_initialized = false;
487 
488     if (g_initialized == false)
489     {
490         g_initialized = true;
491         PluginManager::RegisterPlugin (GetPluginNameStatic(),
492                                        GetPluginDescriptionStatic(),
493                                        CreateInstance);
494     }
495 }
496 
497 addr_t
498 ProcessMachCore::GetImageInfoAddress()
499 {
500     // If we found both a user-process dyld and a kernel binary, we need to decide
501     // which to prefer.
502     if (GetCorefilePreference() == eKernelCorefile)
503     {
504         if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
505         {
506             return m_mach_kernel_addr;
507         }
508         return m_dyld_addr;
509     }
510     else
511     {
512         if (m_dyld_addr != LLDB_INVALID_ADDRESS)
513         {
514             return m_dyld_addr;
515         }
516         return m_mach_kernel_addr;
517     }
518 }
519 
520 
521 lldb_private::ObjectFile *
522 ProcessMachCore::GetCoreObjectFile ()
523 {
524     return m_core_module_sp->GetObjectFile();
525 }
526