1#ifndef ROSE_BinaryAnalysis_Debugger_Gdb_H
2#define ROSE_BinaryAnalysis_Debugger_Gdb_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_DEBUGGER_GDB
5#include <Rose/BinaryAnalysis/Debugger/Base.h>
7#include <Rose/BinaryAnalysis/AddressIntervalSet.h>
8#include <Rose/BinaryAnalysis/Debugger/GdbResponse.h>
11#include <boost/asio.hpp>
12#include <boost/filesystem.hpp>
13#include <boost/process.hpp>
15#include <condition_variable>
21namespace BinaryAnalysis {
25class Gdb:
public Base {
41 std::string host =
"localhost";
46 boost::filesystem::path gdbName_ =
"gdb-multiarch";
47 boost::filesystem::path executable_;
59 Specimen(
const boost::filesystem::path &exeName);
68 Specimen(
const boost::filesystem::path &exeName,
const std::string &host, uint16_t port);
74 const boost::filesystem::path &gdbName()
const;
75 void gdbName(
const boost::filesystem::path&);
84 const boost::filesystem::path& executable()
const;
85 void executable(
const boost::filesystem::path&);
91 const Remote& remote()
const;
92 void remote(
const Remote&);
93 void remote(
const std::string &host, uint16_t port);
97 void print(std::ostream&)
const;
110 std::condition_variable cond_;
112 std::list<Value> items_;
113 bool isClosed_ =
false;
117 void append(
const Value &item) {
118 const std::lock_guard<std::mutex> lock(mutex_);
119 items_.push_back(item);
125 const std::lock_guard<std::mutex> lock(mutex_);
133 const std::lock_guard<std::mutex> lock(mutex_);
141 const std::lock_guard<std::mutex> lock(mutex_);
142 if (items_.empty()) {
145 Value item = items_.front();
153 std::unique_lock<std::mutex> lock(mutex_);
154 while (items_.empty() && !isClosed_)
156 if (items_.empty()) {
159 Value item = items_.front();
167 std::lock_guard<std::mutex> lock(mutex_);
175 bool hasEndMarker =
false;
177 struct ResultRecord {
181 std::list<Yaml::Node> results;
184 std::list<ResultRecord> resultRecord;
189 RegisterDescriptor reg_;
192 explicit RegInfo(RegisterDescriptor);
193 explicit RegInfo(
size_t);
194 RegisterDescriptor reg()
const;
195 size_t nBits()
const;
202 std::thread gdbThread_;
203 Fifo<std::string> gdbOutput_;
204 boost::asio::io_context ioctx_;
205 boost::process::async_pipe gdbOutputPipe_;
206 boost::process::opstream gdbInput_;
207 boost::asio::streambuf gdbOutputBuffer_;
208 std::vector<std::pair<std::string, RegInfo>> registers_;
209 std::list<GdbResponse> responses_;
211 std::map<
Address,
unsigned > gdbBreakPoints_;
212 std::future<int> exitCodeFuture_;
215 bool checkWrites_ =
false;
217 bool checkWrites_ =
true;
232 static Ptr instance();
237 static Ptr instance(
const Specimen&);
250 bool checkWrites()
const;
251 void checkWrites(
bool);
261 virtual void attach(
const Specimen&);
273 const std::list<GdbResponse>& sendCommand(
const std::string&);
279 std::list<GdbResponse> readRequiredResponses();
285 std::list<GdbResponse> readOptionalResponses();
290 const std::list<GdbResponse>& responses()
const;
293 void resetResponses();
298 const std::vector<std::pair<std::string, RegInfo>>& registerNames()
const;
304 virtual bool isAttached()
override;
305 virtual void detach()
override;
306 virtual void terminate()
override;
307 virtual std::vector<ThreadId> threadIds()
override;
308 virtual void setBreakPoint(
const AddressInterval&)
override;
309 virtual void setBreakPoints(
const AddressIntervalSet&)
override;
311 virtual void clearBreakPoint(
const AddressInterval&)
override;
312 virtual void clearBreakPoints()
override;
313 virtual void singleStep(ThreadId)
override;
314 virtual void runToBreakPoint(ThreadId)
override;
316 virtual std::vector<RegisterDescriptor> availableRegisters()
override;
318 virtual void writeRegister(ThreadId, RegisterDescriptor, uint64_t value)
override;
319 virtual size_t readMemory(Address va,
size_t nBytes, uint8_t *buffer)
override;
320 virtual std::vector<uint8_t> readMemory(Address va,
size_t nBytes)
override;
322 virtual size_t writeMemory(Address va,
size_t nBytes,
const uint8_t *bytes)
override;
323 virtual bool isTerminated()
override;
324 virtual std::string howTerminated()
override;
333 std::list<GdbResponse> readResponseSet(
bool required);
340 RegisterDescriptor findRegister(RegisterDescriptor)
const;
343 bool gdbHandlesBreakPoints()
const;
350 std::string parseDataListRegisterValuesValue(
const std::string&);
356std::ostream& operator<<(std::ostream&,
const Gdb::Specimen&);
Holds a value or nothing.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
void print(const GlobalVariables &, const Partitioner2::PartitionerConstPtr &, std::ostream &out, const std::string &prefix="")
Print info about multiple global variables.
Sawyer::Container::IntervalSet< AddressInterval > AddressIntervalSet
A set of virtual addresses.
std::uint64_t Address
Address.
size_t nBits(Unsigned=Unsigned(0))
Number of bits in a type or value.
ROSE_UTIL_API std::string toString(const Path &)
Convert a path to a string.
ROSE_DLL_API void clear()
Empties the memory pool of all nodes.
@ ERROR
Error messages that indicate an abnormal situation from which the program was able to at least partia...
const char * ResultClass(int64_t)
Convert Rose::BinaryAnalysis::Debugger::Gdb::Response::ResultRecord::ResultClass enum constant to a s...