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
GetPluginNameStatic()43 ProcessMachCore::GetPluginNameStatic()
44 {
45     static ConstString g_name("mach-o-core");
46     return g_name;
47 }
48 
49 const char *
GetPluginDescriptionStatic()50 ProcessMachCore::GetPluginDescriptionStatic()
51 {
52     return "Mach-O core file debugging plug-in.";
53 }
54 
55 void
Terminate()56 ProcessMachCore::Terminate()
57 {
58     PluginManager::UnregisterPlugin (ProcessMachCore::CreateInstance);
59 }
60 
61 
62 lldb::ProcessSP
CreateInstance(Target & target,Listener & listener,const FileSpec * crash_file)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
CanDebug(Target & target,bool plugin_specified_by_name)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 //----------------------------------------------------------------------
ProcessMachCore(Target & target,Listener & listener,const FileSpec & core_file)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_dyld_plugin_name ()
111 {
112 }
113 
114 //----------------------------------------------------------------------
115 // Destructor
116 //----------------------------------------------------------------------
~ProcessMachCore()117 ProcessMachCore::~ProcessMachCore()
118 {
119     Clear();
120     // We need to call finalize on the process before destroying ourselves
121     // to make sure all of the broadcaster cleanup goes as planned. If we
122     // destruct this class, then Process::~Process() might have problems
123     // trying to fully destroy the broadcaster.
124     Finalize();
125 }
126 
127 //----------------------------------------------------------------------
128 // PluginInterface
129 //----------------------------------------------------------------------
130 ConstString
GetPluginName()131 ProcessMachCore::GetPluginName()
132 {
133     return GetPluginNameStatic();
134 }
135 
136 uint32_t
GetPluginVersion()137 ProcessMachCore::GetPluginVersion()
138 {
139     return 1;
140 }
141 
142 bool
GetDynamicLoaderAddress(lldb::addr_t addr)143 ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
144 {
145     llvm::MachO::mach_header header;
146     Error error;
147     if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header))
148         return false;
149     if (header.magic == llvm::MachO::HeaderMagic32Swapped ||
150         header.magic == llvm::MachO::HeaderMagic64Swapped)
151     {
152         header.magic        = llvm::ByteSwap_32(header.magic);
153         header.cputype      = llvm::ByteSwap_32(header.cputype);
154         header.cpusubtype   = llvm::ByteSwap_32(header.cpusubtype);
155         header.filetype     = llvm::ByteSwap_32(header.filetype);
156         header.ncmds        = llvm::ByteSwap_32(header.ncmds);
157         header.sizeofcmds   = llvm::ByteSwap_32(header.sizeofcmds);
158         header.flags        = llvm::ByteSwap_32(header.flags);
159     }
160 
161     // TODO: swap header if needed...
162     //printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
163     if (header.magic == llvm::MachO::HeaderMagic32 ||
164         header.magic == llvm::MachO::HeaderMagic64)
165     {
166         // Check MH_EXECUTABLE to see if we can find the mach image
167         // that contains the shared library list. The dynamic loader
168         // (dyld) is what contains the list for user applications,
169         // and the mach kernel contains a global that has the list
170         // of kexts to load
171         switch (header.filetype)
172         {
173         case llvm::MachO::HeaderFileTypeDynamicLinkEditor:
174             //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
175             // Address of dyld "struct mach_header" in the core file
176             m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
177             m_dyld_addr = addr;
178             return true;
179 
180         case llvm::MachO::HeaderFileTypeExecutable:
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::HeaderFlagBitIsDynamicLinkObject) == 0)
185             {
186                 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
187                 // Address of the mach kernel "struct mach_header" in the core file.
188                 m_dyld_addr = addr;
189                 return true;
190             }
191             break;
192         }
193     }
194     return false;
195 }
196 
197 //----------------------------------------------------------------------
198 // Process Control
199 //----------------------------------------------------------------------
200 Error
DoLoadCore()201 ProcessMachCore::DoLoadCore ()
202 {
203     Error error;
204     if (!m_core_module_sp)
205     {
206         error.SetErrorString ("invalid core module");
207         return error;
208     }
209 
210     ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
211     if (core_objfile == NULL)
212     {
213         error.SetErrorString ("invalid core object file");
214         return error;
215     }
216 
217     if (core_objfile->GetNumThreadContexts() == 0)
218     {
219         error.SetErrorString ("core file doesn't contain any LC_THREAD load commands, or the LC_THREAD architecture is not supported in this lldb");
220         return error;
221     }
222 
223     SectionList *section_list = core_objfile->GetSectionList();
224     if (section_list == NULL)
225     {
226         error.SetErrorString ("core file has no sections");
227         return error;
228     }
229 
230     const uint32_t num_sections = section_list->GetNumSections(0);
231     if (num_sections == 0)
232     {
233         error.SetErrorString ("core file has no sections");
234         return error;
235     }
236 
237     SetCanJIT(false);
238 
239     llvm::MachO::mach_header header;
240     DataExtractor data (&header,
241                         sizeof(header),
242                         m_core_module_sp->GetArchitecture().GetByteOrder(),
243                         m_core_module_sp->GetArchitecture().GetAddressByteSize());
244 
245     bool ranges_are_sorted = true;
246     addr_t vm_addr = 0;
247     for (uint32_t i=0; i<num_sections; ++i)
248     {
249         Section *section = section_list->GetSectionAtIndex (i).get();
250         if (section)
251         {
252             lldb::addr_t section_vm_addr = section->GetFileAddress();
253             FileRange file_range (section->GetFileOffset(), section->GetFileSize());
254             VMRangeToFileOffset::Entry range_entry (section_vm_addr,
255                                                     section->GetByteSize(),
256                                                     file_range);
257 
258             if (vm_addr > section_vm_addr)
259                 ranges_are_sorted = false;
260             vm_addr = section->GetFileAddress();
261             VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
262 //            printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
263 //                    i,
264 //                    range_entry.GetRangeBase(),
265 //                    range_entry.GetRangeEnd(),
266 //                    range_entry.data.GetRangeBase(),
267 //                    range_entry.data.GetRangeEnd());
268 
269             if (last_entry &&
270                 last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
271                 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
272             {
273                 last_entry->SetRangeEnd (range_entry.GetRangeEnd());
274                 last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
275                 //puts("combine");
276             }
277             else
278             {
279                 m_core_aranges.Append(range_entry);
280             }
281 
282             // After we have added this section to our m_core_aranges map,
283             // we can check the start of the section to see if it might
284             // contain dyld for user space apps, or the mach kernel file
285             // for kernel cores.
286             if (m_dyld_addr == LLDB_INVALID_ADDRESS)
287                 GetDynamicLoaderAddress (section_vm_addr);
288         }
289     }
290     if (!ranges_are_sorted)
291     {
292         m_core_aranges.Sort();
293     }
294 
295     // Even if the architecture is set in the target, we need to override
296     // it to match the core file which is always single arch.
297     ArchSpec arch (m_core_module_sp->GetArchitecture());
298     if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
299     {
300         arch.SetTriple ("i386", m_target.GetPlatform().get());
301     }
302     if (arch.IsValid())
303         m_target.SetArchitecture(arch);
304 
305     if (m_dyld_addr == LLDB_INVALID_ADDRESS)
306     {
307         // We need to locate the main executable in the memory ranges
308         // we have in the core file. We already checked the first address
309         // in each memory zone above, so we just need to check each page
310         // except the first page in each range and stop once we have found
311         // our main executable
312         const size_t num_core_aranges = m_core_aranges.GetSize();
313         for (size_t i=0; i<num_core_aranges && m_dyld_addr == LLDB_INVALID_ADDRESS; ++i)
314         {
315             const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
316             lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
317             lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
318             for (lldb::addr_t section_vm_addr = section_vm_addr_start + 0x1000;
319                  section_vm_addr < section_vm_addr_end;
320                  section_vm_addr += 0x1000)
321             {
322                 if (GetDynamicLoaderAddress (section_vm_addr))
323                 {
324                     break;
325                 }
326             }
327         }
328     }
329     return error;
330 }
331 
332 lldb_private::DynamicLoader *
GetDynamicLoader()333 ProcessMachCore::GetDynamicLoader ()
334 {
335     if (m_dyld_ap.get() == NULL)
336         m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
337     return m_dyld_ap.get();
338 }
339 
340 bool
UpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)341 ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
342 {
343     if (old_thread_list.GetSize(false) == 0)
344     {
345         // Make up the thread the first time this is called so we can setup our one and only
346         // core thread state.
347         ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
348 
349         if (core_objfile)
350         {
351             const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
352             for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
353             {
354                 ThreadSP thread_sp(new ThreadMachCore (*this, tid));
355                 new_thread_list.AddThread (thread_sp);
356             }
357         }
358     }
359     else
360     {
361         const uint32_t num_threads = old_thread_list.GetSize(false);
362         for (uint32_t i=0; i<num_threads; ++i)
363             new_thread_list.AddThread (old_thread_list.GetThreadAtIndex (i));
364     }
365     return new_thread_list.GetSize(false) > 0;
366 }
367 
368 void
RefreshStateAfterStop()369 ProcessMachCore::RefreshStateAfterStop ()
370 {
371     // Let all threads recover from stopping and do any clean up based
372     // on the previous thread state (if any).
373     m_thread_list.RefreshStateAfterStop();
374     //SetThreadStopInfo (m_last_stop_packet);
375 }
376 
377 Error
DoDestroy()378 ProcessMachCore::DoDestroy ()
379 {
380     return Error();
381 }
382 
383 //------------------------------------------------------------------
384 // Process Queries
385 //------------------------------------------------------------------
386 
387 bool
IsAlive()388 ProcessMachCore::IsAlive ()
389 {
390     return true;
391 }
392 
393 bool
WarnBeforeDetach() const394 ProcessMachCore::WarnBeforeDetach () const
395 {
396     return false;
397 }
398 
399 //------------------------------------------------------------------
400 // Process Memory
401 //------------------------------------------------------------------
402 size_t
ReadMemory(addr_t addr,void * buf,size_t size,Error & error)403 ProcessMachCore::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
404 {
405     // Don't allow the caching that lldb_private::Process::ReadMemory does
406     // since in core files we have it all cached our our core file anyway.
407     return DoReadMemory (addr, buf, size, error);
408 }
409 
410 size_t
DoReadMemory(addr_t addr,void * buf,size_t size,Error & error)411 ProcessMachCore::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
412 {
413     ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
414 
415     if (core_objfile)
416     {
417         const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains (addr);
418         if (core_memory_entry)
419         {
420             const addr_t offset = addr - core_memory_entry->GetRangeBase();
421             const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr;
422             size_t bytes_to_read = size;
423             if (bytes_to_read > bytes_left)
424                 bytes_to_read = bytes_left;
425             return core_objfile->CopyData (core_memory_entry->data.GetRangeBase() + offset, bytes_to_read, buf);
426         }
427         else
428         {
429             error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
430         }
431     }
432     return 0;
433 }
434 
435 void
Clear()436 ProcessMachCore::Clear()
437 {
438     m_thread_list.Clear();
439 }
440 
441 void
Initialize()442 ProcessMachCore::Initialize()
443 {
444     static bool g_initialized = false;
445 
446     if (g_initialized == false)
447     {
448         g_initialized = true;
449         PluginManager::RegisterPlugin (GetPluginNameStatic(),
450                                        GetPluginDescriptionStatic(),
451                                        CreateInstance);
452     }
453 }
454 
455 addr_t
GetImageInfoAddress()456 ProcessMachCore::GetImageInfoAddress()
457 {
458     return m_dyld_addr;
459 }
460 
461 
462 lldb_private::ObjectFile *
GetCoreObjectFile()463 ProcessMachCore::GetCoreObjectFile ()
464 {
465     return m_core_module_sp->GetObjectFile();
466 }
467