ROSE  0.11.145.0
Linux.h
1 #ifndef ROSE_BinaryAnalysis_Debugger_Linux_H
2 #define ROSE_BinaryAnalysis_Debugger_Linux_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_DEBUGGER_LINUX
5 
6 #include <Rose/BinaryAnalysis/Debugger/Base.h>
7 #include <Rose/BinaryAnalysis/SystemCall.h>
8 
9 #include <Sawyer/Optional.h>
10 #include <sys/ptrace.h>
11 
12 namespace Rose {
13 namespace BinaryAnalysis {
14 namespace Debugger {
15 
17 class Linux: public Base {
19  // Types
21 public:
23  using Ptr = LinuxPtr;
24 
26  enum class DetachMode {
27  KILL,
28  DETACH,
29  CONTINUE,
30  NOTHING
31  };
32 
34  enum class Flag {
35  ATTACH = 0x00000001,
36  REDIRECT_INPUT = 0x00000002,
37  REDIRECT_OUTPUT = 0x00000004,
38  REDIRECT_ERROR = 0x00000008,
39  CLOSE_FILES = 0x00000010,
40  DEFAULT_FLAGS = 0x00000013
41  };
42 
46  class Specimen {
47  BitFlags<Flag> flags_; // operational flags
48  unsigned long persona_; // personality(2) flags
49 
50  // Members for running a program
51  boost::filesystem::path program_; // full path of executable program
52  std::vector<std::string> arguments_; // command-line arguments of executable program
53  boost::filesystem::path workingDirectory_; // name or working directory, or use CWD if empty
54  std::vector<boost::regex> clearEnvVars_; // clear environment variables matching these patterns
55  std::map<std::string, std::string> setEnvVars_; // environment variables to be set
56 
57  // Members for attaching to a process
58  int pid_ = -1; // process ID (int instead of pid_t for portability)
59 
60  public:
62  Specimen();
63 
65  Specimen(int pid); // implicit
66 
68  Specimen(const boost::filesystem::path&); // implicit
69 
71  Specimen(const boost::filesystem::path &name, const std::vector<std::string> &args);
72 
74  Specimen(const std::vector<std::string> &nameAndArgs); // implicit
75 
76  public:
83  const boost::filesystem::path& program() const;
84  void program(const boost::filesystem::path&);
93  const std::vector<std::string>& arguments() const;
94  void arguments(const std::vector<std::string>&);
102  void eraseEnvironmentVariable(const std::string&);
103 
109  void eraseMatchingEnvironmentVariables(const boost::regex&);
110 
114  void eraseAllEnvironmentVariables();
115 
121  void insertEnvironmentVariable(const std::string &name, const std::string &value);
122 
130  boost::filesystem::path workingDirectory() const;
131  void workingDirectory(const boost::filesystem::path&);
139  const BitFlags<Flag>& flags() const;
140  BitFlags<Flag>& flags();
150  unsigned long persona() const;
151  void persona(unsigned long bits);
162  bool randomizedAddresses() const;
163  void randomizedAddresses(bool);
172  int process() const;
173  void process(int pid);
177  void print(std::ostream &out) const;
178 
179  // Used internally.
180  char** prepareEnvAdjustments() const;
181  };
182 
184  // Private types
186 private:
188 
189  // What type of register values are cached?
190  enum class RegCacheType { NONE, REGS, FPREGS };
191 
192  // Low-level collection of register values.
193  using RegPage = std::array<uint8_t, 512>;
194 
195  // Low-level structure containing values for all registers.
196  struct AllRegValues {
197  RegPage regs; // integer registers
198  RegPage fpregs; // floating-point registers
199  };
200 
201 
203  // Data members
205 private:
206  Specimen specimen_; // description of specimen being debugged
207  int child_ = 0; // process being debugged (int, not pid_t, for Windows portability)
208  DetachMode autoDetach_ = DetachMode::KILL; // how to detach from the subordinate when deleting this debugger
209  int wstat_ = -1; // last status from waitpid
210  AddressIntervalSet breakPoints_; // list of break point addresses
211  int sendSignal_ = 0; // pending signal
212  UserRegDefs userRegDefs_; // how registers map to user_regs_struct in <sys/user.h>
213  UserRegDefs userFpRegDefs_; // how registers map to user_fpregs_struct in <sys/user.h>
214  size_t kernelWordSize_ = 0; // cached width in bits of kernel's words
215  RegPage regCache_; // latest register information read from subordinate
216  RegCacheType regCacheType_ = RegCacheType::NONE; // what are the contents of regsPage_?
217  Sawyer::Optional<rose_addr_t> syscallVa_; // address of some executable system call instruction.
218  SystemCall syscallDecls_; // to get declarations for system calls
219 
221  // Initialization and destruction.
223 public:
227  static Ptr instance();
228 
230  static Ptr instance(const Specimen &specimen, Sawyer::Optional<DetachMode> onDelete = Sawyer::Nothing());
231 
232  Linux();
233  ~Linux();
234 
236  // Attaching and detaching
238 public:
246  void attach(const Specimen&, Sawyer::Optional<DetachMode> onDelete = Sawyer::Nothing());
250  Sawyer::Optional<int> processId() const;
251 
257  DetachMode detachMode() const;
258  void detachMode(DetachMode);
264  size_t kernelWordSize();
265 
267  int waitpidStatus() const;
268 
270  // Running
272 public:
274  void stepIntoSystemCall(ThreadId);
275 
280  void runToSystemCall(ThreadId);
281 
283  // System calls
285 public:
289  int64_t remoteSystemCall(ThreadId, int syscallNumber);
290  int64_t remoteSystemCall(ThreadId, int syscallNumber,
291  uint64_t arg1);
292  int64_t remoteSystemCall(ThreadId, int syscallNumber,
293  uint64_t arg1, uint64_t arg2);
294  int64_t remoteSystemCall(ThreadId, int syscallNumber,
295  uint64_t arg1, uint64_t arg2, uint64_t arg3);
296  int64_t remoteSystemCall(ThreadId, int syscallNumber,
297  uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
298  int64_t remoteSystemCall(ThreadId, int syscallNumber,
299  uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5);
300  int64_t remoteSystemCall(ThreadId, int syscallNumber,
301  uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6);
302  int64_t remoteSystemCall(ThreadId, int syscallNumber, std::vector<uint64_t> args);
309  int remoteOpenFile(ThreadId, const boost::filesystem::path &fileName, unsigned flags, mode_t mode);
310 
312  int remoteCloseFile(ThreadId, unsigned remoteFd);
313 
317  rose_addr_t remoteMmap(ThreadId, rose_addr_t va, size_t nBytes, unsigned prot, unsigned flags, const boost::filesystem::path&,
318  off_t offset);
319 
321  // Overrides for methods declared and documented in the super class.
323 public:
324  virtual bool isAttached() override;
325  virtual void detach() override;
326  virtual void terminate() override;
327  virtual std::vector<ThreadId> threadIds() override;
328  virtual void executionAddress(ThreadId, rose_addr_t) override;
329  virtual rose_addr_t executionAddress(ThreadId) override;
330  virtual void setBreakPoint(const AddressInterval&) override;
331  virtual void clearBreakPoint(const AddressInterval&) override;
332  virtual void clearBreakPoints() override;
333  virtual void singleStep(ThreadId) override;
334  virtual void runToBreakPoint(ThreadId) override;
335  virtual Sawyer::Container::BitVector readRegister(ThreadId, RegisterDescriptor) override;
336  virtual void writeRegister(ThreadId, RegisterDescriptor, const Sawyer::Container::BitVector&) override;
337  virtual void writeRegister(ThreadId, RegisterDescriptor, uint64_t value) override;
338  virtual size_t readMemory(rose_addr_t va, size_t nBytes, uint8_t *buffer) override;
339  virtual std::vector<uint8_t> readMemory(rose_addr_t va, size_t nBytes) override;
340  virtual Sawyer::Container::BitVector readMemory(rose_addr_t va, size_t nBytes, ByteOrder::Endianness order) override;
341  virtual size_t writeMemory(rose_addr_t va, size_t nBytes, const uint8_t *bytes) override;
342  virtual bool isTerminated() override;
343  virtual std::string howTerminated() override;
344  virtual std::vector<RegisterDescriptor> availableRegisters() override;
345  virtual Sawyer::Container::BitVector readAllRegisters(ThreadId) override;
346  virtual void writeAllRegisters(ThreadId, const Sawyer::Container::BitVector&) override;
347 
348 private:
349  // Wait for subordinate or throw on error
350  void waitForChild();
351 
352  // Open /dev/null with the specified flags as the indicated file descriptor, closing what was previously on that
353  // descriptor. If an error occurs, the targetFd is closed anyway.
354  void devNullTo(int targetFd, int openFlags);
355 
356  // Get/set personality in a portable way
357  static unsigned long getPersonality();
358  static void setPersonality(unsigned long);
359 
360  // Address of a system call instruction. The initial search can be expensive, so the result is cached.
361  Sawyer::Optional<rose_addr_t> findSystemCall();
362 
363  // Low-level methods to read and write data for all known registers.
364  AllRegValues loadAllRegisters(ThreadId);
365  void saveAllRegisters(ThreadId, const AllRegValues&);
366 
367  // Update the register cache to contain the specified register. Return the offset to the start of the register
368  // inside the register cache.
369  size_t updateRegCache(RegisterDescriptor);
370 
371  // Send a ptrace command
372  long sendCommand(__ptrace_request, void *addr = nullptr, void *data = nullptr);
373  long sendCommandInt(__ptrace_request, void *addr, int i);
374 
375  // Load system call declarations from the appropriate header file
376  void declareSystemCalls(size_t nBits);
377 };
378 
379 std::ostream& operator<<(std::ostream&, const Linux::Specimen&);
380 
381 } // namespace
382 } // namespace
383 } // namespace
384 
385 #endif
386 #endif
const char * DetachMode(int64_t)
Convert Rose::BinaryAnalysis::Debugger::Linux::DetachMode enum constant to a string.
Main namespace for the ROSE library.
const char * RegPage(int64_t)
Convert Rose::BinaryAnalysis::Debugger::Linux::RegPage enum constant to a string. ...
void print(const StackVariables &, const Partitioner2::PartitionerConstPtr &, std::ostream &out, const std::string &prefix="")
Print info about multiple local variables.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
Represents no value.
Definition: Optional.h:32
Container associating values with keys.
Definition: Sawyer/Map.h:66