1 //===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Enhanced Disassembly library's disassembler class.
11 // The disassembler is responsible for vending individual instructions according
12 // to a given architecture and disassembly syntax.
14 //===----------------------------------------------------------------------===//
16 #include "EDDisassembler.h"
18 #include "llvm/MC/EDInstInfo.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCDisassembler.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstPrinter.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCParser/AsmLexer.h"
28 #include "llvm/MC/MCParser/MCAsmParser.h"
29 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
30 #include "llvm/Support/MemoryBuffer.h"
31 #include "llvm/Support/MemoryObject.h"
32 #include "llvm/Support/SourceMgr.h"
33 #include "llvm/Target/TargetAsmLexer.h"
34 #include "llvm/Target/TargetAsmParser.h"
35 #include "llvm/Target/TargetRegistry.h"
36 #include "llvm/Target/TargetMachine.h"
37 #include "llvm/Target/TargetRegisterInfo.h"
38 #include "llvm/Target/TargetSelect.h"
41 bool EDDisassembler::sInitialized
= false;
42 EDDisassembler::DisassemblerMap_t
EDDisassembler::sDisassemblers
;
45 Triple::ArchType Arch
;
49 static struct TripleMap triplemap
[] = {
50 { Triple::x86
, "i386-unknown-unknown" },
51 { Triple::x86_64
, "x86_64-unknown-unknown" },
52 { Triple::arm
, "arm-unknown-unknown" },
53 { Triple::thumb
, "thumb-unknown-unknown" },
54 { Triple::InvalidArch
, NULL
, }
57 /// infoFromArch - Returns the TripleMap corresponding to a given architecture,
58 /// or NULL if there is an error
60 /// @arg arch - The Triple::ArchType for the desired architecture
61 static const char *tripleFromArch(Triple::ArchType arch
) {
62 unsigned int infoIndex
;
64 for (infoIndex
= 0; triplemap
[infoIndex
].String
!= NULL
; ++infoIndex
) {
65 if (arch
== triplemap
[infoIndex
].Arch
)
66 return triplemap
[infoIndex
].String
;
72 /// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
73 /// for the desired assembly syntax, suitable for passing to
74 /// Target::createMCInstPrinter()
76 /// @arg arch - The target architecture
77 /// @arg syntax - The assembly syntax in sd form
78 static int getLLVMSyntaxVariant(Triple::ArchType arch
,
79 EDDisassembler::AssemblySyntax syntax
) {
83 // Mappings below from X86AsmPrinter.cpp
84 case EDDisassembler::kEDAssemblySyntaxX86ATT
:
85 if (arch
== Triple::x86
|| arch
== Triple::x86_64
)
89 case EDDisassembler::kEDAssemblySyntaxX86Intel
:
90 if (arch
== Triple::x86
|| arch
== Triple::x86_64
)
94 case EDDisassembler::kEDAssemblySyntaxARMUAL
:
95 if (arch
== Triple::arm
|| arch
== Triple::thumb
)
102 void EDDisassembler::initialize() {
108 InitializeAllTargetInfos();
109 InitializeAllTargets();
110 InitializeAllAsmPrinters();
111 InitializeAllAsmParsers();
112 InitializeAllDisassemblers();
115 #undef BRINGUP_TARGET
117 EDDisassembler
*EDDisassembler::getDisassembler(Triple::ArchType arch
,
118 AssemblySyntax syntax
) {
123 EDDisassembler::DisassemblerMap_t::iterator i
= sDisassemblers
.find(key
);
125 if (i
!= sDisassemblers
.end()) {
128 EDDisassembler
* sdd
= new EDDisassembler(key
);
134 sDisassemblers
[key
] = sdd
;
142 EDDisassembler
*EDDisassembler::getDisassembler(StringRef str
,
143 AssemblySyntax syntax
) {
144 return getDisassembler(Triple(str
).getArch(), syntax
);
147 EDDisassembler::EDDisassembler(CPUKey
&key
) :
150 ErrorStream(nulls()),
152 const char *triple
= tripleFromArch(key
.Arch
);
157 LLVMSyntaxVariant
= getLLVMSyntaxVariant(key
.Arch
, key
.Syntax
);
159 if (LLVMSyntaxVariant
< 0)
162 std::string
tripleString(triple
);
163 std::string errorString
;
165 Tgt
= TargetRegistry::lookupTarget(tripleString
,
172 std::string featureString
;
173 TargetMachine
.reset(Tgt
->createTargetMachine(tripleString
, CPU
,
176 const TargetRegisterInfo
*registerInfo
= TargetMachine
->getRegisterInfo();
181 initMaps(*registerInfo
);
183 AsmInfo
.reset(Tgt
->createAsmInfo(tripleString
));
188 Disassembler
.reset(Tgt
->createMCDisassembler());
193 InstInfos
= Disassembler
->getEDInfo();
195 InstString
.reset(new std::string
);
196 InstStream
.reset(new raw_string_ostream(*InstString
));
197 InstPrinter
.reset(Tgt
->createMCInstPrinter(LLVMSyntaxVariant
, *AsmInfo
));
202 GenericAsmLexer
.reset(new AsmLexer(*AsmInfo
));
203 SpecificAsmLexer
.reset(Tgt
->createAsmLexer(*AsmInfo
));
204 SpecificAsmLexer
->InstallLexer(*GenericAsmLexer
);
206 initMaps(*TargetMachine
->getRegisterInfo());
211 EDDisassembler::~EDDisassembler() {
217 /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
218 /// as provided by the sd interface. See MemoryObject.
219 class EDMemoryObject
: public llvm::MemoryObject
{
221 EDByteReaderCallback Callback
;
224 EDMemoryObject(EDByteReaderCallback callback
,
225 void *arg
) : Callback(callback
), Arg(arg
) { }
226 ~EDMemoryObject() { }
227 uint64_t getBase() const { return 0x0; }
228 uint64_t getExtent() const { return (uint64_t)-1; }
229 int readByte(uint64_t address
, uint8_t *ptr
) const {
233 if (Callback(ptr
, address
, Arg
))
241 EDInst
*EDDisassembler::createInst(EDByteReaderCallback byteReader
,
244 EDMemoryObject
memoryObject(byteReader
, arg
);
246 MCInst
* inst
= new MCInst
;
249 if (!Disassembler
->getInstruction(*inst
,
257 const llvm::EDInstInfo
*thisInstInfo
= NULL
;
260 thisInstInfo
= &InstInfos
[inst
->getOpcode()];
263 EDInst
* sdInst
= new EDInst(inst
, byteSize
, *this, thisInstInfo
);
268 void EDDisassembler::initMaps(const TargetRegisterInfo
®isterInfo
) {
269 unsigned numRegisters
= registerInfo
.getNumRegs();
270 unsigned registerIndex
;
272 for (registerIndex
= 0; registerIndex
< numRegisters
; ++registerIndex
) {
273 const char* registerName
= registerInfo
.get(registerIndex
).Name
;
275 RegVec
.push_back(registerName
);
276 RegRMap
[registerName
] = registerIndex
;
284 stackPointers
.insert(registerIDWithName("SP"));
285 stackPointers
.insert(registerIDWithName("ESP"));
286 stackPointers
.insert(registerIDWithName("RSP"));
288 programCounters
.insert(registerIDWithName("IP"));
289 programCounters
.insert(registerIDWithName("EIP"));
290 programCounters
.insert(registerIDWithName("RIP"));
294 stackPointers
.insert(registerIDWithName("SP"));
296 programCounters
.insert(registerIDWithName("PC"));
301 const char *EDDisassembler::nameWithRegisterID(unsigned registerID
) const {
302 if (registerID
>= RegVec
.size())
305 return RegVec
[registerID
].c_str();
308 unsigned EDDisassembler::registerIDWithName(const char *name
) const {
309 regrmap_t::const_iterator iter
= RegRMap
.find(std::string(name
));
310 if (iter
== RegRMap
.end())
313 return (*iter
).second
;
316 bool EDDisassembler::registerIsStackPointer(unsigned registerID
) {
317 return (stackPointers
.find(registerID
) != stackPointers
.end());
320 bool EDDisassembler::registerIsProgramCounter(unsigned registerID
) {
321 return (programCounters
.find(registerID
) != programCounters
.end());
324 int EDDisassembler::printInst(std::string
&str
, MCInst
&inst
) {
325 PrinterMutex
.acquire();
327 InstPrinter
->printInst(&inst
, *InstStream
);
332 PrinterMutex
.release();
337 static void diag_handler(const SMDiagnostic
&diag
,
341 EDDisassembler
*disassembler
= static_cast<EDDisassembler
*>(context
);
342 diag
.Print("", disassembler
->ErrorStream
);
346 int EDDisassembler::parseInst(SmallVectorImpl
<MCParsedAsmOperand
*> &operands
,
347 SmallVectorImpl
<AsmToken
> &tokens
,
348 const std::string
&str
) {
361 const char *cStr
= str
.c_str();
362 MemoryBuffer
*buf
= MemoryBuffer::getMemBuffer(cStr
, cStr
+ strlen(cStr
));
368 sourceMgr
.setDiagHandler(diag_handler
, static_cast<void*>(this));
369 sourceMgr
.AddNewSourceBuffer(buf
, SMLoc()); // ownership of buf handed over
370 MCContext
context(*AsmInfo
, NULL
);
371 OwningPtr
<MCStreamer
> streamer(createNullStreamer(context
));
372 OwningPtr
<MCAsmParser
> genericParser(createMCAsmParser(*Tgt
, sourceMgr
,
376 StringRef triple
= tripleFromArch(Key
.Arch
);
377 OwningPtr
<MCSubtargetInfo
> STI(Tgt
->createMCSubtargetInfo(triple
, "", ""));
378 OwningPtr
<TargetAsmParser
> TargetParser(Tgt
->createAsmParser(*STI
,
381 AsmToken OpcodeToken
= genericParser
->Lex();
382 AsmToken NextToken
= genericParser
->Lex(); // consume next token, because specificParser expects us to
384 if (OpcodeToken
.is(AsmToken::Identifier
)) {
385 instName
= OpcodeToken
.getString();
386 instLoc
= OpcodeToken
.getLoc();
388 if (NextToken
.isNot(AsmToken::Eof
) &&
389 TargetParser
->ParseInstruction(instName
, instLoc
, operands
))
395 ParserMutex
.acquire();
398 GenericAsmLexer
->setBuffer(buf
);
400 while (SpecificAsmLexer
->Lex(),
401 SpecificAsmLexer
->isNot(AsmToken::Eof
) &&
402 SpecificAsmLexer
->isNot(AsmToken::EndOfStatement
)) {
403 if (SpecificAsmLexer
->is(AsmToken::Error
)) {
407 tokens
.push_back(SpecificAsmLexer
->getTok());
411 ParserMutex
.release();
416 int EDDisassembler::llvmSyntaxVariant() const {
417 return LLVMSyntaxVariant
;