1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | #include "Disassembler.h" |
11 | #include "llvm-c/Disassembler.h" |
12 | #include "llvm/MC/MCAsmInfo.h" |
13 | #include "llvm/MC/MCContext.h" |
14 | #include "llvm/MC/MCDisassembler.h" |
15 | #include "llvm/MC/MCInst.h" |
16 | #include "llvm/MC/MCInstPrinter.h" |
17 | #include "llvm/MC/MCInstrInfo.h" |
18 | #include "llvm/MC/MCRegisterInfo.h" |
19 | #include "llvm/MC/MCSubtargetInfo.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Support/MemoryObject.h" |
22 | #include "llvm/Support/TargetRegistry.h" |
23 | |
24 | namespace llvm { |
25 | class Target; |
26 | } |
27 | using namespace llvm; |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, |
37 | void *DisInfo, int TagType, |
38 | LLVMOpInfoCallback GetOpInfo, |
39 | LLVMSymbolLookupCallback SymbolLookUp){ |
40 | |
41 | std::string Error; |
42 | const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); |
43 | assert(TheTarget && "Unable to create target!")((void)0); |
44 | |
45 | |
46 | const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(Triple); |
47 | if (!MAI) |
| 2 | | Assuming 'MAI' is non-null | |
|
| |
48 | return 0; |
49 | |
50 | const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); |
51 | if (!MII) |
| 4 | | Assuming 'MII' is non-null | |
|
| |
52 | return 0; |
53 | |
54 | const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple); |
55 | if (!MRI) |
| 6 | | Assuming 'MRI' is non-null | |
|
| |
56 | return 0; |
57 | |
58 | |
59 | std::string FeaturesStr; |
60 | |
61 | const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU, |
62 | FeaturesStr); |
63 | if (!STI) |
| 8 | | Assuming 'STI' is non-null | |
|
| |
64 | return 0; |
65 | |
66 | |
67 | MCContext *Ctx = new MCContext(*MAI, *MRI, 0); |
| |
68 | if (!Ctx) |
| |
69 | return 0; |
70 | |
71 | |
72 | MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); |
73 | if (!DisAsm) |
| |
74 | return 0; |
| 13 | | Memory is never released; potential leak of memory pointed to by 'Ctx' |
|
75 | DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo, Ctx); |
76 | |
77 | |
78 | int AsmPrinterVariant = MAI->getAssemblerDialect(); |
79 | MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, |
80 | *MAI, *MII, *MRI, *STI); |
81 | if (!IP) |
82 | return 0; |
83 | |
84 | LLVMDisasmContext *DC = new LLVMDisasmContext(Triple, DisInfo, TagType, |
85 | GetOpInfo, SymbolLookUp, |
86 | TheTarget, MAI, MRI, |
87 | STI, MII, Ctx, DisAsm, IP); |
88 | if (!DC) |
89 | return 0; |
90 | |
91 | return DC; |
92 | } |
93 | |
94 | LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo, |
95 | int TagType, LLVMOpInfoCallback GetOpInfo, |
96 | LLVMSymbolLookupCallback SymbolLookUp) { |
97 | return LLVMCreateDisasmCPU(Triple, "", DisInfo, TagType, GetOpInfo, |
| 1 | Calling 'LLVMCreateDisasmCPU' | |
|
98 | SymbolLookUp); |
99 | } |
100 | |
101 | |
102 | |
103 | |
104 | void LLVMDisasmDispose(LLVMDisasmContextRef DCR){ |
105 | LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; |
106 | delete DC; |
107 | } |
108 | |
109 | namespace { |
110 | |
111 | |
112 | |
113 | class DisasmMemoryObject : public MemoryObject { |
114 | uint8_t *Bytes; |
115 | uint64_t Size; |
116 | uint64_t BasePC; |
117 | public: |
118 | DisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) : |
119 | Bytes(bytes), Size(size), BasePC(basePC) {} |
120 | |
121 | uint64_t getBase() const { return BasePC; } |
122 | uint64_t getExtent() const { return Size; } |
123 | |
124 | int readByte(uint64_t Addr, uint8_t *Byte) const { |
125 | if (Addr - BasePC >= Size) |
126 | return -1; |
127 | *Byte = Bytes[Addr - BasePC]; |
128 | return 0; |
129 | } |
130 | }; |
131 | } |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, |
146 | uint64_t BytesSize, uint64_t PC, char *OutString, |
147 | size_t OutStringSize){ |
148 | LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; |
149 | |
150 | DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC); |
151 | |
152 | uint64_t Size; |
153 | MCInst Inst; |
154 | const MCDisassembler *DisAsm = DC->getDisAsm(); |
155 | MCInstPrinter *IP = DC->getIP(); |
156 | MCDisassembler::DecodeStatus S; |
157 | S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC, |
158 | nulls(), DC->CommentStream); |
159 | switch (S) { |
160 | case MCDisassembler::Fail: |
161 | case MCDisassembler::SoftFail: |
162 | |
163 | return 0; |
164 | |
165 | case MCDisassembler::Success: { |
166 | DC->CommentStream.flush(); |
167 | StringRef Comments = DC->CommentsToEmit.str(); |
168 | |
169 | SmallVector<char, 64> InsnStr; |
170 | raw_svector_ostream OS(InsnStr); |
171 | IP->printInst(&Inst, OS, Comments); |
172 | OS.flush(); |
173 | |
174 | |
175 | DC->CommentsToEmit.clear(); |
176 | DC->CommentStream.resync(); |
177 | |
178 | assert(OutStringSize != 0 && "Output buffer cannot be zero size")((void)0); |
179 | size_t OutputSize = std::min(OutStringSize-1, InsnStr.size()); |
180 | std::memcpy(OutString, InsnStr.data(), OutputSize); |
181 | OutString[OutputSize] = '\0'; |
182 | |
183 | return Size; |
184 | } |
185 | } |
186 | llvm_unreachable("Invalid DecodeStatus!")__builtin_unreachable(); |
187 | } |
188 | |
189 | |
190 | |
191 | |
192 | |
193 | int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){ |
194 | if (Options & LLVMDisassembler_Option_UseMarkup1){ |
195 | LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; |
196 | MCInstPrinter *IP = DC->getIP(); |
197 | IP->setUseMarkup(1); |
198 | Options &= ~LLVMDisassembler_Option_UseMarkup1; |
199 | } |
200 | if (Options & LLVMDisassembler_Option_PrintImmHex2){ |
201 | LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; |
202 | MCInstPrinter *IP = DC->getIP(); |
203 | IP->setPrintImmHex(1); |
204 | Options &= ~LLVMDisassembler_Option_PrintImmHex2; |
205 | } |
206 | if (Options & LLVMDisassembler_Option_AsmPrinterVariant4){ |
207 | LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; |
208 | |
209 | const MCAsmInfo *MAI = DC->getAsmInfo(); |
210 | const MCInstrInfo *MII = DC->getInstrInfo(); |
211 | const MCRegisterInfo *MRI = DC->getRegisterInfo(); |
212 | const MCSubtargetInfo *STI = DC->getSubtargetInfo(); |
213 | int AsmPrinterVariant = MAI->getAssemblerDialect(); |
214 | AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0; |
215 | MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter( |
216 | AsmPrinterVariant, *MAI, *MII, *MRI, *STI); |
217 | if (IP) { |
218 | DC->setIP(IP); |
219 | Options &= ~LLVMDisassembler_Option_AsmPrinterVariant4; |
220 | } |
221 | } |
222 | return (Options == 0); |
223 | } |