1 //===-- SBTarget.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 #include "SBTarget.h" 11 12 #include "lldb/lldb-include.h" 13 14 #include "lldb/API/SBFileSpec.h" 15 #include "lldb/API/SBModule.h" 16 #include "lldb/Breakpoint/BreakpointID.h" 17 #include "lldb/Breakpoint/BreakpointIDList.h" 18 #include "lldb/Breakpoint/BreakpointList.h" 19 #include "lldb/Breakpoint/BreakpointLocation.h" 20 #include "lldb/Core/Address.h" 21 #include "lldb/Core/AddressResolver.h" 22 #include "lldb/Core/AddressResolverName.h" 23 #include "lldb/Core/Args.h" 24 #include "lldb/Core/ArchSpec.h" 25 #include "lldb/Core/Debugger.h" 26 #include "lldb/Core/Disassembler.h" 27 #include "lldb/Core/FileSpec.h" 28 #include "lldb/Core/RegularExpression.h" 29 #include "lldb/Core/SearchFilter.h" 30 #include "lldb/Core/STLUtils.h" 31 #include "lldb/Target/Process.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/TargetList.h" 34 35 #include "lldb/Interpreter/CommandReturnObject.h" 36 #include "../source/Commands/CommandObjectBreakpoint.h" 37 38 #include "SBDebugger.h" 39 #include "SBProcess.h" 40 #include "SBListener.h" 41 #include "SBBreakpoint.h" 42 43 using namespace lldb; 44 using namespace lldb_private; 45 46 #define DEFAULT_DISASM_BYTE_SIZE 32 47 48 //---------------------------------------------------------------------- 49 // SBTarget constructor 50 //---------------------------------------------------------------------- 51 SBTarget::SBTarget () 52 { 53 } 54 55 SBTarget::SBTarget (const SBTarget& rhs) : 56 m_target_sp (rhs.m_target_sp) 57 { 58 } 59 60 SBTarget::SBTarget(const TargetSP& target_sp) : 61 m_target_sp (target_sp) 62 { 63 } 64 65 const SBTarget& 66 SBTarget::Assign (const SBTarget& rhs) 67 { 68 if (this != &rhs) 69 { 70 m_target_sp = rhs.m_target_sp; 71 } 72 return *this; 73 } 74 75 76 //---------------------------------------------------------------------- 77 // Destructor 78 //---------------------------------------------------------------------- 79 SBTarget::~SBTarget() 80 { 81 } 82 83 bool 84 SBTarget::IsValid () const 85 { 86 return m_target_sp.get() != NULL; 87 } 88 89 SBProcess 90 SBTarget::GetProcess () 91 { 92 SBProcess sb_process; 93 if (IsValid()) 94 sb_process.SetProcess (m_target_sp->GetProcessSP()); 95 return sb_process; 96 } 97 98 SBProcess 99 SBTarget::CreateProcess () 100 { 101 SBProcess sb_process; 102 103 if (IsValid()) 104 { 105 SBListener sb_listener = SBDebugger::GetListener(); 106 if (sb_listener.IsValid()) 107 sb_process.SetProcess (m_target_sp->CreateProcess (*sb_listener)); 108 } 109 return sb_process; 110 } 111 112 SBProcess 113 SBTarget::LaunchProcess 114 ( 115 char const **argv, 116 char const **envp, 117 const char *tty, 118 bool stop_at_entry 119 ) 120 { 121 SBProcess process(GetProcess ()); 122 if (!process.IsValid()) 123 process = CreateProcess(); 124 if (process.IsValid()) 125 { 126 Error error (process->Launch (argv, envp, tty, tty, tty)); 127 if (error.Success()) 128 { 129 if (!stop_at_entry) 130 { 131 StateType state = process->WaitForProcessToStop (NULL); 132 if (state == eStateStopped) 133 process->Resume(); 134 } 135 } 136 } 137 return process; 138 } 139 140 SBFileSpec 141 SBTarget::GetExecutable () 142 { 143 SBFileSpec exe_file_spec; 144 if (IsValid()) 145 { 146 ModuleSP exe_module_sp (m_target_sp->GetExecutableModule ()); 147 if (exe_module_sp) 148 exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec()); 149 } 150 return exe_file_spec; 151 } 152 153 154 bool 155 SBTarget::DeleteTargetFromList (TargetList *list) 156 { 157 if (IsValid()) 158 return list->DeleteTarget (m_target_sp); 159 else 160 return false; 161 } 162 163 bool 164 SBTarget::MakeCurrentTarget () 165 { 166 if (IsValid()) 167 { 168 Debugger::GetSharedInstance().GetTargetList().SetCurrentTarget (m_target_sp.get()); 169 return true; 170 } 171 return false; 172 } 173 174 bool 175 SBTarget::operator == (const SBTarget &rhs) const 176 { 177 return m_target_sp.get() == rhs.m_target_sp.get(); 178 } 179 180 bool 181 SBTarget::operator != (const SBTarget &rhs) const 182 { 183 return m_target_sp.get() != rhs.m_target_sp.get(); 184 } 185 186 lldb_private::Target * 187 SBTarget::GetLLDBObjectPtr() 188 { 189 return m_target_sp.get(); 190 } 191 const lldb_private::Target * 192 SBTarget::GetLLDBObjectPtr() const 193 { 194 return m_target_sp.get(); 195 } 196 197 SBBreakpoint 198 SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) 199 { 200 SBBreakpoint sb_bp; 201 if (file != NULL && line != 0) 202 sb_bp = BreakpointCreateByLocation (SBFileSpec (file), line); 203 return sb_bp; 204 } 205 206 SBBreakpoint 207 SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line) 208 { 209 SBBreakpoint sb_bp; 210 if (m_target_sp.get() && line != 0) 211 *sb_bp = m_target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false); 212 return sb_bp; 213 } 214 215 SBBreakpoint 216 SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name) 217 { 218 SBBreakpoint sb_bp; 219 if (m_target_sp.get() && symbol_name && symbol_name[0]) 220 { 221 if (module_name && module_name[0]) 222 { 223 FileSpec module_file_spec(module_name); 224 *sb_bp = m_target_sp->CreateBreakpoint (&module_file_spec, symbol_name, false); 225 } 226 else 227 { 228 *sb_bp = m_target_sp->CreateBreakpoint (NULL, symbol_name, false); 229 } 230 } 231 return sb_bp; 232 } 233 234 SBBreakpoint 235 SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name) 236 { 237 SBBreakpoint sb_bp; 238 if (m_target_sp.get() && symbol_name_regex && symbol_name_regex[0]) 239 { 240 RegularExpression regexp(symbol_name_regex); 241 242 if (module_name && module_name[0]) 243 { 244 FileSpec module_file_spec(module_name); 245 246 *sb_bp = m_target_sp->CreateBreakpoint (&module_file_spec, regexp, false); 247 } 248 else 249 { 250 *sb_bp = m_target_sp->CreateBreakpoint (NULL, regexp, false); 251 } 252 } 253 return sb_bp; 254 } 255 256 257 258 SBBreakpoint 259 SBTarget::BreakpointCreateByAddress (addr_t address) 260 { 261 SBBreakpoint sb_bp; 262 if (m_target_sp.get()) 263 *sb_bp = m_target_sp->CreateBreakpoint (address, false); 264 return sb_bp; 265 } 266 267 void 268 SBTarget::ListAllBreakpoints () 269 { 270 FILE *out_file = SBDebugger::GetOutputFileHandle(); 271 272 if (out_file == NULL) 273 return; 274 275 if (IsValid()) 276 { 277 const BreakpointList &bp_list = m_target_sp->GetBreakpointList(); 278 size_t num_bps = bp_list.GetSize(); 279 for (int i = 0; i < num_bps; ++i) 280 { 281 SBBreakpoint sb_breakpoint (bp_list.GetBreakpointByIndex (i)); 282 sb_breakpoint.GetDescription (out_file, "full"); 283 } 284 } 285 } 286 287 SBBreakpoint 288 SBTarget::FindBreakpointByID (break_id_t bp_id) 289 { 290 SBBreakpoint sb_breakpoint; 291 if (m_target_sp && bp_id != LLDB_INVALID_BREAK_ID) 292 *sb_breakpoint = m_target_sp->GetBreakpointByID (bp_id); 293 return sb_breakpoint; 294 } 295 296 297 bool 298 SBTarget::BreakpointDelete (break_id_t bp_id) 299 { 300 if (m_target_sp) 301 return m_target_sp->RemoveBreakpointByID (bp_id); 302 return false; 303 } 304 305 bool 306 SBTarget::EnableAllBreakpoints () 307 { 308 if (m_target_sp) 309 { 310 m_target_sp->EnableAllBreakpoints (); 311 return true; 312 } 313 return false; 314 } 315 316 bool 317 SBTarget::DisableAllBreakpoints () 318 { 319 if (m_target_sp) 320 { 321 m_target_sp->DisableAllBreakpoints (); 322 return true; 323 } 324 return false; 325 } 326 327 bool 328 SBTarget::DeleteAllBreakpoints () 329 { 330 if (m_target_sp) 331 { 332 m_target_sp->RemoveAllBreakpoints (); 333 return true; 334 } 335 return false; 336 } 337 338 339 uint32_t 340 SBTarget::GetNumModules () const 341 { 342 if (m_target_sp) 343 return m_target_sp->GetImages().GetSize(); 344 return 0; 345 } 346 347 SBModule 348 SBTarget::FindModule (const SBFileSpec &sb_file_spec) 349 { 350 SBModule sb_module; 351 if (m_target_sp && sb_file_spec.IsValid()) 352 sb_module.SetModule (m_target_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL)); 353 return sb_module; 354 } 355 356 SBModule 357 SBTarget::GetModuleAtIndex (uint32_t idx) 358 { 359 SBModule sb_module; 360 if (m_target_sp) 361 sb_module.SetModule(m_target_sp->GetImages().GetModuleAtIndex(idx)); 362 return sb_module; 363 } 364 365 366 SBBroadcaster 367 SBTarget::GetBroadcaster () const 368 { 369 SBBroadcaster broadcaster(m_target_sp.get(), false); 370 return broadcaster; 371 } 372 373 void 374 SBTarget::Disassemble (lldb::addr_t file_address_start, lldb::addr_t file_address_end, const char *module_name) 375 { 376 if (file_address_start == LLDB_INVALID_ADDRESS) 377 return; 378 379 FILE *out = SBDebugger::GetOutputFileHandle(); 380 if (out == NULL) 381 return; 382 383 if (IsValid()) 384 { 385 SBModule module; 386 if (module_name != NULL) 387 { 388 SBFileSpec file_spec (module_name); 389 module = FindModule (file_spec); 390 } 391 ArchSpec arch (m_target_sp->GetArchitecture()); 392 if (!arch.IsValid()) 393 return; 394 Disassembler *disassembler = Disassembler::FindPlugin (arch); 395 if (disassembler == NULL) 396 return; 397 398 // For now, we need a process; the disassembly functions insist. If we don't have one already, 399 // make one. 400 401 SBProcess process = GetProcess(); 402 if (! process.IsValid()) 403 process = CreateProcess(); 404 405 ExecutionContext exe_context (process.get()); 406 407 if (file_address_end == LLDB_INVALID_ADDRESS 408 || file_address_end < file_address_start) 409 file_address_end = file_address_start + DEFAULT_DISASM_BYTE_SIZE; 410 411 // TO BE FIXED: SOMEHOW WE NEED TO SPECIFY/USE THE MODULE, IF THE USER SPECIFIED ONE. I'M NOT 412 // SURE HOW TO DO THAT AT THE MOMENT. WE ALSO NEED TO FIGURE OUT WHAT TO DO IF THERE ARE MULTIPLE 413 // MODULES CONTAINING THE SPECIFIED ADDRESSES (E.G. THEY HAVEN'T ALL LOADED & BEEN GIVEN UNIQUE 414 // ADDRESSES YET). 415 416 DataExtractor data; 417 size_t bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeLoad, 418 file_address_start, 419 file_address_end - file_address_start, data); 420 421 if (bytes_disassembled > 0) 422 { 423 size_t num_instructions = disassembler->GetInstructionList().GetSize(); 424 uint32_t offset = 0; 425 StreamFile out_stream (out); 426 427 for (size_t i = 0; i < num_instructions; ++i) 428 { 429 Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i); 430 if (inst) 431 { 432 lldb::addr_t cur_addr = file_address_start + offset; 433 size_t inst_byte_size = inst->GetByteSize(); 434 inst->Dump (&out_stream, cur_addr, &data, offset, exe_context, false); 435 out_stream.EOL(); 436 offset += inst_byte_size; 437 } 438 } 439 } 440 } 441 } 442 443 void 444 SBTarget::Disassemble (const char *function_name, const char *module_name) 445 { 446 if (function_name == NULL) 447 return; 448 449 FILE *out = SBDebugger::GetOutputFileHandle(); 450 if (out == NULL) 451 return; 452 453 if (IsValid()) 454 { 455 SBModule module; 456 457 if (module_name != NULL) 458 { 459 SBFileSpec file_spec (module_name); 460 module = FindModule (file_spec); 461 } 462 463 ArchSpec arch (m_target_sp->GetArchitecture()); 464 if (!arch.IsValid()) 465 return; 466 467 Disassembler *disassembler = Disassembler::FindPlugin (arch); 468 if (disassembler == NULL) 469 return; 470 471 // For now, we need a process; the disassembly functions insist. If we don't have one already, 472 // make one. 473 474 SBProcess process = GetProcess(); 475 if (! process.IsValid() 476 || process.GetProcessID() == 0) 477 { 478 fprintf (out, "Cannot disassemble functions until after process has launched.\n"); 479 return; 480 } 481 482 ExecutionContext exe_context (process.get()); 483 484 FileSpec *containing_module = NULL; 485 486 if (module_name != NULL) 487 containing_module = new FileSpec (module_name); 488 489 SearchFilterSP filter_sp (m_target_sp->GetSearchFilterForModule (containing_module)); 490 AddressResolverSP resolver_sp (new AddressResolverName (function_name)); 491 492 resolver_sp->ResolveAddress (*filter_sp); 493 494 size_t num_matches_found = resolver_sp->GetNumberOfAddresses(); 495 496 if (num_matches_found == 1) 497 { 498 DataExtractor data; 499 500 AddressRange func_addresses = resolver_sp->GetAddressRangeAtIndex (0); 501 Address start_addr = func_addresses.GetBaseAddress(); 502 lldb::addr_t num_bytes = func_addresses.GetByteSize(); 503 504 lldb::addr_t addr = LLDB_INVALID_ADDRESS; 505 size_t bytes_disassembled = 0; 506 507 508 if (process.GetProcessID() == 0) 509 { 510 // Leave this branch in for now, but it should not be reached, since we exit above if the PID is 0. 511 addr = start_addr.GetFileAddress (); 512 bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeFile, addr, 513 num_bytes, data); 514 515 } 516 else 517 { 518 addr = start_addr.GetLoadAddress (process.get()); 519 bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeLoad, addr, 520 num_bytes, data); 521 522 } 523 524 if (bytes_disassembled > 0) 525 { 526 size_t num_instructions = disassembler->GetInstructionList().GetSize(); 527 uint32_t offset = 0; 528 StreamFile out_stream (out); 529 530 for (size_t i = 0; i < num_instructions; ++i) 531 { 532 Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i); 533 if (inst) 534 { 535 lldb::addr_t cur_addr = addr + offset; 536 size_t inst_byte_size = inst->GetByteSize(); 537 inst->Dump (&out_stream, cur_addr, &data, offset, exe_context, false); 538 out_stream.EOL(); 539 offset += inst_byte_size; 540 } 541 } 542 } 543 } 544 else if (num_matches_found > 1) 545 { 546 // TO BE FIXED: Eventually we want to list/disassemble all functions found. 547 fprintf (out, "Function '%s' was found in multiple modules; please specify the desired module name.\n", 548 function_name); 549 } 550 else 551 fprintf (out, "Function '%s' was not found.\n", function_name); 552 } 553 } 554