#include "disassembler/llvm/LLVMDisassembler.hxx"
-#include "disassembler/llvm/LLVMBasicBlock.hxx"
-#include "disassembler/llvm/LLVMFunction.hxx"
+#include "core/InformationManager.hxx"
+#include "core/Function.hxx"
+#include "core/BasicBlock.hxx"
#include <stack>
#include <algorithm>
+#include <cassert>
using namespace llvm;
using namespace llvm::object;
}
template <typename ELFT>
-LLVMDisassembler<ELFT>::~LLVMDisassembler() {
- std::for_each(functions.begin(), functions.end(),
- [](std::pair<uint64_t,LLVMFunction*> it) {
- delete it.second;
- });
- std::for_each(blocks.begin(), blocks.end(),
- [](std::pair<uint64_t, LLVMBasicBlock*> it) {
- delete it.second;
- });
-}
+LLVMDisassembler<ELFT>::~LLVMDisassembler() {}
template <typename ELFT>
Function* LLVMDisassembler<ELFT>::disassembleFunctionAt(uint64_t address, const std::string& name) {
+ Function * function;
SectionRef text_section = sections[".text"];
uint64_t base_address, size;
text_section.getAddress(base_address);
return NULL;
}
- if (functions.find(address) != functions.end()) {
- return functions[address];
- }
+ if (NULL == (function = manager->getFunction(address))) {
- LLVMFunction * function;
- if (name == "") {
- std::stringstream s;
- s << "<Unnamed 0x" << std::hex << address << ">";
- function = new LLVMFunction(s.str(), address);
- } else {
- function = new LLVMFunction(name, address);
+ if (name == "") {
+ std::stringstream s;
+ s << "<Unnamed 0x" << std::hex << address << ">";
+ function = manager->newFunction(address);
+ function->setName(s.str());
+ } else {
+ function = manager->newFunction(address);
+ function->setName(name);
+ }
+ disassembleFunction(function);
+ manager->finishFunction(function);
}
- functions.insert(std::make_pair(address, function));
-
- disassembleFunction(function);
return function;
}
template <typename ELFT>
-void LLVMDisassembler<ELFT>::disassembleFunction(LLVMFunction* function) {
- std::stack<LLVMBasicBlock*> remaining_blocks;
+void LLVMDisassembler<ELFT>::disassembleFunction(Function* function) {
+ std::stack<BasicBlock*> remaining_blocks;
+ /* TODO:
+ * Do all blocks get added properly? We should take care to remove
+ * the other ones at the end of the function!
+ */
+ std::map<uint64_t, BasicBlock*> new_blocks;
SectionRef text_section = sections[".text"];
StringRef bytes;
text_section.getContents(bytes);
LOG4CXX_DEBUG(logger, "Handling function " << function->getName());
- LLVMBasicBlock * block = new LLVMBasicBlock(function->getStartAddress(), this);
+ BasicBlock * block = manager->newBasicBlock(function->getStartAddress());
remaining_blocks.push(block);
- blocks.insert(std::make_pair(block->getStartAddress(), block));
+ new_blocks.insert(std::make_pair(block->getStartAddress(), block));
function->addBasicBlock(block);
while (remaining_blocks.size()) {
- LLVMBasicBlock * current_block = remaining_blocks.top();
+ BasicBlock * current_block = remaining_blocks.top();
remaining_blocks.pop();
- LOG4CXX_DEBUG(logger, "Handling Block starting at " << std::hex << current_block->getStartAddress());
+ LOG4CXX_DEBUG(logger, "Handling Block starting at " << std::hex
+ << current_block->getStartAddress());
uint64_t inst_size;
uint64_t base_address;
jmptarget += base_address;
if (!MIA->isIndirectBranch(inst)) {
if (MIA->isCall(inst)) {
- if (functions.find(jmptarget) == functions.end()) {
+ if (NULL == manager->getFunction(jmptarget))
disassembleFunctionAt(jmptarget);
- }
} else {
current_block->setNextBlock(0, jmptarget);
- if (blocks.find(jmptarget) == blocks.end()) {
- LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this);
- blocks.insert(std::make_pair(block->getStartAddress(), block));
+ if (new_blocks.find(jmptarget) == new_blocks.end()) {
+ BasicBlock * block = manager->newBasicBlock(jmptarget);
+ assert(block);
+ new_blocks.insert(std::make_pair(block->getStartAddress(), block));
function->addBasicBlock(block);
remaining_blocks.push(block);
} else {
- LOG4CXX_DEBUG(logger, "Reusing Block starting at " << std::hex << current_block->getStartAddress());
- function->addBasicBlock(blocks.find(jmptarget)->second);
+ LOG4CXX_DEBUG(logger, "Reusing Block starting at " << std::hex
+ << current_block->getStartAddress());
+ function->addBasicBlock(new_blocks.find(jmptarget)->second);
}
if (MIA->isConditionalBranch(inst)) {
jmptarget = base_address + current_address + inst_size;
current_block->setNextBlock(1, jmptarget);
- if (blocks.find(jmptarget) == blocks.end()) {
- LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this);
- blocks.insert(std::make_pair(block->getStartAddress(), block));
+ if (new_blocks.find(jmptarget) == new_blocks.end()) {
+ BasicBlock * block = manager->newBasicBlock(jmptarget);
+ assert(block);
+ new_blocks.insert(std::make_pair(block->getStartAddress(), block));
function->addBasicBlock(block);
remaining_blocks.push(block);
} else {
- LOG4CXX_DEBUG(logger, "Reusing Block starting at " << std::hex << current_block->getStartAddress());
- function->addBasicBlock(blocks.find(jmptarget)->second);
+ LOG4CXX_DEBUG(logger, "Reusing Block starting at " << std::hex
+ << current_block->getStartAddress());
+ function->addBasicBlock(new_blocks.find(jmptarget)->second);
}
}
}
template <typename ELFT>
void LLVMDisassembler<ELFT>::disassemble() {
SectionRef text_section = sections[".text"];
- std::vector<LLVMFunction*> remaining_functions;
+ std::vector<Function*> remaining_functions;
// Assume all function symbols actually start a real function
for (auto x = symbols.begin(); x != symbols.end(); ++x) {
continue;
if (!x->second.getAddress(result)) {
- LLVMFunction * fun = new LLVMFunction(x->first, result);
+ Function * fun = manager->newFunction(result);
+ fun->setName(x->first);
remaining_functions.push_back(fun);
- functions.insert(std::make_pair(result, fun));
LOG4CXX_DEBUG(logger, "Disasembling " << x->first);
}
}
- for (LLVMFunction* function : remaining_functions) {
+ for (Function* function : remaining_functions) {
disassembleFunction(function);
+ manager->finishFunction(function);
}
if (binary->isELF()) {
disassembleFunctionAt(_entryAddress, s.str());
}
- if (functions.empty()) {
+ if (!manager->hasFunctions()) {
uint64_t text_entry;
text_section.getAddress(text_entry);
LOG4CXX_INFO(logger, "No Symbols found, starting at the beginning of the text segment");
}
template <typename ELFT>
-void LLVMDisassembler<ELFT>::splitBlocks(LLVMFunction* function) {
+void LLVMDisassembler<ELFT>::splitBlocks(Function* function) {
SectionRef text_section = sections[".text"];
StringRef bytes;
text_section.getContents(bytes);
if(llvm::MCDisassembler::Success ==
DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) {
// See if some other block starts here
- auto other = blocks.find(current_address + inst_size + base_address);
+ BasicBlock* other = manager->getBasicBlock(current_address
+ + inst_size
+ + base_address);
// Special case, other block starts here but we are at the end anyway
- if (other != blocks.end()) {
+ if (other != NULL) {
uint64_t endaddress = current_address + inst_size + base_address;
if (endaddress != current_block->getEndAddress()) {
LOG4CXX_DEBUG(logger, "Shortening block starting at "
<< std::hex
<< current_block->getStartAddress()
<< " now ending at "
- << other->first);
- function->addBasicBlock(other->second);
+ << other->getStartAddress());
+ function->addBasicBlock(other);
current_block->setEndAddress(endaddress);
- current_block->setNextBlock(0, other->first);
+ current_block->setNextBlock(0, other->getStartAddress());
current_block->setNextBlock(1, 0);
}
}
}
-template <typename ELFT>
-void LLVMDisassembler<ELFT>::forEachFunction(std::function<void (uint64_t, Function*)> callback) {
- std::for_each(functions.begin(), functions.end(),
- [&](std::pair<uint64_t, LLVMFunction*> x) {
- callback(x.first, x.second);
- });
-}
+// template <typename ELFT>
+// void LLVMDisassembler<ELFT>::forEachFunction(std::function<void (uint64_t, Function*)> callback) {
+// // std::for_each(functions.begin(), functions.end(),
+// // [&](std::pair<uint64_t, Function*> x) {
+// // callback(x.first, x.second);
+// // });
+// }
template <typename ELFT>
void LLVMDisassembler<ELFT>::printEachInstruction(uint64_t start, uint64_t end,