ROSE 0.11.145.147
Concolic/I386Linux/Architecture.h
1#ifndef ROSE_BinaryAnalysis_Concolic_I386Linux_Architecture_H
2#define ROSE_BinaryAnalysis_Concolic_I386Linux_Architecture_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_CONCOLIC_TESTING
5
6#include <Rose/BinaryAnalysis/Concolic/Architecture.h>
7#include <Rose/BinaryAnalysis/Concolic/ExecutionEvent.h>
8#include <Rose/BinaryAnalysis/Concolic/SharedMemory.h>
9#include <Rose/BinaryAnalysis/Concolic/SystemCall.h>
10#include <Rose/BinaryAnalysis/MemoryMap.h>
11#include <Rose/Yaml.h>
12
13#include <Sawyer/Callbacks.h>
14
15#include <boost/filesystem.hpp>
16
17namespace Rose {
18namespace BinaryAnalysis {
19namespace Concolic {
20namespace I386Linux {
21
23// Linux Intel 80386 and compatible hardware architecture.
25
27class Architecture: public Concolic::Architecture {
28 using Super = Concolic::Architecture;
29
30public:
32 using Ptr = ArchitecturePtr;
33
34private:
35 bool markingArgvAsInput_ = true;
36 bool markingEnvpAsInput_ = false;
37
38protected:
39 Architecture(const std::string&); // for instantiating a factory
40 Architecture(const DatabasePtr&, TestCaseId);
41public:
42 ~Architecture();
43
44public:
46 static Ptr factory();
47
53 static Ptr instance(const DatabasePtr&, TestCaseId, const Yaml::Node &config);
54 static Ptr instance(const DatabasePtr&, const TestCasePtr&, const Yaml::Node &config);
57public:
58 // Same as super class, but casts result to a Linux debugger.
59 Debugger::LinuxPtr debugger() const;
60
62 RegisterDescriptor systemCallReturnRegister();
63
64public:
65 // These are documented in the base class.
66 virtual bool matchFactory(const Yaml::Node&) const override;
67 virtual Super::Ptr instanceFromFactory(const DatabasePtr&, TestCaseId, const Yaml::Node &config) const override;
68 virtual Partitioner2::PartitionerPtr partition(const Partitioner2::EnginePtr&, const std::string &specimen) override;
69 virtual void configureSystemCalls() override;
70 virtual void configureSharedMemory(const Yaml::Node &config) override;
71 virtual void load(const boost::filesystem::path&) override;
72 virtual ByteOrder::Endianness memoryByteOrder() override;
73 virtual std::vector<ExecutionEventPtr> createMemoryRestoreEvents() override;
74 virtual std::vector<ExecutionEventPtr> createMemoryHashEvents() override;
75 virtual std::vector<ExecutionEventPtr> createMemoryAdjustEvents(const MemoryMap::Ptr&, rose_addr_t insnVa) override;
76 virtual bool playEvent(const ExecutionEventPtr&) override;
77 virtual void mapMemory(const AddressInterval&, unsigned permissions) override;
78 virtual void unmapMemory(const AddressInterval&) override;
79 virtual void createInputVariables(const Partitioner2::PartitionerConstPtr&, const Emulation::RiscOperatorsPtr&,
80 const SmtSolver::Ptr &solver) override;
81 virtual void systemCall(const Partitioner2::PartitionerConstPtr&,
82 const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&) override;
83 virtual void advanceExecution(const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&) override;
84 virtual InstructionSemantics::BaseSemantics::DispatcherPtr
85 makeDispatcher(const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&) override;
86
87private:
88 // Maps a scratch page for internal use and updates scratchVa_ with the address of the page.
89 void mapScratchPage();
90
91 // Copy (share) some data from the dst map to the src map at where. Generate map and write events that will map the memory
92 // and initialize it when played back.
93 std::vector<ExecutionEventPtr> copyMemory(const MemoryMap::Ptr &src, const MemoryMap::Ptr &dst, const AddressInterval &where,
94 rose_addr_t insnVa);
95
96 // List of process memory segments that are not special.
97 std::vector<MemoryMap::ProcessMapRecord> disposableMemory();
98
99 // Unmap nearly all memory. The scratch page is not unmapped, nor is the VDSO or VVAR.
100 void unmapAllMemory();
101
102 // When stopped at the beginning of a system call, return the system call function number. See <sys/unistd_32.h> for the
103 // mapping function system call number to the Linux kernel function that handles it.
104 uint64_t systemCallFunctionNumber(const Partitioner2::PartitionerConstPtr&,
105 const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&);
106
107 // Returns the system call argument.
108 InstructionSemantics::BaseSemantics::SValuePtr
109 systemCallArgument(const Partitioner2::PartitionerConstPtr&,
110 const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&, size_t argNumber);
111
112 // Returns the system call return value.
113 InstructionSemantics::BaseSemantics::SValuePtr
114 systemCallReturnValue(const Partitioner2::PartitionerConstPtr&,
115 const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&);
116
117 // Modify the symbolic system call return value.
118 InstructionSemantics::BaseSemantics::SValuePtr
119 systemCallReturnValue(const Partitioner2::PartitionerConstPtr&,
120 const InstructionSemantics::BaseSemantics::RiscOperatorsPtr&,
121 const InstructionSemantics::BaseSemantics::SValuePtr&);
122
123};
124
126// Linux i386 specific system call operations.
128
132class SyscallBase: public SyscallCallback {
133 ExecutionEventPtr latestReturnEvent_; // event for most recent system call return
134 ExecutionEventPtr penultimateReturnEvent_; // event for next most recent system call return
135
136public:
137 SyscallBase();
138 virtual ~SyscallBase();
139
145 void hello(const std::string &name, const SyscallContext&) const;
146
152 virtual void playback(SyscallContext&) = 0;
153
171 virtual void handlePreSyscall(SyscallContext&) {}
172 virtual void handlePostSyscall(SyscallContext&) = 0;
189 ExecutionEventPtr latestReturnEvent() const;
190 ExecutionEventPtr penultimateReturnEvent() const;
197 void showRecentReturnValues(std::ostream&, const SyscallContext&) const;
198
204 SymbolicExpressionPtr penultimateSymbolicReturn() const;
205
206public:
207 // Subclasses need not provide a function operator.
208 virtual bool operator()(bool /*handled*/, SyscallContext&) override final;
209};
210
216class SyscallUnimplemented: public SyscallBase {
217protected:
218 SyscallUnimplemented();
219public:
220 ~SyscallUnimplemented();
221
222public:
224 static Ptr instance();
225
226 void playback(SyscallContext&) override;
227 void handlePostSyscall(SyscallContext&) override;
228};
229
234class SyscallReturnsInput: public SyscallBase {
235protected:
236 SyscallReturnsInput();
237public:
238 ~SyscallReturnsInput();
239
240public:
242 static Ptr instance();
243
244 void playback(SyscallContext&) override;
245 void handlePostSyscall(SyscallContext&) override;
246};
247
249class SyscallTerminates: public SyscallBase {
250protected:
251 SyscallTerminates();
252public:
253 ~SyscallTerminates();
254
255public:
257 static Ptr instance();
258
259 void playback(SyscallContext&) override;
260 void handlePostSyscall(SyscallContext&) override;
261};
262
266class SyscallReturn: public SyscallBase {
267protected:
268 SyscallReturn();
269public:
270 ~SyscallReturn();
271
272protected:
279 virtual std::pair<SymbolicExpressionPtr, Sawyer::Optional<uint64_t>> makeReturnConstraint(SyscallContext&) = 0;
280
281public:
282 void handlePostSyscall(SyscallContext&) override final;
283};
284
290class SyscallConstant: public SyscallReturn {
291protected:
292 SyscallConstant();
293public:
294 ~SyscallConstant();
295
296public:
298 static Ptr instance();
299
300 void playback(SyscallContext&) override;
301 std::pair<SymbolicExpressionPtr, Sawyer::Optional<uint64_t>> makeReturnConstraint(SyscallContext&) override;
302};
303
307class SyscallNondecreasing: public SyscallReturn {
308protected:
309 SyscallNondecreasing();
310public:
311 ~SyscallNondecreasing();
312
313public:
315 static Ptr instance();
316
317 void playback(SyscallContext&) override;
318 std::pair<SymbolicExpressionPtr, Sawyer::Optional<uint64_t>> makeReturnConstraint(SyscallContext&) override;
319};
320
322class SyscallAccess: public SyscallBase {
323protected:
324 SyscallAccess();
325public:
326 ~SyscallAccess();
327
328public:
330 static Ptr instance();
331
332 void playback(SyscallContext&) override;
333 void handlePostSyscall(SyscallContext&) override;
334};
335
337class SyscallBrk: public SyscallBase {
338protected:
339 SyscallBrk();
340public:
341 ~SyscallBrk();
342
343public:
345 static Ptr instance();
346
347 void playback(SyscallContext&) override;
348 void handlePostSyscall(SyscallContext&) override;
349};
350
352class SyscallMmap2: public SyscallBase {
353protected:
354 SyscallMmap2();
355public:
356 ~SyscallMmap2();
357
358public:
360 static Ptr instance();
361
362 void playback(SyscallContext&) override;
363 void handlePostSyscall(SyscallContext&) override;
364};
365
367class SyscallOpenat: public SyscallBase {
368protected:
369 SyscallOpenat();
370public:
371 ~SyscallOpenat();
372
373public:
375 static Ptr instance();
376
377 void playback(SyscallContext&) override;
378 void handlePostSyscall(SyscallContext&) override;
379};
380
381} // namespace
382} // namespace
383} // namespace
384} // namespace
385
386#endif
387#endif
ROSE_DLL_API void load(SgProject *project, std::list< std::string > const &filepaths)
Load ASTs that have been saved to files.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
The ROSE library.
const char * Architecture(int64_t)
Convert Rose::BinaryAnalysis::Disassembler::Mips::Decoder::Architecture enum constant to a string.