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