]> git.siccegge.de Git - frida/frida.git/commitdiff
work
authorChristoph Egger <christoph@christoph-egger.org>
Thu, 14 Nov 2013 14:57:09 +0000 (15:57 +0100)
committerChristoph Egger <christoph@christoph-egger.org>
Thu, 14 Nov 2013 14:57:09 +0000 (15:57 +0100)
Makefile
src/Binary.cxx
src/Binary.hxx
src/gui/Mainwindow.cxx
src/gui/Mainwindow.h++

index 549ea3ca81f34dc9fbdb0fc6719db15a3596f4b5..a32233bb069a8503ac1c5da0550a0ba68c580023 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,9 +3,9 @@
 CXX = clang++
 LD  = clang++
 
-CXXFLAGS += $(shell llvm-config-3.4 --cflags) $(shell pkg-config QtGui --cflags) -Isrc
-LDFLAGS  ?= $(shell llvm-config-3.4 --ldflags)
-LIBS     ?= $(shell llvm-config-3.4 --libs) $(shell pkg-config QtGui --libs)
+CXXFLAGS += $(shell llvm-config-3.4 --cflags) $(shell pkg-config QtGui --cflags) -Isrc -std=c++0x
+LDFLAGS  += $(shell llvm-config-3.4 --ldflags)
+LIBS     += $(shell llvm-config-3.4 --libs) $(shell pkg-config QtGui --libs)
 
 objects = $(patsubst %.cxx,%.o,$(shell find src -name \*.cxx)) $(patsubst %.h++,%_moc.o,$(shell find src -name \*.h++))
 
index d57db4e720f3bd6b4d5b5329341a2bdc091b66cc..83909a0915a1767f8da82b6c91dd5d2b57f98646 100644 (file)
 #include <string>
 #include <algorithm>
 
+#include "llvm/Support/raw_ostream.h"
+
 using namespace llvm;
 using namespace llvm::object;
 
-static bool error(error_code ec) {
-    if (!ec) return false;
+namespace {
+    bool error(error_code ec) {
+        if (!ec) return false;
 
-    outs() << "error reading file: " << ec.message() << ".\n";
-    outs().flush();
-    return true;
-}
+        outs() << "error reading file: " << ec.message() << ".\n";
+        outs().flush();
+        return true;
+    }
 
-static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
-    uint64_t a_addr, b_addr;
-    if (error(a.getOffset(a_addr))) return false;
-    if (error(b.getOffset(b_addr))) return false;
-    return a_addr < b_addr;
-}
+    bool RelocAddressLess(RelocationRef a, RelocationRef b) {
+        uint64_t a_addr, b_addr;
+        if (error(a.getOffset(a_addr))) return false;
+        if (error(b.getOffset(b_addr))) return false;
+        return a_addr < b_addr;
+    }
 
