1 //===-- JITLoaderGDB.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 12 #include "llvm/Support/MathExtras.h" 13 14 #include "lldb/Breakpoint/Breakpoint.h" 15 #include "lldb/Core/DataBufferHeap.h" 16 #include "lldb/Core/PluginManager.h" 17 #include "lldb/Core/Log.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/ModuleSpec.h" 20 #include "lldb/Core/Section.h" 21 #include "lldb/Core/StreamString.h" 22 #include "lldb/Interpreter/OptionValueProperties.h" 23 #include "lldb/Symbol/SymbolContext.h" 24 #include "lldb/Symbol/SymbolVendor.h" 25 #include "lldb/Target/Process.h" 26 #include "lldb/Target/SectionLoadList.h" 27 #include "lldb/Target/Target.h" 28 #include "lldb/Utility/LLDBAssert.h" 29 30 #include "JITLoaderGDB.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 //------------------------------------------------------------------ 36 // Debug Interface Structures 37 //------------------------------------------------------------------ 38 typedef enum 39 { 40 JIT_NOACTION = 0, 41 JIT_REGISTER_FN, 42 JIT_UNREGISTER_FN 43 } jit_actions_t; 44 45 template <typename ptr_t> 46 struct jit_code_entry 47 { 48 ptr_t next_entry; // pointer 49 ptr_t prev_entry; // pointer 50 ptr_t symfile_addr; // pointer 51 uint64_t symfile_size; 52 }; 53 54 template <typename ptr_t> 55 struct jit_descriptor 56 { 57 uint32_t version; 58 uint32_t action_flag; // Values are jit_action_t 59 ptr_t relevant_entry; // pointer 60 ptr_t first_entry; // pointer 61 }; 62 63 namespace { 64 65 PropertyDefinition 66 g_properties[] = 67 { 68 { "enable-jit-breakpoint", OptionValue::eTypeBoolean, true, true , nullptr, nullptr, "Enable breakpoint on __jit_debug_register_code." }, 69 { nullptr , OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr } 70 }; 71 72 enum 73 { 74 ePropertyEnableJITBreakpoint 75 }; 76 77 78 class PluginProperties : public Properties 79 { 80 public: 81 static ConstString 82 GetSettingName() 83 { 84 return JITLoaderGDB::GetPluginNameStatic(); 85 } 86 87 PluginProperties() 88 { 89 m_collection_sp.reset (new OptionValueProperties(GetSettingName())); 90 m_collection_sp->Initialize(g_properties); 91 } 92 93 bool 94 GetEnableJITBreakpoint() const 95 { 96 return m_collection_sp->GetPropertyAtIndexAsBoolean( 97 nullptr, 98 ePropertyEnableJITBreakpoint, 99 g_properties[ePropertyEnableJITBreakpoint].default_uint_value != 0); 100 } 101 102 }; 103 104 typedef std::shared_ptr<PluginProperties> JITLoaderGDBPropertiesSP; 105 106 static const JITLoaderGDBPropertiesSP& 107 GetGlobalPluginProperties() 108 { 109 static const auto g_settings_sp(std::make_shared<PluginProperties>()); 110 return g_settings_sp; 111 } 112 113 template <typename ptr_t> 114 bool ReadJITEntry(const addr_t from_addr, Process *process, jit_code_entry<ptr_t> *entry) 115 { 116 lldbassert(from_addr % sizeof(ptr_t) == 0); 117 118 ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore(); 119 bool i386_target = ArchSpec::kCore_x86_32_first <= core && core <= ArchSpec::kCore_x86_32_last; 120 uint8_t uint64_align_bytes = i386_target ? 4 : 8; 121 const size_t data_byte_size = llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t); 122 123 Error error; 124 DataBufferHeap data(data_byte_size, 0); 125 size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(), data.GetByteSize(), error); 126 if (bytes_read != data_byte_size || !error.Success()) 127 return false; 128 129 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), process->GetByteOrder(), sizeof(ptr_t)); 130 lldb::offset_t offset = 0; 131 entry->next_entry = extractor.GetPointer(&offset); 132 entry->prev_entry = extractor.GetPointer(&offset); 133 entry->symfile_addr = extractor.GetPointer(&offset); 134 offset = llvm::alignTo(offset, uint64_align_bytes); 135 entry->symfile_size = extractor.GetU64(&offset); 136 137 return true; 138 } 139 140 } // anonymous namespace end 141 142 JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) : 143 JITLoader(process), 144 m_jit_objects(), 145 m_jit_break_id(LLDB_INVALID_BREAK_ID), 146 m_jit_descriptor_addr(LLDB_INVALID_ADDRESS) 147 { 148 } 149 150 JITLoaderGDB::~JITLoaderGDB () 151 { 152 if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id)) 153 m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id); 154 } 155 156 void 157 JITLoaderGDB::DebuggerInitialize(Debugger &debugger) 158 { 159 if (!PluginManager::GetSettingForJITLoaderPlugin(debugger, PluginProperties::GetSettingName())) 160 { 161 const bool is_global_setting = true; 162 PluginManager::CreateSettingForJITLoaderPlugin(debugger, 163 GetGlobalPluginProperties()->GetValueProperties(), 164 ConstString ("Properties for the JIT LoaderGDB plug-in."), 165 is_global_setting); 166 } 167 } 168 169 void JITLoaderGDB::DidAttach() 170 { 171 Target &target = m_process->GetTarget(); 172 ModuleList &module_list = target.GetImages(); 173 SetJITBreakpoint(module_list); 174 } 175 176 void JITLoaderGDB::DidLaunch() 177 { 178 Target &target = m_process->GetTarget(); 179 ModuleList &module_list = target.GetImages(); 180 SetJITBreakpoint(module_list); 181 } 182 183 void 184 JITLoaderGDB::ModulesDidLoad(ModuleList &module_list) 185 { 186 if (!DidSetJITBreakpoint() && m_process->IsAlive()) 187 SetJITBreakpoint(module_list); 188 } 189 190 //------------------------------------------------------------------ 191 // Setup the JIT Breakpoint 192 //------------------------------------------------------------------ 193 void 194 JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list) 195 { 196 if (!GetGlobalPluginProperties()->GetEnableJITBreakpoint()) 197 return; 198 199 if ( DidSetJITBreakpoint() ) 200 return; 201 202 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); 203 if (log) 204 log->Printf("JITLoaderGDB::%s looking for JIT register hook", 205 __FUNCTION__); 206 207 addr_t jit_addr = GetSymbolAddress(module_list, 208 ConstString("__jit_debug_register_code"), 209 eSymbolTypeAny); 210 if (jit_addr == LLDB_INVALID_ADDRESS) 211 return; 212 213 m_jit_descriptor_addr = GetSymbolAddress(module_list, 214 ConstString("__jit_debug_descriptor"), 215 eSymbolTypeData); 216 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) 217 { 218 if (log) 219 log->Printf( 220 "JITLoaderGDB::%s failed to find JIT descriptor address", 221 __FUNCTION__); 222 return; 223 } 224 225 if (log) 226 log->Printf("JITLoaderGDB::%s setting JIT breakpoint", 227 __FUNCTION__); 228 229 Breakpoint *bp = 230 m_process->GetTarget().CreateBreakpoint(jit_addr, true, false).get(); 231 bp->SetCallback(JITDebugBreakpointHit, this, true); 232 bp->SetBreakpointKind("jit-debug-register"); 233 m_jit_break_id = bp->GetID(); 234 235 ReadJITDescriptor(true); 236 } 237 238 bool 239 JITLoaderGDB::JITDebugBreakpointHit(void *baton, 240 StoppointCallbackContext *context, 241 user_id_t break_id, user_id_t break_loc_id) 242 { 243 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); 244 if (log) 245 log->Printf("JITLoaderGDB::%s hit JIT breakpoint", 246 __FUNCTION__); 247 JITLoaderGDB *instance = static_cast<JITLoaderGDB *>(baton); 248 return instance->ReadJITDescriptor(false); 249 } 250 251 static void updateSectionLoadAddress(const SectionList §ion_list, 252 Target &target, 253 uint64_t symbolfile_addr, 254 uint64_t symbolfile_size, 255 uint64_t &vmaddrheuristic, 256 uint64_t &min_addr, 257 uint64_t &max_addr) 258 { 259 const uint32_t num_sections = section_list.GetSize(); 260 for (uint32_t i = 0; i<num_sections; ++i) 261 { 262 SectionSP section_sp(section_list.GetSectionAtIndex(i)); 263 if (section_sp) 264 { 265 if(section_sp->IsFake()) { 266 uint64_t lower = (uint64_t)-1; 267 uint64_t upper = 0; 268 updateSectionLoadAddress(section_sp->GetChildren(), target, symbolfile_addr, symbolfile_size, vmaddrheuristic, 269 lower, upper); 270 if (lower < min_addr) 271 min_addr = lower; 272 if (upper > max_addr) 273 max_addr = upper; 274 const lldb::addr_t slide_amount = lower - section_sp->GetFileAddress(); 275 section_sp->Slide(slide_amount, false); 276 section_sp->GetChildren().Slide(-slide_amount, false); 277 section_sp->SetByteSize (upper - lower); 278 } else { 279 vmaddrheuristic += 2<<section_sp->GetLog2Align(); 280 uint64_t lower; 281 if (section_sp->GetFileAddress() > vmaddrheuristic) 282 lower = section_sp->GetFileAddress(); 283 else { 284 lower = symbolfile_addr+section_sp->GetFileOffset(); 285 section_sp->SetFileAddress(symbolfile_addr+section_sp->GetFileOffset()); 286 } 287 target.SetSectionLoadAddress(section_sp, lower, true); 288 uint64_t upper = lower + section_sp->GetByteSize(); 289 if (lower < min_addr) 290 min_addr = lower; 291 if (upper > max_addr) 292 max_addr = upper; 293 // This is an upper bound, but a good enough heuristic 294 vmaddrheuristic += section_sp->GetByteSize(); 295 } 296 } 297 } 298 } 299 300 bool 301 JITLoaderGDB::ReadJITDescriptor(bool all_entries) 302 { 303 if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) 304 return ReadJITDescriptorImpl<uint64_t>(all_entries); 305 else 306 return ReadJITDescriptorImpl<uint32_t>(all_entries); 307 } 308 309 template <typename ptr_t> 310 bool 311 JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) 312 { 313 if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS) 314 return false; 315 316 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); 317 Target &target = m_process->GetTarget(); 318 ModuleList &module_list = target.GetImages(); 319 320 jit_descriptor<ptr_t> jit_desc; 321 const size_t jit_desc_size = sizeof(jit_desc); 322 Error error; 323 size_t bytes_read = m_process->DoReadMemory( 324 m_jit_descriptor_addr, &jit_desc, jit_desc_size, error); 325 if (bytes_read != jit_desc_size || !error.Success()) 326 { 327 if (log) 328 log->Printf("JITLoaderGDB::%s failed to read JIT descriptor", 329 __FUNCTION__); 330 return false; 331 } 332 333 jit_actions_t jit_action = (jit_actions_t)jit_desc.action_flag; 334 addr_t jit_relevant_entry = (addr_t)jit_desc.relevant_entry; 335 if (all_entries) 336 { 337 jit_action = JIT_REGISTER_FN; 338 jit_relevant_entry = (addr_t)jit_desc.first_entry; 339 } 340 341 while (jit_relevant_entry != 0) 342 { 343 jit_code_entry<ptr_t> jit_entry; 344 if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry)) 345 { 346 if (log) 347 log->Printf( 348 "JITLoaderGDB::%s failed to read JIT entry at 0x%" PRIx64, 349 __FUNCTION__, jit_relevant_entry); 350 return false; 351 } 352 353 const addr_t &symbolfile_addr = (addr_t)jit_entry.symfile_addr; 354 const size_t &symbolfile_size = (size_t)jit_entry.symfile_size; 355 ModuleSP module_sp; 356 357 if (jit_action == JIT_REGISTER_FN) 358 { 359 if (log) 360 log->Printf( 361 "JITLoaderGDB::%s registering JIT entry at 0x%" PRIx64 362 " (%" PRIu64 " bytes)", 363 __FUNCTION__, symbolfile_addr, (uint64_t) symbolfile_size); 364 365 char jit_name[64]; 366 snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr); 367 module_sp = m_process->ReadModuleFromMemory( 368 FileSpec(jit_name, false), symbolfile_addr, symbolfile_size); 369 370 if (module_sp && module_sp->GetObjectFile()) 371 { 372 // load the symbol table right away 373 module_sp->GetObjectFile()->GetSymtab(); 374 375 m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp)); 376 if (module_sp->GetObjectFile()->GetPluginName() == ConstString("mach-o")) 377 { 378 ObjectFile *image_object_file = module_sp->GetObjectFile(); 379 if (image_object_file) 380 { 381 const SectionList *section_list = image_object_file->GetSectionList (); 382 if (section_list) 383 { 384 uint64_t vmaddrheuristic = 0; 385 uint64_t lower = (uint64_t)-1; 386 uint64_t upper = 0; 387 updateSectionLoadAddress(*section_list, target, symbolfile_addr, symbolfile_size, 388 vmaddrheuristic, lower, upper); 389 } 390 } 391 } 392 else 393 { 394 bool changed = false; 395 module_sp->SetLoadAddress(target, 0, true, changed); 396 } 397 398 module_list.AppendIfNeeded(module_sp); 399 400 ModuleList module_list; 401 module_list.Append(module_sp); 402 target.ModulesDidLoad(module_list); 403 } 404 else 405 { 406 if (log) 407 log->Printf("JITLoaderGDB::%s failed to load module for " 408 "JIT entry at 0x%" PRIx64, 409 __FUNCTION__, symbolfile_addr); 410 } 411 } 412 else if (jit_action == JIT_UNREGISTER_FN) 413 { 414 if (log) 415 log->Printf( 416 "JITLoaderGDB::%s unregistering JIT entry at 0x%" PRIx64, 417 __FUNCTION__, symbolfile_addr); 418 419 JITObjectMap::iterator it = m_jit_objects.find(symbolfile_addr); 420 if (it != m_jit_objects.end()) 421 { 422 module_sp = it->second; 423 ObjectFile *image_object_file = module_sp->GetObjectFile(); 424 if (image_object_file) 425 { 426 const SectionList *section_list = image_object_file->GetSectionList (); 427 if (section_list) 428 { 429 const uint32_t num_sections = section_list->GetSize(); 430 for (uint32_t i = 0; i<num_sections; ++i) 431 { 432 SectionSP section_sp(section_list->GetSectionAtIndex(i)); 433 if (section_sp) 434 { 435 target.GetSectionLoadList().SetSectionUnloaded (section_sp); 436 } 437 } 438 } 439 } 440 module_list.Remove(module_sp); 441 m_jit_objects.erase(it); 442 } 443 } 444 else if (jit_action == JIT_NOACTION) 445 { 446 // Nothing to do 447 } 448 else 449 { 450 assert(false && "Unknown jit action"); 451 } 452 453 if (all_entries) 454 jit_relevant_entry = (addr_t)jit_entry.next_entry; 455 else 456 jit_relevant_entry = 0; 457 } 458 459 return false; // Continue Running. 460 } 461 462 //------------------------------------------------------------------ 463 // PluginInterface protocol 464 //------------------------------------------------------------------ 465 lldb_private::ConstString 466 JITLoaderGDB::GetPluginNameStatic() 467 { 468 static ConstString g_name("gdb"); 469 return g_name; 470 } 471 472 JITLoaderSP 473 JITLoaderGDB::CreateInstance(Process *process, bool force) 474 { 475 JITLoaderSP jit_loader_sp; 476 ArchSpec arch (process->GetTarget().GetArchitecture()); 477 if (arch.GetTriple().getVendor() != llvm::Triple::Apple) 478 jit_loader_sp.reset(new JITLoaderGDB(process)); 479 return jit_loader_sp; 480 } 481 482 const char * 483 JITLoaderGDB::GetPluginDescriptionStatic() 484 { 485 return "JIT loader plug-in that watches for JIT events using the GDB interface."; 486 } 487 488 lldb_private::ConstString 489 JITLoaderGDB::GetPluginName() 490 { 491 return GetPluginNameStatic(); 492 } 493 494 uint32_t 495 JITLoaderGDB::GetPluginVersion() 496 { 497 return 1; 498 } 499 500 void 501 JITLoaderGDB::Initialize() 502 { 503 PluginManager::RegisterPlugin (GetPluginNameStatic(), 504 GetPluginDescriptionStatic(), 505 CreateInstance, 506 DebuggerInitialize); 507 } 508 509 void 510 JITLoaderGDB::Terminate() 511 { 512 PluginManager::UnregisterPlugin (CreateInstance); 513 } 514 515 bool 516 JITLoaderGDB::DidSetJITBreakpoint() const 517 { 518 return LLDB_BREAK_ID_IS_VALID(m_jit_break_id); 519 } 520 521 addr_t 522 JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name, 523 SymbolType symbol_type) const 524 { 525 SymbolContextList target_symbols; 526 Target &target = m_process->GetTarget(); 527 528 if (!module_list.FindSymbolsWithNameAndType(name, symbol_type, 529 target_symbols)) 530 return LLDB_INVALID_ADDRESS; 531 532 SymbolContext sym_ctx; 533 target_symbols.GetContextAtIndex(0, sym_ctx); 534 535 const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress(); 536 if (!jit_descriptor_addr.IsValid()) 537 return LLDB_INVALID_ADDRESS; 538 539 const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target); 540 return jit_addr; 541 } 542