Skip to content

Commit

Permalink
Remove QVariant from BinarySectionImpl
Browse files Browse the repository at this point in the history
  • Loading branch information
ceeac committed Dec 27, 2020
1 parent b71ae63 commit d4a33d4
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 116 deletions.
2 changes: 1 addition & 1 deletion src/boomerang-plugins/loader/elf/ElfBinaryLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ bool ElfBinaryLoader::loadFromMemory(QByteArray &img)
}

if (par.sectionType == SHT_STRTAB) {
sect->setAttributeForRange("StringsSection", true, sect->getSourceAddr(),
sect->setAttributeForRange("StringsSection", sect->getSourceAddr(),
sect->getSourceAddr() + sect->getSize());
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/boomerang-plugins/loader/machO/MachOBinaryLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,15 @@ bool MachOBinaryLoader::loadFromMemory(QByteArray &img)
if ((0 == strcmp(sections[s_idx].sectname, "__cfstring")) ||
(0 == strcmp(sections[s_idx].sectname, "__cstring"))) {
sect->setAttributeForRange(
"StringsSection", true, Address(BMMH(sections[s_idx].addr)),
"StringsSection", Address(BMMH(sections[s_idx].addr)),
Address(BMMH(sections[s_idx].addr) + BMMH(sections[s_idx].size)));
}

sect->setAttributeForRange(
"ReadOnly", (BMMH(sections[i].flags) & VM_PROT_WRITE) ? true : false,
Address(BMMH(sections[s_idx].addr)),
Address(BMMH(sections[s_idx].addr) + BMMH(sections[s_idx].size)));
if ((BMMH(sections[i].flags) & VM_PROT_WRITE) == 0) {
sect->setAttributeForRange(
"ReadOnly", Address(BMMH(sections[s_idx].addr)),
Address(BMMH(sections[s_idx].addr) + BMMH(sections[s_idx].size)));
}
}

DEBUG_PRINT("loaded segment %1 %2 in mem %3 in file code=%4 data=%5 readonly=%6", a.value(),
Expand Down
2 changes: 1 addition & 1 deletion src/boomerang/db/Prog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ bool Prog::isInStringsSection(Address a) const

const BinarySection *si = static_cast<const BinarySection *>(
m_binaryFile->getImage()->getSectionByAddr(a));
return si && si->isAttributeInRange("StringsSection", a, a + 1);
return si && si->addressHasAttribute("StringsSection", a);
}


Expand Down
2 changes: 1 addition & 1 deletion src/boomerang/db/binary/BinaryImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ bool BinaryImage::isReadOnly(Address addr) const
return true;
}

return section->isAttributeInRange("ReadOnly", addr, addr + 1);
return section->addressHasAttribute("ReadOnly", addr);
}


Expand Down
89 changes: 12 additions & 77 deletions src/boomerang/db/binary/BinarySection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,10 @@
#include "boomerang/util/Util.h"
#include "boomerang/util/log/Log.h"

#include <QVariantMap>

#include <stdexcept>


struct VariantHolder
{
mutable QMultiMap<QString, QVariant> val;
QVariantMap &get() const { return val; }
VariantHolder &operator+=(const VariantHolder &other)
{
val = val.unite(other.val);
return *this;
}

bool operator==(const VariantHolder &other) const { return val == other.val; }
};

class BinarySectionImpl
{
public:
void clearDefinedArea() { m_hasDefinedValue.clear(); }

void addDefinedArea(Address from, Address to) { m_hasDefinedValue.insert(from, to); }

bool isAddressBss(Address a) const
Expand All @@ -47,58 +28,25 @@ class BinarySectionImpl
return !m_hasDefinedValue.isContained(a);
}

void setAttributeForRange(const QString &name, const QVariant &val, Address from, Address to)
void setAttributeForRange(const QString &name, Address from, Address to)
{
QVariantMap vmap;

vmap[name] = val;
VariantHolder map{ vmap };
m_attributeMap.insert(from, to, map);
m_attributeMap[name].insert(from, to);
}