-static void DumpBytes(StringRef bytes) {
-    static const char hex_rep[] = "0123456789abcdef";
-    // FIXME: The real way to do this is to figure out the longest instruction
-    //        and align to that size before printing. I'll fix this when I get
-    //        around to outputting relocations.
-    // 15 is the longest x86 instruction
-    // 3 is for the hex rep of a byte + a space.
-    // 1 is for the null terminator.
-    enum { OutputSize = (15 * 3) + 1 };
-    char output[OutputSize];
-
-    assert(bytes.size() <= 15
-           && "DumpBytes only supports instructions of up to 15 bytes");
-    memset(output, ' ', sizeof(output));
-    unsigned index = 0;
-    for (StringRef::iterator i = bytes.begin(),
-             e = bytes.end(); i != e; ++i) {
-        output[index] = hex_rep[(*i & 0xF0) >> 4];
-        output[index + 1] = hex_rep[*i & 0xF];
-        index += 3;
+    void DumpBytes(StringRef bytes) {
+        static const char hex_rep[] = "0123456789abcdef";
+        // FIXME: The real way to do this is to figure out the longest instruction
+        //        and align to that size before printing. I'll fix this when I get
+        //        around to outputting relocations.
+        // 15 is the longest x86 instruction
+        // 3 is for the hex rep of a byte + a space.
+        // 1 is for the null terminator.
+        enum { OutputSize = (15 * 3) + 1 };
+        char output[OutputSize];
+
+        assert(bytes.size() <= 15
+               && "DumpBytes only supports instructions of up to 15 bytes");
+        memset(output, ' ', sizeof(output));
+        unsigned index = 0;
+        for (StringRef::iterator i = bytes.begin(),
+                 e = bytes.end(); i != e; ++i) {
+            output[index] = hex_rep[(*i & 0xF0) >> 4];
+            output[index + 1] = hex_rep[*i & 0xF];
+            index += 3;
+        }
+
+        output[sizeof(output) - 1] = 0;
+        outs() << output;
     }
 
-    output[sizeof(output) - 1] = 0;
-    outs() << output;
-}
+    std::map<std::string, SectionRef> readSections(const ObjectFile& o) {
+        error_code ec;
+        std::map<std::string, SectionRef> result;
+        section_iterator i(o.begin_sections()), e(o.end_sections());
+        for (; i != e; i.increment(ec)) {
+            StringRef name;
+            if (error(i->getName(name))) break;
 
-::Binary::Binary(const std::string& filename)
-    : triple("unkown-unknown-unknown")
-{
-    std::string error;
+            result.insert(make_pair(name.str(), *i));
+        }
+        return result;
+    }
 
-    createBinary(filename, binary);
-    if (Archive *a = dyn_cast<Archive>(binary.get())) {
-        std::cerr << "Got an archive!" << std::endl;
-        return;
+    std::map<std::string, SymbolRef> readSymbols(const ObjectFile& o) {
+        error_code ec;
+        std::map<std::string, SymbolRef> result;
+        symbol_iterator si(o.begin_symbols()), se(o.end_symbols());
+        for (; si != se; si.increment(ec)) {
+            StringRef name;
+            if (error(si->getName(name))) break;
+
+            result.insert(make_pair(name.str(), *si));
+        }
+        return result;
     }
+}
 
-    o = dyn_cast<ObjectFile>(binary.get());
+namespace qtlldb {
 
-    triple.setArch(Triple::ArchType(o->getArch()));
-    std::string tripleName(triple.getTriple());
+    Binary::Binary(const std::string& filename)
+        : triple("unkown-unknown-unknown")
+    {
+        std::string error;
 
-    target = TargetRegistry::lookupTarget("", triple, error);
-    if (!target) {
-        std::cerr << error;
-        return;
-    }
+        createBinary(filename, binary);
+        if (Archive *a = dyn_cast<Archive>(binary.get())) {
+            std::cerr << "Got an archive!" << std::endl;
+            return;
+        }
 
-    MRI.reset(target->createMCRegInfo(tripleName));
-    if (!MRI) {
-        std::cerr << "error: no register info for target " << tripleName << "\n";
-        return;
-    }
+        o = dyn_cast<ObjectFile>(binary.get());
 
-    // Set up disassembler.
-    AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName));
-    if (!AsmInfo) {
-        std::cerr << "error: no assembly info for target " << tripleName << "\n";
-        return;
-    }
+        triple.setArch(Triple::ArchType(o->getArch()));
+        std::string tripleName(triple.getTriple());
 
-    STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
-    if (!STI) {
-        errs() << "error: no subtarget info for target " << tripleName << "\n";
-        return;
-    }
+        outs() << tripleName << "\n";
 
-    MII.reset(target->createMCInstrInfo());
-    if (!MII) {
-        std::cerr << "error: no instruction info for target " << tripleName << "\n";
-        return;
-    }
+        target = TargetRegistry::lookupTarget("", triple, error);
+        if (!target) {
+            std::cerr << error;
+            return;
+        }
 
-    DisAsm.reset(target->createMCDisassembler(*STI));
-    if (!DisAsm) {
-        std::cerr << "error: no disassembler for target " << tripleName << "\n";
-        return;
-    }
+        outs() << target->getName() << "\n";
 
-    MOFI.reset(new MCObjectFileInfo);
-    Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get()));
-    RelInfo.reset(
-        target->createMCRelocationInfo(tripleName, *Ctx.get()));
-    if (RelInfo) {
-        Symzer.reset(
-            MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(), RelInfo, o));
-        if (Symzer)
-            DisAsm->setSymbolizer(Symzer);
-    }
+        MRI.reset(target->createMCRegInfo(tripleName));
+        if (!MRI) {
+            std::cerr << "error: no register info for target " << tripleName << "\n";
+            return;
+        }
 
-    MIA.reset(target->createMCInstrAnalysis(MII.get()));
+        // Set up disassembler.
+        AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName));
+        if (!AsmInfo) {
+            std::cerr << "error: no assembly info for target " << tripleName << "\n";
+            return;
+        }
 
-    int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
-    IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
-    if (!IP) {
-        std::cerr << "error: no instruction printer for target " << tripleName
-                  << '\n';
-        return;
-    }
+        STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
+        if (!STI) {
+            errs() << "error: no subtarget info for target " << tripleName << "\n";
+            return;
+        }
 
