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