QVariant attributeInRange(const QString &attrib, Address from, Address to) const
bool addressHasAttribute(const QString &attrib, Address addr) const
{
auto startIt = m_attributeMap.find(from);
auto endIt = m_attributeMap.find(to);

if (startIt == m_attributeMap.end()) {
return QVariant();
}
auto it = m_attributeMap.find(attrib);

QList<QVariant> vals;

for (auto iter = startIt; iter != endIt; ++iter) {
if (iter->second.get().contains(attrib)) {
vals << iter->second.get()[attrib];
}
}

if (vals.size() == 1) {
return vals.front();
if (it == m_attributeMap.end()) {
return false;
}

return QVariant(vals);
}

QVariantMap getAttributesForRange(Address from, Address to)
{
QMultiMap<QString, QVariant> res;
auto v = m_attributeMap.equalRange(from, to);

if (v.first == m_attributeMap.end()) {
return std::move(res);
}

for (auto iter = v.first; iter != v.second; ++iter) {
res.unite(iter->second.get());
}

return std::move(res);
return it->second.isContained(addr);
}

public:
IntervalSet<Address> m_hasDefinedValue;
IntervalMap<Address, VariantHolder> m_attributeMap;
std::map<QString, IntervalSet<Address>> m_attributeMap;
};


Expand Down Expand Up @@ -160,32 +108,19 @@ void BinarySection::resize(uint32_t sz)
}


void BinarySection::clearDefinedArea()
{
m_impl->clearDefinedArea();
}


void BinarySection::addDefinedArea(Address from, Address to)
{
m_impl->addDefinedArea(from, to);
}


void BinarySection::setAttributeForRange(const QString &name, const QVariant &val, Address from,
Address to)
{
m_impl->setAttributeForRange(name, val, from, to);
}


QVariantMap BinarySection::getAttributesForRange(Address from, Address to)
void BinarySection::setAttributeForRange(const QString &name, Address from, Address to)
{
return m_impl->getAttributesForRange(from, to);
m_impl->setAttributeForRange(name, from, to);
}


bool BinarySection::isAttributeInRange(const QString &attrib, Address from, Address to) const
bool BinarySection::addressHasAttribute(const QString &attrName, Address addr) const
{
return !m_impl->attributeInRange(attrib, from, to).isNull();
return m_impl->addressHasAttribute(attrName, addr);
}
10 changes: 2 additions & 8 deletions src/boomerang/db/binary/BinarySection.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
#include "boomerang/util/Types.h"

#include <QString>
#include <QVariant>


class QVariant;


/// File-format independent access to sections of binary files.
Expand Down Expand Up @@ -62,12 +58,10 @@ class BOOMERANG_API BinarySection
bool isAddressBss(Address addr) const;

bool anyDefinedValues() const;
void clearDefinedArea();
void addDefinedArea(Address from, Address to);

void setAttributeForRange(const QString &name, const QVariant &val, Address from, Address to);
QVariantMap getAttributesForRange(Address from, Address to);
bool isAttributeInRange(const QString &attrib, Address from, Address to) const;
void setAttributeForRange(const QString &attrName, Address from, Address to);
bool addressHasAttribute(const QString &attrName, Address addr) const;

private:
class BinarySectionImpl *m_impl;
Expand Down
2 changes: 1 addition & 1 deletion src/boomerang/util/IntervalMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class IntervalMap

/**
* \returns an iterator range containing all intervals between \p lower and \p upper.
* If there are no intervals between lower and upper, the function returns (end(), end).
* If there are no intervals between lower and upper, the function returns (end(), end()).
*/
std::pair<const_iterator, const_iterator> equalRange(const Key &lower, const Key &upper) const
{
Expand Down
43 changes: 42 additions & 1 deletion src/boomerang/util/IntervalSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class IntervalSet
return m_data.insert(it, Interval<T>(minLower, maxUpper));
}