-    OwningPtr<MCObjectDisassembler> OD(
-        new MCObjectDisassembler(*o, *DisAsm, *MIA));
-    Mod.reset(OD->buildModule(/* withCFG */ true));
-}
+        MII.reset(target->createMCInstrInfo());
+        if (!MII) {
+            std::cerr << "error: no instruction info for target " << tripleName << "\n";
+            return;
+        }
 
-void ::Binary::disassemble() {
-    for (MCModule::const_atom_iterator AI = Mod->atom_begin(),
-             AE = Mod->atom_end();
-         AI != AE; ++AI) {
+        DisAsm.reset(target->createMCDisassembler(*STI));
+        if (!DisAsm) {
+            std::cerr << "error: no disassembler for target " << tripleName << "\n";
+            return;
+        }
 
-        if ((*AI)->getKind() != llvm::MCAtom::TextAtom)
-            continue;
+        MOFI.reset(new MCObjectFileInfo);
+        Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get()));
+        RelInfo.reset(
+            target->createMCRelocationInfo(tripleName, *Ctx.get()));
+        if (RelInfo) {
+            Symzer.reset(
+                MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(), RelInfo, o));
+            if (Symzer)
+                DisAsm->setSymbolizer(Symzer);
+        }
 
-        outs() << "\n\nAtom " << (*AI)->getName() << ": \n";
-        if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(*AI)) {
-            for (MCTextAtom::const_iterator II = TA->begin(), IE = TA->end();
-                 II != IE;
-                 ++II) {
-//                II->Inst.dump();
-                IP->printInst(&II->Inst, outs(), "");
-                outs() << "\n";
-            }
+        MIA.reset(target->createMCInstrAnalysis(MII.get()));
+
+        int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
+        IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
+        if (!IP) {
+            std::cerr << "error: no instruction printer for target " << tripleName
+                      << '\n';
+            return;
         }
+
+        OwningPtr<MCObjectDisassembler> OD(
+            new MCObjectDisassembler(*o, *DisAsm, *MIA));
+        Mod.reset(OD->buildModule(/* withCFG */ false));
+
+        symbols = readSymbols(*o);
+        sections = readSections(*o);
+
+        // for_each(sections.begin(), sections.end(), [](const std::pair<std::string, SectionRef>& i){
+        //         std::cout << "Section: " << i.first << std::endl;
+        //     });
     }
 
-    outs() << "binary " << triple.getArchName() << "\n";
-}
 
-void ::Binary::disassemble_functions() {
-    error_code ec;
-    for (section_iterator i = o->begin_sections(),
-             e = o->end_sections();
-         i != e; i.increment(ec)) {
-        if (error(ec)) break;
-        bool text;
-        if (error(i->isText(text))) break;
-        if (!text) continue;
-
-        uint64_t SectionAddr;
-        if (error(i->getAddress(SectionAddr))) break;
-
-        // Make a list of all the symbols in this section.
-        std::vector<std::pair<uint64_t, StringRef> > Symbols;
-        for (symbol_iterator si = o->begin_symbols(),
-                 se = o->end_symbols();
-             si != se; si.increment(ec)) {
-            bool contains;
-            if (!error(i->containsSymbol(*si, contains)) && contains) {
-                uint64_t Address;
-                if (error(si->getAddress(Address))) break;
-                if (Address == UnknownAddressOrSize) continue;
-                Address -= SectionAddr;
-
-                StringRef Name;
-                if (error(si->getName(Name))) break;
-
-                outs() << "\nXXX " << Name << "\n";
-
-                Symbols.push_back(std::make_pair(Address, Name));
-            }
-        }
 
-        // Sort the symbols by address, just in case they didn't come in that way.
-        array_pod_sort(Symbols.begin(), Symbols.end());
-
-        // Make a list of all the relocations for this section.
-        std::vector<RelocationRef> Rels;
-        // if (InlineRelocs) {
-        //     for (relocation_iterator ri = i->begin_relocations(),
-        //              re = i->end_relocations();
-        //          ri != re; ri.increment(ec)) {
-        //         if (error(ec)) break;
-        //         Rels.push_back(*ri);
-        //     }
-        // }
-
-        // Sort relocations by address.
-        std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
-
-        StringRef SegmentName = "";
-        // if (const MachOObjectFile *MachO =
-        //     dyn_cast<const MachOObjectFile>(o)) {
-        //     DataRefImpl DR = i->getRawDataRefImpl();
-        //     SegmentName = MachO->getSectionFinalSegmentName(DR);
-        // }
-        StringRef name;
-        if (error(i->getName(name))) break;
-        outs() << "Disassembly of section ";
-        if (!SegmentName.empty())
-            outs() << SegmentName << ",";
-        outs() << name << ':';
-
-        // If the section has no symbols just insert a dummy one and disassemble
-        // the whole section.
-        if (Symbols.empty())
-            Symbols.push_back(std::make_pair(0, name));
-
-
-        StringRef Bytes;
-        if (error(i->getContents(Bytes))) break;
-        StringRefMemoryObject memoryObject(Bytes);
-        uint64_t Size;
-        uint64_t Index;
-        uint64_t SectSize;
-        if (error(i->getSize(SectSize))) break;
-
-        std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
-        std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
-        // Disassemble symbol by symbol.
-        for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
-            uint64_t Start = Symbols[si].first;
-            uint64_t End;
-            // The end is either the size of the section or the beginning of the next
-            // symbol.
-            if (si == se - 1)
-                End = SectSize;
-            // Make sure this symbol takes up space.
-            else if (Symbols[si + 1].first != Start)
-                End = Symbols[si + 1].first - 1;
-            else
-                // This symbol has the same address as the next symbol. Skip it.
-                continue;
+    std::vector<std::string> Binary::getSymbols() {
+        error_code ec;
+        SectionRef r = sections[".text"];
+        std::vector<std::string> result;
+        for_each(symbols.begin(), symbols.end(), [&](const std::pair<std::string, SymbolRef>& i) {
+                     bool contains;
+                     if (!error(r.containsSymbol(i.second, contains)) && contains)
+                         result.push_back(i.first);
+                 });
+        return result;
+    }
 
-            outs() << '\n' << Symbols[si].second << ":\n";
+    void Binary::for_each_instruction(const std::string& function,
+                                      std::function<void (long, std::string, std::string)> callback) {
+        StringRef bytes;
+        SymbolRef ref = symbols[function];
+        section_iterator sec(o->begin_sections());
+        uint64_t base_address, address, ssize, size(0), index, end;
+
+        // outs() << "Start for_each_instruction " << function << "\n";
+
+        if (error(ref.getSection(sec))) return;
+        if (error(ref.getAddress(address))) return;
+        if (address == UnknownAddressOrSize) return;
+        if (error(ref.getSize(ssize))) return;
+        if (error(sec->getAddress(base_address))) return;
+        if (error(sec->getContents(bytes))) return;
+
+        // outs() << "Middle for_each_instruction " << function << " Size: " << ssize << "\n";
+
+        StringRefMemoryObject memoryObject(bytes);
+        
+        for (end = address + ssize - base_address, index = address - base_address; index < end; index += size) {
+            MCInst Inst;
+            
+            if (DisAsm->getInstruction(Inst, size, memoryObject, index,
+                                       nulls(), nulls())) {
+                std::string buf;
+                llvm::raw_string_ostream s(buf);
+                IP->printInst(&Inst, s, "");
+
+                if (index + size < bytes.str().length())
+                    callback(base_address + index, bytes.str().substr(index, size), s.str());
+
+            } else {
+                errs() << "warning: invalid instruction encoding\n";
+                if (size == 0)
+                    size = 1; // skip illegible bytes
+            }
+        }
+        // outs() << "End for_each_instruction\n";
 
-#ifndef NDEBUG
-            raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
-#else
-            raw_ostream &DebugOut = nulls();
-#endif
+    }
 
-            for (Index = Start; Index < End; Index += Size) {
-                MCInst Inst;
+    void Binary::disassemble() {
+        for (MCModule::const_atom_iterator AI = Mod->atom_begin(),
+                 AE = Mod->atom_end();
+             AI != AE; ++AI) {
 
-                if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
-                                           DebugOut, nulls())) {
-                    outs() << format("%8" PRIx64 ":", SectionAddr + Index);
-                    outs() << "\t";
-                    DumpBytes(StringRef(Bytes.data() + Index, Size));
+            if ((*AI)->getKind() != llvm::MCAtom::TextAtom)
+                continue;
 
-                    IP->printInst(&Inst, outs(), "");
+            outs() << "\n\nAtom " << (*AI)->getName() << ": \n";
+            if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(*AI)) {
+                for (MCTextAtom::const_iterator II = TA->begin(), IE = TA->end();
+                     II != IE;
+                     ++II) {
+//                II->Inst.dump();
+                    IP->printInst(&II->Inst, outs(), "");
                     outs() << "\n";
-                } else {
-                    errs() << "warning: invalid instruction encoding\n";
-                    if (Size == 0)
-                        Size = 1; // skip illegible bytes
                 }
+            }
+        }
 
-                // Print relocation for instruction.
-                while (rel_cur != rel_end) {
-                    bool hidden = false;
-                    uint64_t addr;
-                    SmallString<16> name;
-                    SmallString<32> val;
+        outs() << "binary " << triple.getArchName() << "\n";
+    }
 
-                    // If this relocation is hidden, skip it.
-                    if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
-                    if (hidden) goto skip_print_rel;
+    void Binary::disassemble_functions() {
+        error_code ec;
+        for (section_iterator i = o->begin_sections(),
+                 e = o->end_sections();
+             i != e; i.increment(ec)) {
+            if (error(ec)) break;
+            bool text;
+            if (error(i->isText(text))) break;
+            if (!text) continue;
+
+            uint64_t SectionAddr;
+            if (error(i->getAddress(SectionAddr))) break;
+
+            // Make a list of all the symbols in this section.
+            std::vector<std::pair<uint64_t, StringRef> > Symbols;
+            for (symbol_iterator si = o->begin_symbols(),
+                     se = o->end_symbols();
+                 si != se; si.increment(ec)) {
+                bool contains;
+                if (!error(i->containsSymbol(*si, contains)) && contains) {
+                    uint64_t Address;
+                    if (error(si->getAddress(Address))) break;
+                    if (Address == UnknownAddressOrSize) continue;
+                    Address -= SectionAddr;
+
+                    StringRef Name;
+                    if (error(si->getName(Name))) break;
+
+                    outs() << "\nXXX " << Name << "\n";
+
+                    Symbols.push_back(std::make_pair(Address, Name));
+                }
+            }
 
-                    if (error(rel_cur->getOffset(addr))) goto skip_print_rel;
-                    // Stop when rel_cur's address is past the current instruction.
-                    if (addr >= Index + Size) break;
-                    if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
-                    if (error(rel_cur->getValueString(val))) goto skip_print_rel;
+            // Sort the symbols by address, just in case they didn't come in that way.
+            array_pod_sort(Symbols.begin(), Symbols.end());
+
+            // Make a list of all the relocations for this section.
+            std::vector<RelocationRef> Rels;
+            // if (InlineRelocs) {
+            //     for (relocation_iterator ri = i->begin_relocations(),
+            //              re = i->end_relocations();
+            //          ri != re; ri.increment(ec)) {
+            //         if (error(ec)) break;
+            //         Rels.push_back(*ri);
+            //     }
+            // }
+
+            // Sort relocations by address.
+            std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
+
+            StringRef SegmentName = "";
+            // if (const MachOObjectFile *MachO =
+            //     dyn_cast<const MachOObjectFile>(o)) {
+            //     DataRefImpl DR = i->getRawDataRefImpl();
+            //     SegmentName = MachO->getSectionFinalSegmentName(DR);
+            // }
+            StringRef name;
+            if (error(i->getName(name))) break;
+            outs() << "Disassembly of section ";
+            if (!SegmentName.empty())
+                outs() << SegmentName << ",";
+            outs() << name << ':';
+
+            // If the section has no symbols just insert a dummy one and disassemble
+            // the whole section.
+            if (Symbols.empty())
+                Symbols.push_back(std::make_pair(0, name));
+
+
+            StringRef Bytes;
+            if (error(i->getContents(Bytes))) break;
+            StringRefMemoryObject memoryObject(Bytes);
+            uint64_t Size;
+            uint64_t Index;
+            uint64_t SectSize;
+            if (error(i->getSize(SectSize))) break;
+
+            std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
+            std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
+            // Disassemble symbol by symbol.
+            for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
+                uint64_t Start = Symbols[si].first;
+                uint64_t End;
+                // The end is either the size of the section or the beginning of the next
+                // symbol.
+                if (si == se - 1)
+                    End = SectSize;
+                // Make sure this symbol takes up space.
+                else if (Symbols[si + 1].first != Start)
+                    End = Symbols[si + 1].first - 1;
+                else
+                    // This symbol has the same address as the next symbol. Skip it.
+                    continue;
+
+                outs() << '\n' << Symbols[si].second << ":\n";
 
-                    outs() << format("\t\t\t%8" PRIx64 ": ", SectionAddr + addr) << name
-                           << "\t" << val << "\n";
+#ifndef NDEBUG
+                raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
+#else
+                raw_ostream &DebugOut = nulls();
+#endif
 
-                  skip_print_rel:
-                    ++rel_cur;
+                for (Index = Start; Index < End; Index += Size) {
+                    MCInst Inst;
+
+                    if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
+                                               DebugOut, nulls())) {
+                        outs() << format("%8" PRIx64 ":", SectionAddr + Index);
+                        outs() << "\t";
+                        DumpBytes(StringRef(Bytes.data() + Index, Size));
+
+                        IP->printInst(&Inst, outs(), "");
+                        outs() << "\n";
+                    } else {
+                        errs() << "warning: invalid instruction encoding\n";
+                        if (Size == 0)
+                            Size = 1; // skip illegible bytes
+                    }
+
+                    // Print relocation for instruction.
+                    while (rel_cur != rel_end) {
+                        bool hidden = false;
+                        uint64_t addr;
+                        SmallString<16> name;
+                        SmallString<32> val;
+
+                        // If this relocation is hidden, skip it.
+                        if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
+                        if (hidden) goto skip_print_rel;
+
+                        if (error(rel_cur->getOffset(addr))) goto skip_print_rel;
+                        // Stop when rel_cur's address is past the current instruction.
+                        if (addr >= Index + Size) break;
+                        if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
+                        if (error(rel_cur->getValueString(val))) goto skip_print_rel;
+
+                        outs() << format("\t\t\t%8" PRIx64 ": ", SectionAddr + addr) << name
+                               << "\t" << val << "\n";
+
+                      skip_print_rel:
+                        ++rel_cur;
+                    }
                 }
             }
         }
     }
