1 //===-- ThreadPlanRunToAddress.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 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Target/ThreadPlanRunToAddress.h" 15 #include "lldb/Core/Log.h" 16 #include "lldb/Core/Stream.h" 17 #include "lldb/Target/Target.h" 18 #include "lldb/Target/Process.h" 19 #include "lldb/Target/Thread.h" 20 #include "lldb/Target/RegisterContext.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 //---------------------------------------------------------------------- 26 // ThreadPlanRunToAddress: Continue plan 27 //---------------------------------------------------------------------- 28 29 ThreadPlanRunToAddress::ThreadPlanRunToAddress 30 ( 31 Thread &thread, 32 Address &address, 33 bool stop_others 34 ) : 35 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 36 m_stop_others (stop_others), 37 m_addresses (), 38 m_break_ids () 39 { 40 m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get())); 41 SetInitialBreakpoints(); 42 } 43 44 ThreadPlanRunToAddress::ThreadPlanRunToAddress 45 ( 46 Thread &thread, 47 lldb::addr_t address, 48 bool stop_others 49 ) : 50 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 51 m_stop_others (stop_others), 52 m_addresses (), 53 m_break_ids () 54 { 55 m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address)); 56 SetInitialBreakpoints(); 57 } 58 59 ThreadPlanRunToAddress::ThreadPlanRunToAddress 60 ( 61 Thread &thread, 62 const std::vector<lldb::addr_t> &addresses, 63 bool stop_others 64 ) : 65 ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), 66 m_stop_others (stop_others), 67 m_addresses (addresses), 68 m_break_ids () 69 { 70 // Convert all addresses into opcode addresses to make sure we set 71 // breakpoints at the correct address. 72 Target &target = thread.GetProcess()->GetTarget(); 73 std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); 74 for (pos = m_addresses.begin(); pos != end; ++pos) 75 *pos = target.GetOpcodeLoadAddress (*pos); 76 77 SetInitialBreakpoints(); 78 } 79 80 void 81 ThreadPlanRunToAddress::SetInitialBreakpoints () 82 { 83 size_t num_addresses = m_addresses.size(); 84 m_break_ids.resize(num_addresses); 85 86 for (size_t i = 0; i < num_addresses; i++) 87 { 88 Breakpoint *breakpoint; 89 breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true, false).get(); 90 if (breakpoint != nullptr) 91 { 92 m_break_ids[i] = breakpoint->GetID(); 93 breakpoint->SetThreadID(m_thread.GetID()); 94 breakpoint->SetBreakpointKind("run-to-address"); 95 } 96 } 97 } 98 99 ThreadPlanRunToAddress::~ThreadPlanRunToAddress () 100 { 101 size_t num_break_ids = m_break_ids.size(); 102 for (size_t i = 0; i < num_break_ids; i++) 103 { 104 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 105 } 106 } 107 108 void 109 ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level) 110 { 111 size_t num_addresses = m_addresses.size(); 112 113 if (level == lldb::eDescriptionLevelBrief) 114 { 115 if (num_addresses == 0) 116 { 117 s->Printf ("run to address with no addresses given."); 118 return; 119 } 120 else if (num_addresses == 1) 121 s->Printf ("run to address: "); 122 else 123 s->Printf ("run to addresses: "); 124 125 for (size_t i = 0; i < num_addresses; i++) 126 { 127 s->Address (m_addresses[i], sizeof (addr_t)); 128 s->Printf(" "); 129 } 130 } 131 else 132 { 133 if (num_addresses == 0) 134 { 135 s->Printf ("run to address with no addresses given."); 136 return; 137 } 138 else if (num_addresses == 1) 139 s->Printf ("Run to address: "); 140 else 141 { 142 s->Printf ("Run to addresses: "); 143 } 144 145 for (size_t i = 0; i < num_addresses; i++) 146 { 147 if (num_addresses > 1) 148 { 149 s->Printf("\n"); 150 s->Indent(); 151 } 152 153 s->Address(m_addresses[i], sizeof (addr_t)); 154 s->Printf (" using breakpoint: %d - ", m_break_ids[i]); 155 Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get(); 156 if (breakpoint) 157 breakpoint->Dump (s); 158 else 159 s->Printf ("but the breakpoint has been deleted."); 160 } 161 } 162 } 163 164 bool 165 ThreadPlanRunToAddress::ValidatePlan (Stream *error) 166 { 167 // If we couldn't set the breakpoint for some reason, then this won't 168 // work. 169 bool all_bps_good = true; 170 size_t num_break_ids = m_break_ids.size(); 171 172 for (size_t i = 0; i < num_break_ids; i++) 173 { 174 if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) 175 { 176 all_bps_good = false; 177 if (error) 178 { 179 error->Printf ("Could not set breakpoint for address: "); 180 error->Address (m_addresses[i], sizeof (addr_t)); 181 error->Printf ("\n"); 182 } 183 } 184 } 185 return all_bps_good; 186 } 187 188 bool 189 ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr) 190 { 191 return AtOurAddress(); 192 } 193 194 bool 195 ThreadPlanRunToAddress::ShouldStop (Event *event_ptr) 196 { 197 return AtOurAddress(); 198 } 199 200 bool 201 ThreadPlanRunToAddress::StopOthers () 202 { 203 return m_stop_others; 204 } 205 206 void 207 ThreadPlanRunToAddress::SetStopOthers (bool new_value) 208 { 209 m_stop_others = new_value; 210 } 211 212 StateType 213 ThreadPlanRunToAddress::GetPlanRunState () 214 { 215 return eStateRunning; 216 } 217 218 bool 219 ThreadPlanRunToAddress::WillStop () 220 { 221 return true; 222 } 223 224 bool 225 ThreadPlanRunToAddress::MischiefManaged () 226 { 227 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 228 229 if (AtOurAddress()) 230 { 231 // Remove the breakpoint 232 size_t num_break_ids = m_break_ids.size(); 233 234 for (size_t i = 0; i < num_break_ids; i++) 235 { 236 if (m_break_ids[i] != LLDB_INVALID_BREAK_ID) 237 { 238 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]); 239 m_break_ids[i] = LLDB_INVALID_BREAK_ID; 240 } 241 } 242 if (log) 243 log->Printf("Completed run to address plan."); 244 ThreadPlan::MischiefManaged (); 245 return true; 246 } 247 else 248 return false; 249 } 250 251 bool 252 ThreadPlanRunToAddress::AtOurAddress () 253 { 254 lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC(); 255 bool found_it = false; 256 size_t num_addresses = m_addresses.size(); 257 for (size_t i = 0; i < num_addresses; i++) 258 { 259 if (m_addresses[i] == current_address) 260 { 261 found_it = true; 262 break; 263 } 264 } 265 return found_it; 266 } 267