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