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/MCParser/AsmLexer.h"
27 #include "llvm/MC/MCParser/MCAsmParser.h"
28 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/MemoryObject.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Target/TargetAsmLexer.h"
33 #include "llvm/Target/TargetAsmParser.h"
34 #include "llvm/Target/TargetRegistry.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Target/TargetRegisterInfo.h"
37 #include "llvm/Target/TargetSelect.h"
40 bool EDDisassembler::sInitialized
= false;
41 EDDisassembler::DisassemblerMap_t
EDDisassembler::sDisassemblers
;
44 Triple::ArchType Arch
;
48 static struct TripleMap triplemap
[] = {
49 { Triple::x86
, "i386-unknown-unknown" },
50 { Triple::x86_64
, "x86_64-unknown-unknown" },
51 { Triple::arm
, "arm-unknown-unknown" },
52 { Triple::thumb
, "thumb-unknown-unknown" },
53 { Triple::InvalidArch
, NULL
, }
56 /// infoFromArch - Returns the TripleMap corresponding to a given architecture,
57 /// or NULL if there is an error
59 /// @arg arch - The Triple::ArchType for the desired architecture
60 static const char *tripleFromArch(Triple::ArchType arch
) {
61 unsigned int infoIndex
;
63 for (infoIndex
= 0; triplemap
[infoIndex
].String
!= NULL
; ++infoIndex
) {
64 if (arch
== triplemap
[infoIndex
].Arch
)
65 return triplemap
[infoIndex
].String
;
71 /// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
72 /// for the desired assembly syntax, suitable for passing to
73 /// Target::createMCInstPrinter()
75 /// @arg arch - The target architecture
76 /// @arg syntax - The assembly syntax in sd form
77 static int getLLVMSyntaxVariant(Triple::ArchType arch
,
78 EDDisassembler::AssemblySyntax syntax
) {
82 // Mappings below from X86AsmPrinter.cpp
83 case EDDisassembler::kEDAssemblySyntaxX86ATT
:
84 if (arch
== Triple::x86
|| arch
== Triple::x86_64
)
88 case EDDisassembler::kEDAssemblySyntaxX86Intel
:
89 if (arch
== Triple::x86
|| arch
== Triple::x86_64
)
93 case EDDisassembler::kEDAssemblySyntaxARMUAL
:
94 if (arch
== Triple::arm
|| arch
== Triple::thumb
)
101 void EDDisassembler::initialize() {
107 InitializeAllTargetInfos();
108 InitializeAllTargets();
109 InitializeAllAsmPrinters();
110 InitializeAllAsmParsers();
111 InitializeAllDisassemblers();
114 #undef BRINGUP_TARGET
116 EDDisassembler
*EDDisassembler::getDisassembler(Triple::ArchType arch
,
117 AssemblySyntax syntax
) {
122 EDDisassembler::DisassemblerMap_t::iterator i
= sDisassemblers
.find(key
);
124 if (i
!= sDisassemblers
.end()) {
127 EDDisassembler
* sdd
= new EDDisassembler(key
);
133 sDisassemblers
[key
] = sdd
;
141 EDDisassembler
*EDDisassembler::getDisassembler(StringRef str
,
142 AssemblySyntax syntax
) {
143 return getDisassembler(Triple(str
).getArch(), syntax
);
146 EDDisassembler::EDDisassembler(CPUKey
&key
) :
149 ErrorStream(nulls()),
151 const char *triple
= tripleFromArch(key
.Arch
);
156 LLVMSyntaxVariant
= getLLVMSyntaxVariant(key
.Arch
, key
.Syntax
);
158 if (LLVMSyntaxVariant
< 0)
161 std::string
tripleString(triple
);
162 std::string errorString
;
164 Tgt
= TargetRegistry::lookupTarget(tripleString
,
170 std::string featureString
;
172 TargetMachine
.reset(Tgt
->createTargetMachine(tripleString
,
175 const TargetRegisterInfo
*registerInfo
= TargetMachine
->getRegisterInfo();
180 initMaps(*registerInfo
);
182 AsmInfo
.reset(Tgt
->createAsmInfo(tripleString
));
187 Disassembler
.reset(Tgt
->createMCDisassembler());
192 InstInfos
= Disassembler
->getEDInfo();
194 InstString
.reset(new std::string
);
195 InstStream
.reset(new raw_string_ostream(*InstString
));
196 InstPrinter
.reset(Tgt
->createMCInstPrinter(LLVMSyntaxVariant
, *AsmInfo
));
201 GenericAsmLexer
.reset(new AsmLexer(*AsmInfo
));
202 SpecificAsmLexer
.reset(Tgt
->createAsmLexer(*AsmInfo
));
203 SpecificAsmLexer
->InstallLexer(*GenericAsmLexer
);
205 initMaps(*TargetMachine
->getRegisterInfo());
210 EDDisassembler::~EDDisassembler() {
216 /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
217 /// as provided by the sd interface. See MemoryObject.
218 class EDMemoryObject
: public llvm::MemoryObject
{
220 EDByteReaderCallback Callback
;
223 EDMemoryObject(EDByteReaderCallback callback
,
224 void *arg
) : Callback(callback
), Arg(arg
) { }
225 ~EDMemoryObject() { }
226 uint64_t getBase() const { return 0x0; }
227 uint64_t getExtent() const { return (uint64_t)-1; }
228 int readByte(uint64_t address
, uint8_t *ptr
) const {
232 if (Callback(ptr
, address
, Arg
))
240 EDInst
*EDDisassembler::createInst(EDByteReaderCallback byteReader
,
243 EDMemoryObject
memoryObject(byteReader
, arg
);
245 MCInst
* inst
= new MCInst
;
248 if (!Disassembler
->getInstruction(*inst
,
256 const llvm::EDInstInfo
*thisInstInfo
;
258 thisInstInfo
= &InstInfos
[inst
->getOpcode()];
260 EDInst
* sdInst
= new EDInst(inst
, byteSize
, *this, thisInstInfo
);
265 void EDDisassembler::initMaps(const TargetRegisterInfo
®isterInfo
) {
266 unsigned numRegisters
= registerInfo
.getNumRegs();
267 unsigned registerIndex
;
269 for (registerIndex
= 0; registerIndex
< numRegisters
; ++registerIndex
) {
270 const char* registerName
= registerInfo
.get(registerIndex
).Name
;
272 RegVec
.push_back(registerName
);
273 RegRMap
[registerName
] = registerIndex
;
281 stackPointers
.insert(registerIDWithName("SP"));
282 stackPointers
.insert(registerIDWithName("ESP"));
283 stackPointers
.insert(registerIDWithName("RSP"));
285 programCounters
.insert(registerIDWithName("IP"));
286 programCounters
.insert(registerIDWithName("EIP"));
287 programCounters
.insert(registerIDWithName("RIP"));
291 stackPointers
.insert(registerIDWithName("SP"));
293 programCounters
.insert(registerIDWithName("PC"));
298 const char *EDDisassembler::nameWithRegisterID(unsigned registerID
) const {
299 if (registerID
>= RegVec
.size())
302 return RegVec
[registerID
].c_str();
305 unsigned EDDisassembler::registerIDWithName(const char *name
) const {
306 regrmap_t::const_iterator iter
= RegRMap
.find(std::string(name
));
307 if (iter
== RegRMap
.end())
310 return (*iter
).second
;
313 bool EDDisassembler::registerIsStackPointer(unsigned registerID
) {
314 return (stackPointers
.find(registerID
) != stackPointers
.end());
317 bool EDDisassembler::registerIsProgramCounter(unsigned registerID
) {
318 return (programCounters
.find(registerID
) != programCounters
.end());
321 int EDDisassembler::printInst(std::string
&str
, MCInst
&inst
) {
322 PrinterMutex
.acquire();
324 InstPrinter
->printInst(&inst
, *InstStream
);
329 PrinterMutex
.release();
334 int EDDisassembler::parseInst(SmallVectorImpl
<MCParsedAsmOperand
*> &operands
,
335 SmallVectorImpl
<AsmToken
> &tokens
,
336 const std::string
&str
) {
349 const char *cStr
= str
.c_str();
350 MemoryBuffer
*buf
= MemoryBuffer::getMemBuffer(cStr
, cStr
+ strlen(cStr
));
356 sourceMgr
.AddNewSourceBuffer(buf
, SMLoc()); // ownership of buf handed over
357 MCContext
context(*AsmInfo
);
358 OwningPtr
<MCStreamer
> streamer(createNullStreamer(context
));
359 OwningPtr
<MCAsmParser
> genericParser(createMCAsmParser(*Tgt
, sourceMgr
,
362 OwningPtr
<TargetAsmParser
> TargetParser(Tgt
->createAsmParser(*genericParser
,
365 AsmToken OpcodeToken
= genericParser
->Lex();
366 AsmToken NextToken
= genericParser
->Lex(); // consume next token, because specificParser expects us to
368 if (OpcodeToken
.is(AsmToken::Identifier
)) {
369 instName
= OpcodeToken
.getString();
370 instLoc
= OpcodeToken
.getLoc();
372 if (NextToken
.isNot(AsmToken::Eof
) &&
373 TargetParser
->ParseInstruction(instName
, instLoc
, operands
))
379 ParserMutex
.acquire();
382 GenericAsmLexer
->setBuffer(buf
);
384 while (SpecificAsmLexer
->Lex(),
385 SpecificAsmLexer
->isNot(AsmToken::Eof
) &&
386 SpecificAsmLexer
->isNot(AsmToken::EndOfStatement
)) {
387 if (SpecificAsmLexer
->is(AsmToken::Error
)) {
391 tokens
.push_back(SpecificAsmLexer
->getTok());
395 ParserMutex
.release();
400 int EDDisassembler::llvmSyntaxVariant() const {
401 return LLVMSyntaxVariant
;