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