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