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