]> git.siccegge.de Git - frida/frida.git/blob - src/disassembler/llvm/LLVMDisassembler.cxx
Also handle case with no filename provided
[frida/frida.git] / src / disassembler / llvm / LLVMDisassembler.cxx
1 #include "disassembler/llvm/LLVMDisassembler.hxx"
2
3 using namespace llvm;
4 using namespace llvm::object;
5
6 /*
7 * TODO: fallback code falls die Datei kein ELF/PE/COFF/MacO/.. binary
8 * ist sondern z.B. einfach nur Instruktionen oder ein Bootsektor oder
9 * foo
10 */
11
12 LLVMDisassembler::LLVMDisassembler(const std::string& filename)
13 : Disassembler(filename)
14 , logger(log4cxx::Logger::getLogger("LLVMDisassembler"))
15 , triple("unknown-unknown-unknown")
16 {
17 LOG4CXX_DEBUG(logger, "Handling file" << filename);
18 auto result = createBinary(filename);
19
20 error_code ec;
21 if ((ec = result.getError())) {
22 LOG4CXX_ERROR(logger, "Failed to load Binary" << ec.message());
23 binary = NULL;
24 return;
25 }
26
27 binary.reset(result.get());
28
29 o = dyn_cast<ObjectFile>(binary.get());
30
31 triple.setArch(Triple::ArchType(o->getArch()));
32 std::string tripleName(triple.getTriple());
33
34 LOG4CXX_INFO(logger, "Architecture " << tripleName);
35
36
37 std::string es;
38 target = TargetRegistry::lookupTarget("", triple, es);
39 if (!target) {
40 LOG4CXX_ERROR(logger, es);
41 return;
42 }
43
44 LOG4CXX_INFO(logger, "Target " << target->getName());
45
46 MRI.reset(target->createMCRegInfo(tripleName));
47 if (!MRI) {
48 LOG4CXX_ERROR(logger, "no register info for target " << tripleName);
49 return;
50 }
51
52 // Set up disassembler.
53 AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName));
54 if (!AsmInfo) {
55 LOG4CXX_ERROR(logger, "no assembly info for target " << tripleName);
56 return;
57 }
58
59 STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
60 if (!STI) {
61 LOG4CXX_ERROR(logger, "no subtarget info for target " << tripleName);
62 return;
63 }
64
65 MII.reset(target->createMCInstrInfo());
66 if (!MII) {
67 LOG4CXX_ERROR(logger, "no instruction info for target " << tripleName);
68 return;
69 }
70
71 DisAsm.reset(target->createMCDisassembler(*STI));
72 if (!DisAsm) {
73 LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName);
74 return;
75 }
76
77 MOFI.reset(new MCObjectFileInfo);
78 Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get()));
79 RelInfo.reset(
80 target->createMCRelocationInfo(tripleName, *Ctx.get()));
81 if (RelInfo) {
82 Symzer.reset(
83 MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(), RelInfo, o));
84 if (Symzer)
85 DisAsm->setSymbolizer(Symzer);
86 }
87
88 MIA.reset(target->createMCInstrAnalysis(MII.get()));
89
90 int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
91 IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
92 if (!IP) {
93 LOG4CXX_ERROR(logger, "no instruction printer for target " << tripleName);
94 return;
95 }
96
97 OwningPtr<MCObjectDisassembler> OD(
98 new MCObjectDisassembler(*o, *DisAsm, *MIA));
99 Mod.reset(OD->buildModule(false));
100 }