Skip to content
Snippets Groups Projects
Commit 65a002d5 authored by whh8b's avatar whh8b
Browse files

Fleshing out functionality and adding testing code.

parent a680b72a
No related branches found
No related tags found
No related merge requests found
......@@ -37,21 +37,29 @@ class ZiprDollopManager_t {
public:
ZiprDollopManager_t() {}
void AddDollop(Dollop_t *dollop);
Zipr_SDK::Dollop_t *GetContainingDollop(libIRDB::Instruction_t *insn) {
try {
return m_insn_to_dollop.at(insn);
} catch (const std::out_of_range &oor) {
return NULL;
}
Zipr_SDK::Dollop_t *AddNewDollop(libIRDB::Instruction_t *start);
Zipr_SDK::Dollop_t *GetContainingDollop(libIRDB::Instruction_t *insn);
size_t Size() {
return m_dollops.size();
}
static Zipr_SDK::Dollop_t *CreateDollop(libIRDB::Instruction_t *start) {
return new Zipr_SDK::Dollop_t(start);
void AddDollopPatch(Zipr_SDK::DollopPatch_t *new_patch) {
m_patches_to_dollops[new_patch->Target()].push_back(new_patch);
}
std::list<DollopPatch_t*> PatchesToDollop(Dollop_t *target) {
/*
* FIXME: This will throw an exception if target is
* not already in the list. [] fixes that but allocates.
* Decide what to do.
*/
return m_patches_to_dollops.at(target);
}
void PrintDollopPatches(const std::ostream &);
private:
std::map<libIRDB::Instruction_t*,Dollop_t*> m_insn_to_dollop;
std::list<Dollop_t*> m_dollops;
std::list<DollopPatch_t*> m_patches;
std::map<Dollop_t*, std::list<DollopPatch_t*>> m_patches_to_dollops;
};
#endif
#include <zipr_all.h>
#include <iostream>
namespace Zipr_SDK {
using namespace libIRDB;
using namespace zipr;
Dollop_t::Dollop_t(Instruction_t *start)
{
Instruction_t *loop = NULL;
m_start = start;
m_size = CalculateWorstCaseSize();
if (start == NULL)
return;
loop = start;
do {
push_back(new DollopEntry_t(loop));
} while (NULL != (loop = loop->GetFallthrough()));
}
size_t Dollop_t::CalculateWorstCaseSize()
......@@ -38,6 +48,89 @@ namespace Zipr_SDK {
}
Dollop_t *Dollop_t::Split(libIRDB::Instruction_t *split_point) {
return new Dollop_t(NULL);
/*
* 1. Find the matching dollop entry.
*/
DollopEntry_t query(split_point);
std::list<DollopEntry_t *>::iterator de_split_point, de_it;
Dollop_t *new_dollop = NULL;
de_split_point = find_if(begin(),end(),
[&query](const DollopEntry_t *p) {
std::cout << "Checking "
<< std::hex << query.Instruction() << " ?= "
<< std::hex << p->Instruction() << "." << std::endl;
return query == *p;
});
/*
* No matching split point. Just return NULL.
*/
if (de_split_point == end())
return NULL;
new_dollop = new Dollop_t();
/*
* 2. Remove them from this one
*/
de_it = de_split_point;
while (de_it != end()) {
/*
* 3. Move them to a new one
*/
DollopEntry_t *to_remove = *de_it, *to_add = NULL;
std::list<DollopEntry_t*>::iterator to_remove_it = de_it;
de_it++;
new_dollop->push_back(to_add=new DollopEntry_t(to_remove->Instruction()));
erase(to_remove_it);
delete to_remove;
}
/*
* 4. Return the new one
*/
return new_dollop;
}
DollopEntry_t::DollopEntry_t(libIRDB::Instruction_t *insn) {
/*
* NB: This does not link if the insn has a target.
*/
m_instruction = insn;
m_target_dollop = NULL;
}
bool DollopEntry_t::operator==(const DollopEntry_t &comp) {
std::cout << "operator==s being invoked "
<< "(" << std::hex << m_instruction
<< ", " << std::hex << comp.m_instruction
<< ") "
<< "(" << std::hex << m_target_dollop
<< ", " << std::hex << comp.m_target_dollop
<< ") "
<< std::endl;
return comp.m_instruction == m_instruction &&
comp.m_target_dollop == m_target_dollop;
}
bool DollopEntry_t::operator!=(const DollopEntry_t &comp) {
return !operator==(comp);
}
Dollop_t *Dollop_t::CreateNewDollop(libIRDB::Instruction_t *start) {
return new Zipr_SDK::Dollop_t(start);
}
std::ostream &operator<<(std::ostream &out, const Dollop_t &d) {
std::list<DollopEntry_t*>::const_iterator it, it_end;
for (it = d.begin(), it_end = d.end();
it != it_end;
it++) {
out << std::hex << (*it)->Instruction() << ",";
}
return out;
}
std::ostream &operator<<(std::ostream &out, const DollopPatch_t &p) {
out << std::hex << &p << ":" << std::hex << p.Target();
return out;
}
}
#include <zipr_all.h>
#include <iostream>
using namespace zipr;
using namespace std;
using namespace Zipr_SDK;
using namespace libIRDB;
Dollop_t *ZiprDollopManager_t::AddNewDollop(Instruction_t *start) {
Dollop_t *new_dollop = Dollop_t::CreateNewDollop(start);
AddDollop(new_dollop);
return new_dollop;
}
void ZiprDollopManager_t::PrintDollopPatches(const ostream &out) {
std::list<DollopPatch_t*>::const_iterator patch_it, patch_it_end;
for (patch_it = m_patches.begin(), patch_it_end = m_patches.end();
patch_it != patch_it_end;
patch_it++) {
cout << *(*patch_it) << endl;
}
}
Dollop_t *ZiprDollopManager_t::GetContainingDollop(libIRDB::Instruction_t *insn) {
try {
return m_insn_to_dollop.at(insn);
} catch (const std::out_of_range &oor) {
return NULL;
}
return NULL;
}
void ZiprDollopManager_t::AddDollop(Dollop_t *dollop) {
return;
/*
* Populate the instruction-to-dollop map.
*/
list<DollopEntry_t*>::const_iterator it, it_end;
for (it = dollop->begin(), it_end = dollop->end();
it != it_end;
it++) {
m_insn_to_dollop[(*it)->Instruction()] = dollop;
}
/*
* Push the actual dollop onto the list of dollops.
*/
m_dollops.push_back(dollop);
}
......@@ -56,7 +56,7 @@ libpath='''
'''
myenv.Append(CCFLAGS=" -Wall ")
myenv.Append(CXXFLAGS=" -g -O0 ")
myenv.Append(CXXFLAGS=" -std=c++11 -g -O0 ")
myenv.Append(LINKFLAGS=" -Wl,-E ") # export all symbols
......
......@@ -23,6 +23,7 @@
using namespace zipr;
using namespace std;
using namespace Zipr_SDK;
#define INVOKE(a) \
bool __ ## a ## _result = false; \
......@@ -37,10 +38,189 @@ else \
printf(" fail\n"); \
}
int main(int argc, char *argv[])
{
bool TestGetContainingDollopNoFallthrough() {
ZiprDollopManager_t dollop_man;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
Dollop_t *dollop_a = NULL;
dollop_a = Dollop_t::CreateNewDollop(insn_a);
dollop_man.AddDollop(dollop_a);
return dollop_man.GetContainingDollop(insn_b) == NULL &&
dollop_man.GetContainingDollop(insn_a) == dollop_a;
}
bool TestGetContainingDollopFallthrough(void) {
ZiprDollopManager_t dollop_man;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
Dollop_t *dollop_a = NULL;
insn_a->SetFallthrough(insn_b);
dollop_a = Dollop_t::CreateNewDollop(insn_a);
dollop_man.AddDollop(dollop_a);
return dollop_man.GetContainingDollop(insn_b) == dollop_a &&
dollop_man.GetContainingDollop(insn_a) == dollop_a;
}
bool TestGetContainingDollop(void) {
ZiprDollopManager_t dollop_man;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
Dollop_t *dollop_a = Dollop_t::CreateNewDollop(insn_a);
Dollop_t *dollop_b = Dollop_t::CreateNewDollop(insn_b);
dollop_man.AddDollop(dollop_a);
dollop_man.AddDollop(dollop_b);
return dollop_man.GetContainingDollop(insn_a) == dollop_a &&
dollop_man.GetContainingDollop(insn_b) == dollop_b;
}
bool TestAddDollopEntry(void) {
ZiprDollopManager_t dollop_man;
libIRDB::Instruction_t *insn = new libIRDB::Instruction_t();
dollop_man.AddDollop(ZiprDollopManager_t::CreateDollop(insn));
dollop_man.AddDollop(Dollop_t::CreateNewDollop(insn));
return 1 == dollop_man.Size();
}
bool TestDollopPatch(void) {
Dollop_t *a = NULL;
DollopPatch_t patch;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
a = Dollop_t::CreateNewDollop(insn_a);
patch.Target(a);
return patch.Target() == a;
}
bool TestDollopPatchDollopManager(void) {
ZiprDollopManager_t dollop_man;
DollopPatch_t patch_a, patch_b;
Dollop_t *dollop_a, *dollop_b;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
dollop_a = Dollop_t::CreateNewDollop(insn_a);
dollop_b = Dollop_t::CreateNewDollop(insn_b);
patch_a.Target(dollop_b);
patch_b.Target(dollop_a);
dollop_man.AddDollopPatch(&patch_a);
dollop_man.AddDollopPatch(&patch_b);
dollop_man.PrintDollopPatches(cout);
return true;
}
bool TestDollopPatchMapDollopManager(void) {
bool success = true;
ZiprDollopManager_t dollop_man;
DollopPatch_t patch_a, patch_aa, patch_c;
Dollop_t *dollop_a, *dollop_c;
std::list<DollopPatch_t *>::const_iterator patches_it, patches_it_end;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_c = new libIRDB::Instruction_t();
dollop_a = Dollop_t::CreateNewDollop(insn_a);
dollop_c = Dollop_t::CreateNewDollop(insn_c);
patch_a.Target(dollop_a);
patch_aa.Target(dollop_a);
patch_c.Target(dollop_c);
dollop_man.AddDollop(dollop_a);
dollop_man.AddDollop(dollop_c);
dollop_man.AddDollopPatch(&patch_a);
dollop_man.AddDollopPatch(&patch_aa);
dollop_man.AddDollopPatch(&patch_c);
cout << "&dollop_a: " << std::hex << dollop_a << endl;
cout << "&dollop_c: " << std::hex << dollop_c << endl;
std::list<DollopPatch_t *> patches = dollop_man.PatchesToDollop(dollop_a);
for (patches_it = patches.begin(), patches_it_end = patches.end();
patches_it != patches.end();
patches_it++) {
success &= ((*patches_it)->Target()) == dollop_a;
cout << *(*patches_it) << endl;
}
patches = dollop_man.PatchesToDollop(dollop_c);
for (patches_it = patches.begin(), patches_it_end = patches.end();
patches_it != patches.end();
patches_it++) {
success &= ((*patches_it)->Target()) == dollop_c;
cout << *(*patches_it) << endl;
}
return success;
}
bool TestDollopSplit(void) {
Dollop_t *a, *b;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_c = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_d = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_e = new libIRDB::Instruction_t();
insn_a->SetFallthrough(insn_b);
insn_b->SetFallthrough(insn_c);
insn_c->SetFallthrough(insn_d);
insn_d->SetFallthrough(insn_e);
a = Dollop_t::CreateNewDollop(insn_a);
cout << "Dollop A: " << endl;
cout << *a << endl;
b = a->Split(insn_b);
cout << "Dollop A: " << endl;
cout << *a << endl;
cout << "Dollop B: " << endl;
cout << *b << endl;
return a->GetDollopEntryCount() == 1 && b->GetDollopEntryCount() == 4;
}
bool TestDollopEntryEquals(void) {
DollopEntry_t *a, *b, *c, *d;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
a = new DollopEntry_t(insn_a);
b = new DollopEntry_t(insn_b);
c = new DollopEntry_t(insn_a);
d = new DollopEntry_t(insn_a);
d->SetTargetDollop((Dollop_t*)0x5000);
return *a != *b &&
*b != *c &&
*a == *a &&
*b == *b &&
*a == *c &&
*a != *d;
}
int main(int argc, char *argv[])
{
INVOKE(TestAddDollopEntry);
INVOKE(TestDollopEntryEquals);
INVOKE(TestDollopSplit);
INVOKE(TestGetContainingDollop);
INVOKE(TestGetContainingDollopFallthrough);
INVOKE(TestGetContainingDollopNoFallthrough);
INVOKE(TestDollopPatch);
INVOKE(TestDollopPatchDollopManager);
INVOKE(TestDollopPatchMapDollopManager);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment