X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=blobdiff_plain;f=src%2Fcore%2FInformationManager.cxx;h=604425e617499fa5155e3db8d84f40af49448824;hp=5a70dee6a54041951a4461723a85f40714caf518;hb=HEAD;hpb=9b99fc5856d5fe88bb1d2aad4d2ee7cd86b5be57 diff --git a/src/core/InformationManager.cxx b/src/core/InformationManager.cxx index 5a70dee..604425e 100644 --- a/src/core/InformationManager.cxx +++ b/src/core/InformationManager.cxx @@ -4,8 +4,9 @@ #include "core/Function.hxx" #include "core/BasicBlock.hxx" #include "core/Comment.hxx" +#include "core/events/ChangeCommentEvent.hxx" -#include "gui/qt.hxx" +#include "qt.hxx" #include #include @@ -17,6 +18,7 @@ InformationManager::InformationManager() : logger(log4cxx::Logger::getLogger("core.InformationManager")) { current_information_manager = this; + qRegisterMetaType("NewFunctionEvent"); QPluginLoader* loader = new QPluginLoader("libguilePlugin", NULL); if (!loader->load()) @@ -26,6 +28,7 @@ InformationManager::InformationManager() } InformationManager::~InformationManager() { + disassemblerThread.quit(); for (auto b : blocks) delete b.second; @@ -34,13 +37,23 @@ InformationManager::~InformationManager() { for (auto i : plugins) delete i; + disassemblerThread.wait(); } void InformationManager::reset(const std::string& filename) { this->filename = filename; disassembler.reset(createLLVMDisassembler(filename, this)); - if (disassembler.get() != NULL) + if (disassembler.get() != NULL) { + emit resetEvent(); +#ifndef CONFIG_TEST + disassembler.get()->moveToThread(&disassemblerThread); + connect(&disassemblerThread, &QThread::started, + disassembler.get(), &Disassembler::start); + disassemblerThread.start(); +#else disassembler.get()->start(); +#endif + } } void InformationManager::load(const std::string& filename) { @@ -48,7 +61,10 @@ void InformationManager::load(const std::string& filename) { QuaZipFile file(&zip); QuaZipFileInfo info; - zip.open(QuaZip::mdUnzip); + if (!zip.open(QuaZip::mdUnzip)) { + LOG4CXX_ERROR(logger, "Failed to open archive " << filename); + return; + } tmpfile.reset(new QTemporaryFile()); { @@ -71,10 +87,21 @@ void InformationManager::load(const std::string& filename) { file.open(QIODevice::ReadOnly); if(info.name != "binary") { - QXmlStreamReader reader(&file); - assert(QXmlStreamReader::StartDocument == reader.readNext()); - assert(QXmlStreamReader::StartElement == reader.readNext()); - Function * fun = Function::deserialize(reader, this); + if (info.name.startsWith("comment:")) { + QXmlStreamReader reader(&file); + auto starttoken = reader.readNext(); + auto elementtoken = reader.readNext(); + assert(QXmlStreamReader::StartDocument == starttoken); + assert(QXmlStreamReader::StartElement == elementtoken); + Comment::deserialize(reader, this); + } else { + QXmlStreamReader reader(&file); + auto starttoken = reader.readNext(); + auto elementtoken = reader.readNext(); + assert(QXmlStreamReader::StartDocument == starttoken); + assert(QXmlStreamReader::StartElement == elementtoken); + Function::deserialize(reader, this); + } } file.close(); } @@ -115,14 +142,27 @@ void InformationManager::save(const std::string& filename) { stream.writeEndDocument(); outZipFile.close(); } + for (auto commentpair : comments) { + Comment* comment = commentpair.second; + if (!comment->isLocal()) { + QuaZipNewInfo zipinfo(QString("comment:%1").arg(comment->getAddress(), 0, 16)); + zipinfo.setPermissions(static_cast(0x6444)); + outZipFile.open(QIODevice::WriteOnly, zipinfo); + QXmlStreamWriter stream(&outZipFile); + stream.setAutoFormatting(true); + stream.setAutoFormattingIndent(-1); + stream.writeStartDocument(); + + comment->serialize(stream); + + stream.writeEndDocument(); + outZipFile.close(); + } + } zip.close(); } -void InformationManager::signal_new_function(Function* fun) { -} - - /* ******************************* * Accessors for the Functions map @@ -163,6 +203,22 @@ std::map::const_iterator InformationManager::endBasicBloc return blocks.end(); } +/* ********************************* + * Accessors for the Comments map + */ +std::pair< + std::multimap::const_iterator, + std::multimap::const_iterator> +InformationManager::getComments(uint64_t address) { + return comments.equal_range(address); +} + +std::multimap::const_iterator InformationManager::beginComments() { + return comments.begin(); +} +std::multimap::const_iterator InformationManager::endComments() { + return comments.end(); +} /* ********************************* * Accessors for the Interpreter map @@ -189,7 +245,13 @@ std::map::const_iterator InformationManager::endInter */ Function* InformationManager::newFunction(uint64_t address) { - Function* fun = new Function(address, this); + Function* fun = new Function(address, false, this); + functions.insert(std::make_pair(address, fun)); + return fun; +} + +Function* InformationManager::newDynamicFunction(uint64_t address) { + Function* fun = new Function(address, true, this); functions.insert(std::make_pair(address, fun)); return fun; } @@ -201,11 +263,15 @@ BasicBlock* InformationManager::newBasicBlock(uint64_t address) { } Comment* InformationManager::newGlobalComment(uint64_t address) { - return NULL; + Comment* comment = new Comment(address, this); + comments.insert(std::make_pair(address, comment)); + return comment; } Comment* InformationManager::newLocalComment(uint64_t address, Function* f) { - return NULL; + Comment* comment = new Comment(address, f, this); + comments.insert(std::make_pair(address, comment)); + return comment; } void InformationManager::finishFunction(Function* fun) { @@ -214,13 +280,17 @@ void InformationManager::finishFunction(Function* fun) { BasicBlock* bl = b.second; blocks.insert(std::make_pair(bl->getStartAddress(), bl)); } - new_function_signal(fun); + NewFunctionEvent event(fun->getStartAddress(), fun); + emit newFunctionEvent(event); } -void InformationManager::finishBasicBlock(BasicBlock* b) { +void InformationManager::finishBasicBlock(BasicBlock*) { } -void InformationManager::finnishComment(Comment* c) { +void InformationManager::finishComment(Comment* c) { + LOG4CXX_DEBUG(logger, "Finishing comment " << c->getAddress()); + ChangeCommentEvent event(c->getAddress(), c->getLocation(), c); + emit changeCommentEvent(&event); } void InformationManager::deleteFunction(Function* f) { @@ -234,5 +304,12 @@ void InformationManager::deleteBasicBlock(BasicBlock* b) { } void InformationManager::deleteComment(Comment* c) { + auto range = comments.equal_range(c->getAddress()); + for (auto it = range.first; it != range.second; ++it) { + if (it->second == c) { + comments.erase(it); + break; + } + } delete c; }