1#ifndef ROSE_BinaryAnalysis_Partitioner2_ParallelPartitioner_H
2#define ROSE_BinaryAnalysis_Partitioner2_ParallelPartitioner_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
6#include <Rose/BinaryAnalysis/InstructionCache.h>
7#include <Rose/Progress.h>
9#include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
10#include <Rose/BinaryAnalysis/Partitioner2/Semantics.h>
11#include <Sawyer/Attribute.h>
12#include <Sawyer/Graph.h>
13#include <Sawyer/IntervalSetMap.h>
14#include <Sawyer/Message.h>
15#include <Sawyer/SharedObject.h>
18namespace BinaryAnalysis {
19namespace Partitioner2 {
20namespace Experimental {
21namespace ParallelPartitioner {
37using FunctionReasons = BitFlags<SgAsmFunction::FunctionReason>;
41 size_t maxAnalysisBBlockSize = 20;
56void initDiagnostics();
63template<
class V,
class K>
71 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
79 void set(
const Key &key,
const Value &value) {
80 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
91 bool maybeSet(
const Key &key,
const Value &value) {
92 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
93 if (key_ && *key_ == key) {
106 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
107 if (key_ && *key_ == key)
116 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
117 if (key_ && *key_ == key) {
118 auto retval = value_;
130 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
139 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
140 return key_ && *key_ == key;
153 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
157 void set(
const Value &value) {
158 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
163 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
173 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
178 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
179 auto retval = value_;
185 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
190 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
202 typename Cache::Key key_;
203 typename Cache::OptionalValue value_;
209 : cache_(cache), key_(key), value_(cache_.take(key)), canceled_(false) {}
212 Borrowed(Cache &cache,
typename Cache::Key key,
const typename Cache::Value &value)
213 : cache_(cache), key_(key), value_(value), canceled_(false) {}
233 if (!canceled_ && value_ && !cache_.maybeSet(key_, *value_)) {
244 const typename Cache::OptionalValue&
get()
const {
253Borrowed<Cache> borrow(Cache &cache,
typename Cache::Key key) {
254 return Borrowed<Cache>(cache, key);
262Borrowed<Cache> borrow(Cache &cache,
typename Cache::Key key,
const typename Cache::Value &value) {
263 return Borrowed<Cache>(cache, key, value);
273 using Ptr = std::shared_ptr<InsnInfo>;
290 const rose_addr_t va_;
293 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
305 : ast_(insn), va_(insn->get_address()), size_(insn->get_size()), wasDecoded_(false) {
306 ASSERT_not_null(insn);
307 ASSERT_require(size_ > 0);
312 : va_(va), size_(0), wasDecoded_(false) {}
438 void merge(
const CfgEdge &other) {
439 types_.
set(other.types_);
450 friend std::ostream& operator<<(std::ostream&,
const CfgEdge&);
462 : va_(insnInfo->address()) {}
468 return va_ < other.va_;
495 DiscoverInstruction = 0,
540 virtual std::string
title()
const = 0;
573 std::string
title()
const override {
596 std::string
title()
const override {
609 bool operator()(
const std::shared_ptr<WorkItem>&,
const std::shared_ptr<WorkItem>&)
const;
620 using Item = std::shared_ptr<WorkItem>;
622 using Queue = std::priority_queue<Item, Container, WorkItemSorter>;
625 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
652 void operator()(std::shared_ptr<WorkItem> work,
Scheduler&) {
678 std::shared_ptr<InstructionCache> insnCache_;
680 rose_addr_t nExeVas_;
682 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
714 static Accuracy
choose(Accuracy a, Accuracy b);
824 std::vector<LockedInstruction>
locks;
825 std::vector<SgAsmInstruction*>
insns;
975 void run(
size_t maxWorkers);
Cache of instruction ASTs.
Pointer to an instruction.
Borrows a value from the cache and returns it later.
void cancel()
Cancel the borrow, so nothing is returned.
Borrowed(Cache &cache, typename Cache::Key key, const typename Cache::Value &value)
Arrange to return an already taken item back to the cache.
const Cache::OptionalValue & get() const
Return any value that has been borrowed.
void rtn()
Return the item now instead of later.
Borrowed(Cache &cache, typename Cache::Key key)
Borrow a cached item by taking it from the cache.
Implements a cache for a single datum.
bool maybeSet(const Key &key, const Value &value)
Set the cache only if it doesn't contain a value.
bool exists(const Key &key) const
Tests whether a value is cached.
OptionalValue get(const Key &key) const
Get the cached item if present.
void reset()
Remove the item from the cache.
OptionalValue take(const Key &key)
Take the cached item if present.
void set(const Key &key, const Value &value)
Set the cache to hold the specified key / value pair.
Decode an instruction at a specific address.
std::string title() const override
A one-line title.
void run() override
Performs the work.
Information about an instruction.
rose_addr_t address() const
Address of instruction.
void functionReasons(FunctionReasons)
Property: Function reasons.
InsnInfo(const InstructionPtr &insn)
Construct info with decoded instruction.
bool wasDecoded() const
Whether any attempt was made to decode this instruction.
static uint64_t hash(const List &)
Hash instruction list.
std::vector< Ptr > List
List of pointers to InsnInfo objects.
std::shared_ptr< InsnInfo > Ptr
Shared ownership pointer.
void eraseFunctionReasons(FunctionReasons)
Property: Function reasons.
Sawyer::Optional< size_t > size() const
Size of instruciton in bytes if known.
void setDecoded()
Whether any attempt was made to decode this instruction.
InsnInfo(rose_addr_t va)
Construct info from only an address.
const Cached & cached() const
Cached information.
Sawyer::Optional< AddressInterval > hull() const
Location of instruction if known.
void insertFunctionReasons(FunctionReasons)
Property: Function reasons.
static bool addressOrder(const Ptr &a, const Ptr &b)
For sorty by address.
FunctionReasons functionReasons() const
Property: Function reasons.
InstructionPtr ast() const
Get the underlying instruction AST.
Cached & cached()
Cached information.
Find unused executable addresses.
std::string title() const override
A one-line title.
void run() override
Performs the work.
Discovers instructions, basic blocks, and functions.
InsnCfg & insnCfg()
Control flow graph.
bool isFunctionCall(rose_addr_t insnVa, Accuracy accuracy)
Determine whether the instruction is a function call.
void transferResults(const Rose::BinaryAnalysis::Partitioner2::PartitionerPtr &out)
Build results from CFG.
std::vector< SymbolicExpression::Ptr > computeSuccessors(rose_addr_t insnVa, Accuracy accuracy)
Return the computed symbolic successors for an instruction.
InsnInfo::Ptr existingInstruction(rose_addr_t)
Return information about a vertex of the global CFG.
void statusReports()
Generate status reports every so often.
AddressSet computedConcreteSuccessors(rose_addr_t insnVa, Accuracy accuracy)
Return the computed concrete successors for an instruction.
AddressIntervalSet unusedExecutableVas(AddressInterval where) const
All unused executable addresses within region.
InstructionPtr decodeInstruction(rose_addr_t)
Decode an instruction at the specified address.
size_t nDecodedAddresses() const
Amount of memory with known instructions.
InsnInfo::List basicBlockContaining(rose_addr_t) const
Find basic block containing specified instruction.
std::map< rose_addr_t, rose_addr_t > calculateInsnToBbMap() const
Create a map from instructions to basic blocks.
static Accuracy choose(Accuracy a, Accuracy b)
Accuracy setting.
std::vector< InsnInfo::List > allBasicBlocks() const
List of all basic blocks.
static bool addressOrder(const InsnInfo::List &a, const InsnInfo::List &b)
Predicate to order blocks by starting address.
InstructionPtr existingInstructionAst(rose_addr_t)
Returns the AST for an instruction.
Borrowed< CachedItem< Semantics::RiscOperatorsPtr, uint64_t > > basicBlockSemantics(const InsnInfo::List &)
Calculate the semantics for a basic block.
LockInCache lockInCache(const InsnInfo::List &)
Lock instructions in the cache.
CreateLinkedCfgVertices createLinkedCfgVertices(rose_addr_t sourceVa, rose_addr_t targetVa, const CfgEdge &)
Add an edge and maybe vertices to the global CFG.
rose_addr_t remap()
Figure out how to remap memory.
void printInsnCfg(std::ostream &) const
Output the CFG as a DOT graph.
const Settings & settings() const
Behavior settings.
Settings & settings()
Behavior settings.
Progress::Ptr progress() const
Progress reports for ratio of memory disassembled.
InstructionCache & instructionCache() const
The instruction cache.
void scheduleNextUnusedRegion(const AddressInterval &where)
Add a work item to decode lowest unused addresses.
MemoryMap::Ptr memoryMap() const
Returns the memory map used for disassembling.
void run(size_t maxWorkers)
Run in parallel.
std::vector< SymbolicExpression::Ptr > computeSuccessors(const InsnInfo::List &, Accuracy accuracy)
Return the computed symbolic successors for an instruction.
const InsnCfg & insnCfg() const
Control flow graph.
void scheduleDecodeInstruction(rose_addr_t insnVa)
Add a work item to decode an instruction.
std::map< rose_addr_t, AddressSet > assignFunctions()
Assign instructions to functions.
InsnInfo::List basicBlockEndingAt(rose_addr_t, size_t maxInsns=UNLIMITED) const
Find a basic block's worth of instructions.
InsnInfo::Ptr makeInstruction(rose_addr_t)
Create and return information about a vertex of the CFG.
void dumpInsnCfg(std::ostream &, const Rose::BinaryAnalysis::Partitioner2::Partitioner &) const
Output the CFG as text for debugging.
bool isRunning() const
Whether the partitioner is running.
InsnInfo::Ptr makeInstruction(rose_addr_t, const InstructionPtr &)
Create and return information about a vertex of the CFG.
Partitioner(const MemoryMap::Ptr &memory, const Disassembler::BasePtr &decoder, const Settings &settings=Settings())
Constructor new partitioner.
Schedules work items for execution.
std::vector< Item > Container
Type of items stored in this scheduler.
bool isEmpty() const
Test whether any work remains to be done.
Item next()
Returns the next item of work to be performed.
void reportStatus(std::ostream &) const
Output a status report.
void insert(const Item &)
Insert a new work item into the work list.
Item of work to be completed.
Priority
Coarse priority for work items.
virtual void run()=0
Performs the work.
Priority priority() const
Priority set at construction time.
Partitioner & partitioner() const
Partitioner set at construction time.
WorkItem(Partitioner &partitioner, Priority priority, uint64_t sort)
Construct new item with given priority for a specific partitioner.
virtual std::string title() const =0
A one-line title.
bool operator<(const WorkItem &) const
Sort work.
Handles work items when they're dispatched to a worker thread.
Partitions instructions into basic blocks and functions.
API and storage for attributes.
BitFlags & set(Enum e)
Set the specified bit.
T least() const
Returns lower limit.
void reset()
Reset as if default-constructed.
Base class for reference counted objects.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
@ LOW
Enum type for precision.
@ HIGH
High precision, but slow.
EdgeType
Partitioner control flow edge types.
@ E_NORMAL
Normal control flow edge, nothing special.
SemanticMemoryParadigm
Organization of semantic memory.
@ MAP_BASED_MEMORY
Fast but not precise.
ROSE_UTIL_API std::string addrToString(uint64_t value, size_t nbits=0)
Convert a virtual address to a string.
const size_t UNLIMITED
Effectively unlimited size.
size_t fastRandomIndex(size_t n, size_t seed=0)
Thread-safe random number generator.
CachedItem< Semantics::RiscOperatorsPtr, uint64_t > semantics
Symbolic semantics of basic block.
CachedItem< bool, uint64_t > isFunctionCall
Is this a function call.
Information returned by createLinkedCfgVertices.
bool createdEdge
Whether the edge was created.
bool createdSource
Whether the source vertex was created.
InsnInfo::Ptr target
Target instruction.
InsnInfo::Ptr source
Source instruction.
bool createdTarget
Whether the target vertex was created.
Object returned by lockInCache.
std::vector< LockedInstruction > locks
The locking pointers.
std::vector< SgAsmInstruction * > insns
The raw pointers.
SemanticMemoryParadigm semanticMemoryParadigm
Chronological or address hashes for indexing memory.
size_t minHoleSearch
Do now search unused regions smaller than this many bytes.
Accuracy successorAccuracy
Max number of insns in basic block during various analyses.
Accuracy functionCallDetectionAccuracy
How to determine whether something is a function call.