Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2010 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can | |
| 4 * be found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #include <assert.h> | |
| 8 #include <string.h> | |
| 9 #include <stdlib.h> | |
| 10 #include <stdio.h> | |
|
mmortensen
2010/12/07 22:53:58
Minor nit: we could use C++ style headers here, s
mlinck
2010/12/10 21:10:27
I'm leaning towards leaving these since they're wo
| |
| 11 | |
| 12 #include "native_client/src/trusted/gdb_rsp/abi.h" | |
| 13 #include "native_client/src/trusted/gdb_rsp/host.h" | |
| 14 #include "native_client/src/trusted/gdb_rsp/host_mock.h" | |
| 15 #include "native_client/src/trusted/gdb_rsp/packet.h" | |
| 16 #include "native_client/src/trusted/gdb_rsp/session.h" | |
| 17 #include "native_client/src/trusted/gdb_rsp/util.h" | |
| 18 | |
| 19 #include "native_client/src/trusted/port/std_types.h" | |
| 20 #include "native_client/src/trusted/port/platform.h" | |
| 21 | |
| 22 #ifdef WIN32 | |
| 23 #define snprintf sprintf_s | |
| 24 #endif | |
| 25 | |
| 26 | |
| 27 using std::string; | |
| 28 using port::IPlatform; | |
| 29 | |
| 30 namespace gdb_rsp { | |
| 31 | |
| 32 | |
| 33 // Construct unitialzied | |
| 34 HostMock::HostMock() : Host(0) { } | |
|
noelallen_use_chromium
2010/12/07 23:04:44
http://www.corp.google.com/eng/doc/cppguide.xml#0_
| |
| 35 | |
| 36 HostMock::~HostMock() { | |
| 37 while (!signals_.empty()) { | |
| 38 SignalMock* sig = signals_.front(); | |
| 39 signals_.pop_front(); | |
| 40 delete sig; | |
| 41 } | |
| 42 | |
| 43 while (!memory_.empty()) { | |
| 44 delete[] memory_.begin()->second; | |
| 45 memory_.erase(memory_.begin()); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 bool HostMock::Init() { | |
| 50 string reply; | |
| 51 | |
| 52 properties_.clear(); | |
| 53 properties_["PacketSize"] = "3fa"; | |
| 54 | |
| 55 SetRequest("qExecPath", "nullptr.nexe"); | |
| 56 SetRequest("qExecArgs", ""); | |
| 57 SetRequest("qExecEnvs", ""); | |
| 58 | |
| 59 abi_ = Abi::Find("i386:x86-64"); | |
| 60 | |
| 61 status_ = HS_STOPPED; | |
| 62 return true; | |
| 63 } | |
| 64 | |
| 65 bool HostMock::Step() { | |
| 66 // We can only step if we are stopped | |
| 67 if (HS_STOPPED != status_) return false; | |
| 68 | |
| 69 status_ = HS_RUNNING; | |
| 70 return true; | |
| 71 } | |
| 72 | |
| 73 bool HostMock::Continue() { | |
| 74 // We can only step if we are stopped | |
| 75 if (HS_STOPPED != status_) return false; | |
| 76 | |
| 77 status_ = HS_RUNNING; | |
| 78 return true; | |
| 79 } | |
| 80 | |
| 81 | |
| 82 bool HostMock::Break() { | |
| 83 char brk[2] = { 0x03, 0x00 }; | |
|
noelallen_use_chromium
2010/12/07 23:04:44
Where is this used? This should have generated a
| |
| 84 | |
| 85 // We can only break if running | |
| 86 if (HS_RUNNING != status_) return false; | |
| 87 | |
| 88 status_ = HS_STOPPING; | |
| 89 | |
| 90 SignalMock* sig = new SignalMock; | |
|
noelallen_use_chromium
2010/12/07 23:04:44
While this is not REALLY trusted code, since it wi
mlinck
2010/12/10 21:10:27
There's a separate target for these called gdb_rsp
| |
| 91 sig->sig = 5; | |
| 92 sig->thread = 0; | |
| 93 sig->rel = true; | |
| 94 sig->ip = 0; | |
| 95 | |
| 96 signals_.push_front(sig); | |
| 97 return true; | |
| 98 } | |
| 99 | |
| 100 bool HostMock::Detach() { | |
| 101 // We can only detach if stopped | |
| 102 if (HS_STOPPED != status_) return false; | |
| 103 return true; | |
| 104 } | |
| 105 | |
| 106 #define MEMBLOCKSIZE 65536 | |
| 107 bool HostMock::GetMemory(void *dst, uint64_t addr, uint32_t size) { | |
| 108 char *out = reinterpret_cast<char *>(dst); | |
| 109 | |
| 110 while (size) { | |
| 111 uint64_t key = addr & ~(MEMBLOCKSIZE - 1); | |
| 112 uint64_t offs = addr & (MEMBLOCKSIZE - 1); | |
| 113 uint32_t max = static_cast<uint32_t>(MEMBLOCKSIZE - offs); | |
| 114 char *data = memory_[key]; | |
| 115 | |
| 116 /* Truncate this iteration */ | |
| 117 if (max > size) max = size; | |
| 118 | |
| 119 /* Check if block is availible */ | |
|
noelallen_use_chromium
2010/12/07 23:04:44
Misleading:
Fail if block does not exist.
| |
| 120 if (NULL == data) return false; | |
| 121 | |
| 122 /* Copy it out. */ | |
| 123 memcpy(out, &data[addr - key], max); | |
| 124 size -= max; | |
| 125 out += max; | |
|
noelallen_use_chromium
2010/12/07 23:04:44
Does this actually work? Addr does not appear to
| |
| 126 } | |
| 127 | |
| 128 return true; | |
| 129 } | |
| 130 | |
| 131 bool HostMock::SetMemory(const void *src, uint64_t addr, uint32_t size) { | |
| 132 const char *in = reinterpret_cast<const char *>(src); | |
| 133 | |
| 134 while (size) { | |
|
noelallen_use_chromium
2010/12/07 23:04:44
Same as above.
| |
| 135 uint64_t key = addr & ~(MEMBLOCKSIZE - 1); | |
| 136 uint64_t offs = addr & (MEMBLOCKSIZE - 1); | |
| 137 uint32_t max = static_cast<uint32_t>(MEMBLOCKSIZE - offs); | |
| 138 char *data = memory_[key]; | |
| 139 | |
| 140 /* Truncate this iteration */ | |
| 141 if (max > size) max = size; | |
| 142 | |
| 143 /* Check if block is availible, if not allocate */ | |
| 144 if (NULL == data) { | |
| 145 data = new char[MEMBLOCKSIZE]; | |
| 146 memory_[key] = data; | |
| 147 } | |
| 148 | |
| 149 /* Copy it out. */ | |
| 150 memcpy(&data[addr - key], in, max); | |
| 151 size -= max; | |
| 152 in += max; | |
| 153 } | |
| 154 | |
| 155 return true; | |
| 156 } | |
| 157 | |
| 158 bool HostMock::Request(const std::string &req, std::string *resp) { | |
| 159 std::map<string, string>::const_iterator itr; | |
| 160 itr = requests_.find(req); | |
| 161 | |
| 162 if (requests_.end() == itr) return false; | |
| 163 | |
| 164 *resp = itr->second; | |
| 165 return true; | |
| 166 } | |
| 167 | |
| 168 void HostMock::SetRequest(const std::string &req, const std::string &resp) { | |
| 169 requests_[req] = resp; | |
| 170 } | |
| 171 | |
| 172 | |
|
noelallen_use_chromium
2010/12/07 23:04:44
Either the source or the header should describe th
| |
| 173 void HostMock::AddSignal(int32_t signal, uint32_t thread) { | |
| 174 SignalMock* sig = new SignalMock; | |
| 175 sig->sig = signal; | |
| 176 sig->thread = thread; | |
| 177 sig->rel = true; | |
| 178 sig->ip = 0; | |
| 179 | |
| 180 signals_.push_back(sig); | |
| 181 } | |
| 182 | |
| 183 void HostMock::AddSignalAbs(int32_t signal, uint32_t thread, uint64_t ip) { | |
| 184 SignalMock* sig = new SignalMock; | |
| 185 sig->sig = signal; | |
| 186 sig->thread = thread; | |
| 187 sig->rel = false; | |
| 188 sig->ip = ip; | |
| 189 | |
| 190 signals_.push_back(sig); | |
| 191 } | |
| 192 | |
| 193 void HostMock::AddSignalDelta(int32_t signal, uint32_t thread, int64_t delta) { | |
| 194 SignalMock* sig = new SignalMock; | |
| 195 sig->sig = signal; | |
| 196 sig->thread = thread; | |
| 197 sig->rel = true; | |
| 198 sig->ip = delta; | |
| 199 | |
| 200 signals_.push_back(sig); | |
| 201 } | |
| 202 | |
| 203 // Wait to see if we receive a break | |
| 204 bool HostMock::WaitForBreak() { | |
| 205 if (signals_.empty()) return false; | |
| 206 | |
| 207 SignalMock* sig = signals_.front(); | |
| 208 signals_.pop_front(); | |
| 209 | |
| 210 Thread* thread = GetThread(sig->thread); | |
| 211 if (thread) { | |
| 212 const Abi *abi = thread->GetAbi(); | |
| 213 const Abi::RegDef *def = abi->GetRegisterType(Abi::INST_PTR); | |
| 214 uint64_t ip; | |
| 215 | |
| 216 if (sig->rel) { | |
| 217 thread->GetRegister(def->index_, &ip); | |
| 218 sig->ip += ip; | |
|
noelallen_use_chromium
2010/12/07 23:04:44
Should this be
ip += sig->ip
| |
| 219 } else { | |
| 220 ip = sig->ip; | |
| 221 } | |
| 222 | |
| 223 /* Update the current thread's IP */ | |
| 224 thread->SetRegister(def->index_, &ip); | |
| 225 } | |
| 226 | |
| 227 /* Generate a "signal" packet */ | |
| 228 char tmp[64]; | |
| 229 snprintf(tmp, "S%02d", sig->sig, 63); | |
|
noelallen_use_chromium
2010/12/07 23:04:44
should use sizeof(tmp) instead of 63 in case the s
| |
| 230 ParseStopPacket(tmp); | |
| 231 | |
| 232 delete sig; | |
| 233 return true; | |
| 234 } | |
| 235 | |
| 236 | |
| 237 | |
| 238 } // namespace gdb_rsp | |
| 239 | |
| 240 | |
| OLD | NEW |