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