1 #ifndef ROSE_BinaryAnalysis_Partitioner2_Utility_H
2 #define ROSE_BinaryAnalysis_Partitioner2_Utility_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #include <Rose/BinaryAnalysis/Partitioner2/AddressUsageMap.h>
7 #include <Rose/BinaryAnalysis/Partitioner2/BasicBlock.h>
8 #include <Rose/BinaryAnalysis/Partitioner2/DataBlock.h>
9 #include <Rose/BinaryAnalysis/Partitioner2/Function.h>
10 #include <Rose/CommandLine/IntervalParser.h>
12 #include <Rose/Diagnostics.h>
18 namespace BinaryAnalysis {
19 namespace Partitioner2 {
28 bool sortByExpression(
const BasicBlock::Successor&,
const BasicBlock::Successor&);
32 template<
class Container,
class Comparator>
34 isSorted(
const Container &container, Comparator sorted,
bool distinct=
true) {
35 typename Container::const_iterator current = container.begin();
36 if (current!=container.end()) {
37 typename Container::const_iterator next = current;
38 while (++next != container.end()) {
39 if ((distinct && !sorted(*current, *next)) || sorted(*next, *current))
47 template<
class Container,
class Value,
class Comparator>
48 typename Container::const_iterator
49 lowerBound(
const Container &container,
const Value &item, Comparator cmp) {
50 return std::lower_bound(container.begin(), container.end(), item, cmp);
52 template<
class Container,
class Value,
class Comparator>
53 typename Container::iterator
54 lowerBound(Container &container,
const Value &item, Comparator cmp) {
55 return std::lower_bound(container.begin(), container.end(), item, cmp);
59 template<
class Value,
class Comparator>
61 equalUnique(
const Value &a,
const Value &b, Comparator cmp) {
62 return !cmp(a, b) && !cmp(b, a);
66 template<
class Container,
class Value,
class Comparator>
68 insertUnique(Container &container,
const Value &item, Comparator cmp) {
69 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
70 typename Container::iterator lb = lowerBound(container, item, cmp);
71 if (lb==container.end() || !equalUnique(*lb, item, cmp)) {
72 container.insert(lb, item);
73 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
80 template<
class Container,
class Value,
class Comparator>
82 replaceOrInsert(Container &container,
const Value &item, Comparator cmp) {
83 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
84 typename Container::iterator lb = lowerBound(container, item, cmp);
85 if (lb == container.end() || !equalUnique(*lb, item, cmp)) {
86 container.insert(lb, item);
90 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
94 template<
class Container,
class Value,
class Comparator>
96 eraseUnique(Container &container,
const Value &item, Comparator cmp) {
97 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
98 typename Container::iterator lb = lowerBound(container, item, cmp);
99 if (lb!=container.end() && equalUnique(*lb, item, cmp)) {
107 template<
class Container,
class Value,
class Comparator>
109 existsUnique(
const Container &container,
const Value &item, Comparator cmp) {
112 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
113 typename Container::const_iterator lb = lowerBound(container, item, cmp);
114 if (lb==container.end() || cmp(*lb, item) || cmp(item, *lb))
120 template<
class Container,
class Value,
class Comparator>
122 getUnique(
const Container &container,
const Value &item, Comparator cmp) {
125 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
126 typename Container::const_iterator lb = lowerBound(container, item, cmp);
127 if (lb==container.end() || cmp(*lb, item) || cmp(item, *lb))
133 template<
class Container,
class Value,
class Comparator>
135 getOrInsertUnique(Container &container,
const Value &item, Comparator cmp) {
136 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
137 typename Container::iterator lb = lowerBound(container, item, cmp);
138 if (lb != container.end() && equalUnique(*lb, item, cmp)) {
141 container.insert(lb, item);
142 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(container, cmp,
true));
147 template<
class Container,
class Comparator>
149 isSupersetUnique(
const Container &sup,
const Container &sub, Comparator lessThan) {
150 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(sup, lessThan,
true));
151 ASSERT_require(!ROSE_PARTITIONER_EXPENSIVE_CHECKS || isSorted(sub, lessThan,
true));
152 typename Container::const_iterator isup = sup.begin(),
isub = sub.begin();
153 while (isup != sup.end() &&
isub != sub.end()) {
154 while (isup != sup.end() && lessThan(*isup, *isub))
156 if (isup == sup.end() || lessThan(*isub, *isup))
160 return isub == sub.end();
163 std::ostream& operator<<(std::ostream&,
const AddressUser&);
164 std::ostream& operator<<(std::ostream&,
const AddressUsers&);
165 std::ostream& operator<<(std::ostream&,
const AddressUsageMap&);
183 :
Super(valueSaver) {}
226 Trigger(
size_t nSkip,
size_t nTimes): nCalls_(0) {
246 size_t nCalls()
const {
return nCalls_; }
const ValueSaver::Ptr valueSaver() const
Property: functor responsible for saving a parsed value in user storage.
static Ptr instance()
Default allocating constructor.
bool isEmpty() const
True if interval is empty.
Trigger(const Settings &settings)
Armed for triggering when number of calls falls within when.
Base class for machine instructions.
Sawyer::SharedPointer< AddressIntervalParser > Ptr
Shared-ownership pointer to an AddressIntervalParser.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.
Sawyer::SharedPointer< DataBlock > Ptr
Shared pointer to a data block.
Parse an address interval.
A collection of related switch declarations.
Represents a synthesized function.
size_t nCalls() const
Number of times called.
Main namespace for the ROSE library.
static Interval baseSize(rose_addr_t lo, rose_addr_t size)
Construct an interval from one endpoint and a size.
bool contains(const Interval &other) const
Containment predicate.
size_t serialNumber()
Return the next serial number.
Trigger based on number of times called.
static std::string docString()
Documentation for command-line switches.
bool isArmed() const
True if trigger is armed.
Trigger()
Trigger armed for single call.
static Ptr instance(const Sawyer::CommandLine::ValueSaver::Ptr &valueSaver)
Allocating constructor.
Sawyer::SharedPointer< BasicBlock > Ptr
Shared pointer to a basic block.
void initDiagnostics()
Initialize diagnostics.
static Sawyer::CommandLine::SwitchGroup switches(Settings &)
Command-line switches to initialize settings.
static std::string docString()
Runtime documentation.
T greatest() const
Returns upper limit.
static Trigger always()
Armed to always trigger.
static Trigger never()
Armed to never trigger.
FunctionPtr Ptr
Shared-ownership pointer for function.
bool shouldTrigger()
Increment calls and return true if triggering.
static Trigger once()
Armed for one call.
void reset()
Reset number of calls to zero.
Trigger(size_t nSkip, size_t nTimes)
Armed for triggering after nSkip calls but not more than nTimes times.