Index: src/trusted/gdb_rsp/host_mock.cc |
=================================================================== |
--- src/trusted/gdb_rsp/host_mock.cc (revision 0) |
+++ src/trusted/gdb_rsp/host_mock.cc (revision 0) |
@@ -0,0 +1,240 @@ |
+/* |
+ * Copyright 2010 The Native Client Authors. All rights reserved. |
+ * Use of this source code is governed by a BSD-style license that can |
+ * be found in the LICENSE file. |
+ */ |
+ |
+#include <assert.h> |
+#include <string.h> |
+#include <stdlib.h> |
+#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
|
+ |
+#include "native_client/src/trusted/gdb_rsp/abi.h" |
+#include "native_client/src/trusted/gdb_rsp/host.h" |
+#include "native_client/src/trusted/gdb_rsp/host_mock.h" |
+#include "native_client/src/trusted/gdb_rsp/packet.h" |
+#include "native_client/src/trusted/gdb_rsp/session.h" |
+#include "native_client/src/trusted/gdb_rsp/util.h" |
+ |
+#include "native_client/src/trusted/port/std_types.h" |
+#include "native_client/src/trusted/port/platform.h" |
+ |
+#ifdef WIN32 |
+#define snprintf sprintf_s |
+#endif |
+ |
+ |
+using std::string; |
+using port::IPlatform; |
+ |
+namespace gdb_rsp { |
+ |
+ |
+// Construct unitialzied |
+HostMock::HostMock() : Host(0) { } |
noelallen_use_chromium
2010/12/07 23:04:44
http://www.corp.google.com/eng/doc/cppguide.xml#0_
|
+ |
+HostMock::~HostMock() { |
+ while (!signals_.empty()) { |
+ SignalMock* sig = signals_.front(); |
+ signals_.pop_front(); |
+ delete sig; |
+ } |
+ |
+ while (!memory_.empty()) { |
+ delete[] memory_.begin()->second; |
+ memory_.erase(memory_.begin()); |
+ } |
+} |
+ |
+bool HostMock::Init() { |
+ string reply; |
+ |
+ properties_.clear(); |
+ properties_["PacketSize"] = "3fa"; |
+ |
+ SetRequest("qExecPath", "nullptr.nexe"); |
+ SetRequest("qExecArgs", ""); |
+ SetRequest("qExecEnvs", ""); |
+ |
+ abi_ = Abi::Find("i386:x86-64"); |
+ |
+ status_ = HS_STOPPED; |
+ return true; |
+} |
+ |
+bool HostMock::Step() { |
+ // We can only step if we are stopped |
+ if (HS_STOPPED != status_) return false; |
+ |
+ status_ = HS_RUNNING; |
+ return true; |
+} |
+ |
+bool HostMock::Continue() { |
+ // We can only step if we are stopped |
+ if (HS_STOPPED != status_) return false; |
+ |
+ status_ = HS_RUNNING; |
+ return true; |
+} |
+ |
+ |
+bool HostMock::Break() { |
+ char brk[2] = { 0x03, 0x00 }; |
noelallen_use_chromium
2010/12/07 23:04:44
Where is this used? This should have generated a
|
+ |
+ // We can only break if running |
+ if (HS_RUNNING != status_) return false; |
+ |
+ status_ = HS_STOPPING; |
+ |
+ 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
|
+ sig->sig = 5; |
+ sig->thread = 0; |
+ sig->rel = true; |
+ sig->ip = 0; |
+ |
+ signals_.push_front(sig); |
+ return true; |
+} |
+ |
+bool HostMock::Detach() { |
+ // We can only detach if stopped |
+ if (HS_STOPPED != status_) return false; |
+ return true; |
+} |
+ |
+#define MEMBLOCKSIZE 65536 |
+bool HostMock::GetMemory(void *dst, uint64_t addr, uint32_t size) { |
+ char *out = reinterpret_cast<char *>(dst); |
+ |
+ while (size) { |
+ uint64_t key = addr & ~(MEMBLOCKSIZE - 1); |
+ uint64_t offs = addr & (MEMBLOCKSIZE - 1); |
+ uint32_t max = static_cast<uint32_t>(MEMBLOCKSIZE - offs); |
+ char *data = memory_[key]; |
+ |
+ /* Truncate this iteration */ |
+ if (max > size) max = size; |
+ |
+ /* Check if block is availible */ |
noelallen_use_chromium
2010/12/07 23:04:44
Misleading:
Fail if block does not exist.
|
+ if (NULL == data) return false; |
+ |
+ /* Copy it out. */ |
+ memcpy(out, &data[addr - key], max); |
+ size -= max; |
+ out += max; |
noelallen_use_chromium
2010/12/07 23:04:44
Does this actually work? Addr does not appear to
|
+ } |
+ |
+ return true; |
+} |
+ |
+bool HostMock::SetMemory(const void *src, uint64_t addr, uint32_t size) { |
+ const char *in = reinterpret_cast<const char *>(src); |
+ |
+ while (size) { |
noelallen_use_chromium
2010/12/07 23:04:44
Same as above.
|
+ uint64_t key = addr & ~(MEMBLOCKSIZE - 1); |
+ uint64_t offs = addr & (MEMBLOCKSIZE - 1); |
+ uint32_t max = static_cast<uint32_t>(MEMBLOCKSIZE - offs); |
+ char *data = memory_[key]; |
+ |
+ /* Truncate this iteration */ |
+ if (max > size) max = size; |
+ |
+ /* Check if block is availible, if not allocate */ |
+ if (NULL == data) { |
+ data = new char[MEMBLOCKSIZE]; |
+ memory_[key] = data; |
+ } |
+ |
+ /* Copy it out. */ |
+ memcpy(&data[addr - key], in, max); |
+ size -= max; |
+ in += max; |
+ } |
+ |
+ return true; |
+} |
+ |
+bool HostMock::Request(const std::string &req, std::string *resp) { |
+ std::map<string, string>::const_iterator itr; |
+ itr = requests_.find(req); |
+ |
+ if (requests_.end() == itr) return false; |
+ |
+ *resp = itr->second; |
+ return true; |
+} |
+ |
+void HostMock::SetRequest(const std::string &req, const std::string &resp) { |
+ requests_[req] = resp; |
+} |
+ |
+ |
noelallen_use_chromium
2010/12/07 23:04:44
Either the source or the header should describe th
|
+void HostMock::AddSignal(int32_t signal, uint32_t thread) { |
+ SignalMock* sig = new SignalMock; |
+ sig->sig = signal; |
+ sig->thread = thread; |
+ sig->rel = true; |
+ sig->ip = 0; |
+ |
+ signals_.push_back(sig); |
+} |
+ |
+void HostMock::AddSignalAbs(int32_t signal, uint32_t thread, uint64_t ip) { |
+ SignalMock* sig = new SignalMock; |
+ sig->sig = signal; |
+ sig->thread = thread; |
+ sig->rel = false; |
+ sig->ip = ip; |
+ |
+ signals_.push_back(sig); |
+} |
+ |
+void HostMock::AddSignalDelta(int32_t signal, uint32_t thread, int64_t delta) { |
+ SignalMock* sig = new SignalMock; |
+ sig->sig = signal; |
+ sig->thread = thread; |
+ sig->rel = true; |
+ sig->ip = delta; |
+ |
+ signals_.push_back(sig); |
+} |
+ |
+// Wait to see if we receive a break |
+bool HostMock::WaitForBreak() { |
+ if (signals_.empty()) return false; |
+ |
+ SignalMock* sig = signals_.front(); |
+ signals_.pop_front(); |
+ |
+ Thread* thread = GetThread(sig->thread); |
+ if (thread) { |
+ const Abi *abi = thread->GetAbi(); |
+ const Abi::RegDef *def = abi->GetRegisterType(Abi::INST_PTR); |
+ uint64_t ip; |
+ |
+ if (sig->rel) { |
+ thread->GetRegister(def->index_, &ip); |
+ sig->ip += ip; |
noelallen_use_chromium
2010/12/07 23:04:44
Should this be
ip += sig->ip
|
+ } else { |
+ ip = sig->ip; |
+ } |
+ |
+ /* Update the current thread's IP */ |
+ thread->SetRegister(def->index_, &ip); |
+ } |
+ |
+ /* Generate a "signal" packet */ |
+ char tmp[64]; |
+ 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
|
+ ParseStopPacket(tmp); |
+ |
+ delete sig; |
+ return true; |
+} |
+ |
+ |
+ |
+} // namespace gdb_rsp |
+ |
+ |
Property changes on: src\trusted\gdb_rsp\host_mock.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |