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