/**
* Returns an iterator range containing all intervals between \p lower and \p upper
*/
Expand Down Expand Up @@ -114,6 +113,48 @@ class IntervalSet
return std::make_pair(itLower, itUpper);
}

/**
* Returns an iterator range containing all intervals between \p lower and \p upper
*/
std::pair<const_iterator, const_iterator> equalRange(const T &lower, const T &upper) const
{
return equalRange(Interval<T>(lower, upper));
}

std::pair<const_iterator, const_iterator> equalRange(const Interval<T> &interval) const
{
if (interval.lower() >= interval.upper()) {
return { end(), end() };
}

typename Data::iterator itLower = end();
typename Data::iterator itUpper = end();

// todo: speed up
for (iterator existingIt = begin(); existingIt != end(); ++existingIt) {
if (existingIt->lower() >= interval.upper()) {
return { end(), end() }; // no blocking intervals
}
else if (existingIt->upper() > interval.lower()) {
itLower = existingIt;
break;
}
}

if (itLower == end()) {
return { end(), end() };
}

for (iterator existingIt = std::next(itLower); existingIt != end(); ++existingIt) {
if (existingIt->lower() >= interval.upper()) {
itUpper = existingIt;
break;
}
}

return std::make_pair(itLower, itUpper);
}

/// \returns true if \p value is contained in any interval of this set.
bool isContained(const T &value) const
{
Expand Down
2 changes: 1 addition & 1 deletion tests/unit-tests/boomerang/db/binary/BinaryImageTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ void BinaryImageTest::testIsReadOnly()
QVERIFY(img.isReadOnly(Address(0x1800)));
sect1->setReadOnly(false);

sect1->setAttributeForRange("ReadOnly", true, Address(0x1400), Address(0x2000));
sect1->setAttributeForRange("ReadOnly", Address(0x1400), Address(0x2000));
QVERIFY(!img.isReadOnly(Address(0x1200)));
QVERIFY(img.isReadOnly(Address(0x1800)));
}
Expand Down
22 changes: 3 additions & 19 deletions tests/unit-tests/boomerang/db/binary/BinarySectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,6 @@ void BinarySectionTest::testResize()
}


void BinarySectionTest::testClearDefinedArea()
{
BinarySection section(Address(0x1000), 0x1000, "testSection");
section.clearDefinedArea();
QVERIFY(!section.anyDefinedValues());

section.addDefinedArea(Address(0x1000), Address(0x0800));
section.clearDefinedArea();
QVERIFY(!section.anyDefinedValues());
}


void BinarySectionTest::testAddDefinedArea()
{
BinarySection section(Address(0x1000), 0x1000, "testSection");
Expand All @@ -76,13 +64,9 @@ void BinarySectionTest::testAddDefinedArea()
void BinarySectionTest::testAttributes()
{
BinarySection section(Address(0x1000), 0x1000, "testSection");
QVariantMap varMap = section.getAttributesForRange(Address(0x1000), Address(0x2000));
QVERIFY(varMap.empty());

section.setAttributeForRange("ReadOnly", true, Address(0x1000), Address(0x1800));
varMap = section.getAttributesForRange(Address(0x1000), Address(0x2000));
QVERIFY(!varMap.empty());
QVERIFY(section.isAttributeInRange("ReadOnly", Address(0x1000), Address(0x2000)));
QVERIFY(!section.addressHasAttribute("ReadOnly", Address(0x1800)));
section.setAttributeForRange("ReadOnly", Address(0x1000), Address(0x1800));
QVERIFY(section.addressHasAttribute("ReadOnly", Address(0x1600)));
}

QTEST_GUILESS_MAIN(BinarySectionTest)
1 change: 0 additions & 1 deletion tests/unit-tests/boomerang/db/binary/BinarySectionTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ private slots:
void testIsAddressBss();
void testAnyDefinedValues();
void testResize();
void testClearDefinedArea();
void testAddDefinedArea();

void testAttributes();
Expand Down

0 comments on commit d4a33d4

Please sign in to comment.