-}
 
-void ::Binary::disassemble_cfg() {
-    for (MCModule::const_func_iterator FI = Mod->func_begin(),
-             FE = Mod->func_end();
-         FI != FE; ++FI) {
-        static int filenum = 0;
-        std::string FileName = std::string("dot/") + (Twine((*FI)->getName()) + "_" + utostr(filenum) + ".dot").str();
+    void Binary::disassemble_cfg() {
+        for (MCModule::const_func_iterator FI = Mod->func_begin(),
+                 FE = Mod->func_end();
+             FI != FE; ++FI) {
+            static int filenum = 0;
+            std::string FileName = std::string("dot/") + (Twine((*FI)->getName()) + "_" + utostr(filenum) + ".dot").str();
 
-        std::cerr << FileName << std::endl;
+            std::cerr << FileName << std::endl;
 
             // Start a new dot file.
-        std::string Error;
-        raw_fd_ostream Out(FileName.c_str(), Error);
-        if (!Error.empty()) {
-            errs() << "llvm-objdump: warning: " << Error << '\n';
-            return;
-        }
-
-        Out << "digraph \"" << (*FI)->getName() << "\" {\n";
-        Out << "graph [ rankdir = \"LR\" ];\n";
-        for (MCFunction::const_iterator i = (*FI)->begin(), e = (*FI)->end(); i != e; ++i) {
-            // Only print blocks that have predecessors.
-            bool hasPreds = (*i)->pred_begin() != (*i)->pred_end();
+            std::string Error;
+            raw_fd_ostream Out(FileName.c_str(), Error);
+            if (!Error.empty()) {
+                errs() << "llvm-objdump: warning: " << Error << '\n';
+                return;
+            }
 
-            if (!hasPreds && i != (*FI)->begin())
-                continue;
+            Out << "digraph \"" << (*FI)->getName() << "\" {\n";
+            Out << "graph [ rankdir = \"LR\" ];\n";
+            for (MCFunction::const_iterator i = (*FI)->begin(), e = (*FI)->end(); i != e; ++i) {
+                // Only print blocks that have predecessors.
+                bool hasPreds = (*i)->pred_begin() != (*i)->pred_end();
+
+                if (!hasPreds && i != (*FI)->begin())
+                    continue;
+
+                Out << '"' << (*i)->getInsts()->getBeginAddr() << "\" [ label=\"<a>";
+                // Print instructions.
+                for (unsigned ii = 0, ie = (*i)->getInsts()->size(); ii != ie;
+                     ++ii) {
+                    if (ii != 0) // Not the first line, start a new row.
+                        Out << '|';
+                    if (ii + 1 == ie) // Last line, add an end id.
+                        Out << "<o>";
+
+                    // Escape special chars and print the instruction in mnemonic form.
+                    std::string Str;
+                    raw_string_ostream OS(Str);
+                    IP->printInst(&(*i)->getInsts()->at(ii).Inst, OS, "");
+                    Out << DOT::EscapeString(OS.str());
+                }
+                Out << "\" shape=\"record\" ];\n";
 
-            Out << '"' << (*i)->getInsts()->getBeginAddr() << "\" [ label=\"<a>";
-            // Print instructions.
-            for (unsigned ii = 0, ie = (*i)->getInsts()->size(); ii != ie;
-                 ++ii) {
-                if (ii != 0) // Not the first line, start a new row.
-                    Out << '|';
-                if (ii + 1 == ie) // Last line, add an end id.
-                    Out << "<o>";
-
-                // Escape special chars and print the instruction in mnemonic form.
-                std::string Str;
-                raw_string_ostream OS(Str);
-                IP->printInst(&(*i)->getInsts()->at(ii).Inst, OS, "");
-                Out << DOT::EscapeString(OS.str());
+                // Add edges.
+                for (MCBasicBlock::succ_const_iterator si = (*i)->succ_begin(),
+                         se = (*i)->succ_end(); si != se; ++si)
+                    Out << (*i)->getInsts()->getBeginAddr() << ":o -> "
+                        << (*si)->getInsts()->getBeginAddr() << ":a\n";
             }
-            Out << "\" shape=\"record\" ];\n";
+            Out << "}\n";
 
-            // Add edges.
-            for (MCBasicBlock::succ_const_iterator si = (*i)->succ_begin(),
-                     se = (*i)->succ_end(); si != se; ++si)
-                Out << (*i)->getInsts()->getBeginAddr() << ":o -> "
-                    << (*si)->getInsts()->getBeginAddr() << ":a\n";
+            ++filenum;
         }
-        Out << "}\n";
-
-        ++filenum;
     }
 }
index 31d7485b8fd6ea8d6706f0764131cf3b2c94a8a1..180d8eefe04948d73455a9edafe7051fee14fa35 100644 (file)
@@ -1,34 +1,52 @@
+#ifndef INCLUDE__Binary_hxx
+#define INCLUDE__Binary_hxx
+
 #include "include.hxx"
+#include "Section.hxx"
 
 #include <string>
+#include <vector>
+#include <functional>
 
 using llvm::OwningPtr;
 
-class Binary {
-private:
-    llvm::Triple triple;
-    const llvm::Target * target;
-    llvm::object::ObjectFile * o;
-
-    OwningPtr<llvm::object::Binary> binary;
-    OwningPtr<const llvm::MCRegisterInfo> MRI;
-    OwningPtr<const llvm::MCAsmInfo> AsmInfo;
-    OwningPtr<llvm::MCModule> Mod;
-    OwningPtr<llvm::MCInstPrinter> IP;
-    OwningPtr<llvm::MCDisassembler> DisAsm;
-    OwningPtr<const llvm::MCObjectFileInfo> MOFI;
-    OwningPtr<llvm::MCContext> Ctx;
-    OwningPtr<const llvm::MCInstrAnalysis> MIA;
-    OwningPtr<const llvm::MCSubtargetInfo> STI;
-    OwningPtr<const llvm::MCInstrInfo> MII;
-    OwningPtr<llvm::MCRelocationInfo> RelInfo;
-    OwningPtr<llvm::MCSymbolizer> Symzer;
-public:
-    Binary(const std::string& filename);
-
-    void disassemble();
-
-    void disassemble_functions();
-
-    void disassemble_cfg();
-};
+namespace qtlldb {
+    class Binary {
+    public:
+        Binary(const std::string& filename);
+
+        void disassemble();
+
+        void disassemble_functions();
+
+        void disassemble_cfg();
+
+        std::vector<std::string> getSymbols();
+
+        std::vector<std::string> getFunctions();
+        void for_each_instruction(const std::string& function, std::function<void (long, std::string, std::string)> callback);
+
+    private:
+        llvm::Triple triple;
+        const llvm::Target * target;
+        llvm::object::ObjectFile * o;
+
+        OwningPtr<llvm::object::Binary> binary;
+        OwningPtr<const llvm::MCRegisterInfo> MRI;
+        OwningPtr<const llvm::MCAsmInfo> AsmInfo;
+        OwningPtr<llvm::MCModule> Mod;
+        OwningPtr<llvm::MCInstPrinter> IP;
+        OwningPtr<llvm::MCDisassembler> DisAsm;
+        OwningPtr<const llvm::MCObjectFileInfo> MOFI;
+        OwningPtr<llvm::MCContext> Ctx;
+        OwningPtr<const llvm::MCInstrAnalysis> MIA;
+        OwningPtr<const llvm::MCSubtargetInfo> STI;
+        OwningPtr<const llvm::MCInstrInfo> MII;
+        OwningPtr<llvm::MCRelocationInfo> RelInfo;
+        OwningPtr<llvm::MCSymbolizer> Symzer;
+
+        std::map<std::string, llvm::object::SectionRef> sections;
+        std::map<std::string, llvm::object::SymbolRef> symbols;
+    };
+}
+#endif
index 3e26227ad6acd086854dfe7ab08a1d347c2b605f..412c42400f4170d06457edc400efebd70bd7b9ff 100644 (file)
@@ -1,31 +1,41 @@
 #include "Mainwindow.h++"
 
+#include <iostream>
+#include <sstream>
+
 #include <QtGui>
 
+namespace {
+
+}
+
 Mainwindow::Mainwindow()
 {
-    // openAction = new QAction(tr("&Open"), this);
+    openAction = new QAction(tr("&Open"), this);
     // saveAction = new QAction(tr("&Save"), this);
     exitAction = new QAction(tr("E&xit"), this);
 
-    // connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
+    connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
     // connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
     connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
 
     fileMenu = menuBar()->addMenu(tr("&File"));
-    // fileMenu->addAction(openAction);
+    fileMenu->addAction(openAction);
     // fileMenu->addAction(saveAction);
-    // fileMenu->addSeparator();
+    fileMenu->addSeparator();
     fileMenu->addAction(exitAction);
 
-    // 
-    // setCentralWidget(textEdit);
+    listWidget = new QListWidget();
+    stackedWidget = new QStackedWidget();
+    dockWidget = new QDockWidget(tr("Functions"), this);
+    dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea |
+                                Qt::RightDockWidgetArea);
+    dockWidget->setWidget(listWidget);
+    addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
+    setCentralWidget(stackedWidget);
 
-    tabwidget = new QTabWidget;
-    setCentralWidget(tabwidget);
-
-    textEdit = new QTextEdit;
-    tabwidget->addTab(textEdit, "edit");
+    connect(listWidget, SIGNAL(currentRowChanged(int)),
+            stackedWidget, SLOT(setCurrentIndex(int)));
 
     setWindowTitle(tr("Notepad"));
 }
@@ -42,5 +52,53 @@ void Mainwindow::quit()
 }
 
 void Mainwindow::open() {
+    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
+                                                    tr("Binaries (*)"));
+
+    if (fileName != "") {
+        curBin = new qtlldb::Binary(fileName.toStdString());
+
+        std::vector<std::string> symbols = curBin->getSymbols();
+        if (0 == symbols.size())
+            populateSymbolInformation(".text");
+        for (std::vector<std::string>::iterator it = symbols.begin();
+             it != symbols.end();
+             ++it) {
+            populateSymbolInformation(*it);
+        }
+    }
+}
+
+void Mainwindow::populateSymbolInformation(const std::string& sym) {
+    QTabWidget * w = new QTabWidget();
+
+    // Listing
+    QTableWidget * t = new QTableWidget();
+    t->setColumnCount(3);
+    t->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+    curBin->for_each_instruction(sym, [&t](long add, std::string bytes, std::string mnemonic) {
+            int row = t->rowCount();
+            std::stringstream s;
+            t->setRowCount(t->rowCount() + 1);
+            s << std::hex << add;
+            t->setItem(row,0,new QTableWidgetItem(s.str().c_str()));
+            s.str("");
+            s << std::hex;
+            for_each(bytes.begin(), bytes.end(), [&s](char c){s << (unsigned int)((unsigned char)c) << ' ';});
+            t->setItem(row,1,new QTableWidgetItem(s.str().c_str()));
+            t->setItem(row,2,new QTableWidgetItem(mnemonic.c_str() + 1));
+        });
+    w->addTab(t, "Listing");
+
+    // CFG
+    QGraphicsScene * scene = new QGraphicsScene;
+    QGraphicsRectItem *rect = scene->addRect(QRectF(0, 0, 100, 100));
+    rect->setFlag(QGraphicsItem::ItemIsMovable);
+    QGraphicsView * view = new QGraphicsView(scene);
+    w->addTab(view, "CFG");
+
+
 
+    listWidget->addItem(sym.c_str());
+    stackedWidget->addWidget(w);
 }
index daf9d3d34a094427c7483be35326e9e37a5c6481..46a6676187261d68eac8ce38e4439d4149fc5223 100644 (file)
@@ -1,23 +1,34 @@
 #include "include.hxx"
 
-
 #include <QTextEdit>
 #include <QPushButton>
 #include <QMainWindow>
+#include <QListWidget>
+#include <QStackedWidget>
 
+#include "Binary.hxx"
 
 class Mainwindow : public QMainWindow {
     Q_OBJECT
+public:
+    Mainwindow();
 private:
+    void populateSymbolInformation(const std::string& sym);
+
     QTextEdit *textEdit;
     QPushButton *quitButton;
-    QAction *exitAction;
     QMenu *fileMenu;
+
     QTabWidget * tabwidget;
+    QListWidget * listWidget;
+    QStackedWidget * stackedWidget;
+    QDockWidget * dockWidget;
+
+    QAction *exitAction;
+    QAction *openAction;
+
+    qtlldb::Binary * curBin;
 private slots:
     void quit();
     void open();
-
-public:
-    Mainwindow();
 };