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