EDDisassembler.cpp revision 3e74d6fdd248e20a280f1dff3da9a6c689c2c4c3
1ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===//
2ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
3ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//                     The LLVM Compiler Infrastructure
4ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
5ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// This file is distributed under the University of Illinois Open Source
6ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// License. See LICENSE.TXT for details.
7ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
8ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===----------------------------------------------------------------------===//
9ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
10ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// This file implements the Enhanced Disassembly library's  disassembler class.
11ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// The disassembler is responsible for vending individual instructions according
12ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan// to a given architecture and disassembly syntax.
13ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//
14ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan//===----------------------------------------------------------------------===//
15ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
168f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan#include "EDDisassembler.h"
178f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan#include "EDInst.h"
189899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan#include "llvm/MC/EDInstInfo.h"
19ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCAsmInfo.h"
20ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCContext.h"
21ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCDisassembler.h"
22ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCExpr.h"
23ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCInst.h"
24ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCInstPrinter.h"
250e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/MC/MCRegisterInfo.h"
26ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCStreamer.h"
27ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng#include "llvm/MC/MCSubtargetInfo.h"
28ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/AsmLexer.h"
29ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCAsmParser.h"
30ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmLexer.h"
3294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
33ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryBuffer.h"
34ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/MemoryObject.h"
35ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#include "llvm/Support/SourceMgr.h"
363e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
373e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h"
38ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananusing namespace llvm;
39ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
40ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::sInitialized = false;
41ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
42ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
439899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstruct TripleMap {
44ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  Triple::ArchType Arch;
45ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  const char *String;
46ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan};
47ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
489899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstatic struct TripleMap triplemap[] = {
499899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::x86,          "i386-unknown-unknown"    },
509899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::x86_64,       "x86_64-unknown-unknown"  },
519899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::arm,          "arm-unknown-unknown"     },
529899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::thumb,        "thumb-unknown-unknown"   },
539899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  { Triple::InvalidArch,  NULL,                     }
54ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan};
55ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
569899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan/// infoFromArch - Returns the TripleMap corresponding to a given architecture,
57ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///   or NULL if there is an error
58ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///
59ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch - The Triple::ArchType for the desired architecture
609899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callananstatic const char *tripleFromArch(Triple::ArchType arch) {
61ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  unsigned int infoIndex;
62ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
639899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) {
649899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan    if (arch == triplemap[infoIndex].Arch)
659899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan      return triplemap[infoIndex].String;
66ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
67ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
68ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return NULL;
69ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
70ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
71ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
72ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///   for the desired assembly syntax, suitable for passing to
73ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///   Target::createMCInstPrinter()
74ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan///
75ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg arch   - The target architecture
76ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan/// @arg syntax - The assembly syntax in sd form
77ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananstatic int getLLVMSyntaxVariant(Triple::ArchType arch,
78847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner                                EDDisassembler::AssemblySyntax syntax) {
79ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  switch (syntax) {
80ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  default:
81ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return -1;
82ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  // Mappings below from X86AsmPrinter.cpp
83847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case EDDisassembler::kEDAssemblySyntaxX86ATT:
84ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    if (arch == Triple::x86 || arch == Triple::x86_64)
85ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return 0;
86ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    else
87ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return -1;
88847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case EDDisassembler::kEDAssemblySyntaxX86Intel:
89ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    if (arch == Triple::x86 || arch == Triple::x86_64)
90ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return 1;
91ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    else
92ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return -1;
93847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  case EDDisassembler::kEDAssemblySyntaxARMUAL:
948f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    if (arch == Triple::arm || arch == Triple::thumb)
958f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      return 0;
968f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    else
978f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      return -1;
98ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
99ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
100ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
101ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananvoid EDDisassembler::initialize() {
102ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (sInitialized)
103ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
104ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
105ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  sInitialized = true;
106ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1079899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  InitializeAllTargetInfos();
108e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng  InitializeAllTargetMCs();
1099899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  InitializeAllAsmParsers();
1109899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  InitializeAllDisassemblers();
111ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
112ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
113ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan#undef BRINGUP_TARGET
114ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
115ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
116847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner                                                AssemblySyntax syntax) {
117ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  CPUKey key;
118ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  key.Arch = arch;
119ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  key.Syntax = syntax;
120ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
121ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
122ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
123ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (i != sDisassemblers.end()) {
124ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return i->second;
1258f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  } else {
126ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    EDDisassembler* sdd = new EDDisassembler(key);
1278f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    if (!sdd->valid()) {
128ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      delete sdd;
129ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return NULL;
130ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    }
131ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
132ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    sDisassemblers[key] = sdd;
133ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
134ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return sdd;
135ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
136ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
137ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return NULL;
138ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
139ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
140ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler *EDDisassembler::getDisassembler(StringRef str,
141847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner                                                AssemblySyntax syntax) {
142847da55716e9c1d39c08ed052bc86d28796cb91fChris Lattner  return getDisassembler(Triple(str).getArch(), syntax);
143ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
144ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
145ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::EDDisassembler(CPUKey &key) :
1468f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  Valid(false),
1478f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  HasSemantics(false),
1488f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  ErrorStream(nulls()),
1498f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  Key(key) {
1509899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  const char *triple = tripleFromArch(key.Arch);
1518f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan
1529899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  if (!triple)
1539899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan    return;
154ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1554285b294a86f507822b8c00d85888e78f69672e5Sean Callanan  LLVMSyntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
156ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1574285b294a86f507822b8c00d85888e78f69672e5Sean Callanan  if (LLVMSyntaxVariant < 0)
158ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
159ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
160ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  std::string tripleString(triple);
161ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  std::string errorString;
162ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
163ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  Tgt = TargetRegistry::lookupTarget(tripleString,
164ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                     errorString);
165ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
166ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!Tgt)
167ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
168ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1691b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  MRI.reset(Tgt->createMCRegInfo(tripleString));
170ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
1711b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  if (!MRI)
172ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
1731b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng
1741b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  initMaps(*MRI);
175ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
1761abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng  AsmInfo.reset(Tgt->createMCAsmInfo(tripleString));
177ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
178ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!AsmInfo)
179ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
180ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
181ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  Disassembler.reset(Tgt->createMCDisassembler());
182ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
183ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!Disassembler)
184ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
1859899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan
1869899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan  InstInfos = Disassembler->getEDInfo();
187ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
188ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstString.reset(new std::string);
189ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstStream.reset(new raw_string_ostream(*InstString));
190b262799d49891b036daa00eddf51947487346c98Evan Cheng  InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo));
191ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
192ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!InstPrinter)
193ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
194ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
195ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
19694b9550a32d189704a8eae55505edf62662c0534Evan Cheng  SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo));
197ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
198d74667e226c3053128f34c6f2c6c9ebfe5b98e50Sean Callanan
1991b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Cheng  initMaps(*MRI);
200ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
201ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  Valid = true;
202ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
203ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
204ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDDisassembler::~EDDisassembler() {
2058f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  if (!valid())
206ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return;
207ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
208ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
209ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanannamespace {
210ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
211ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  ///   as provided by the sd interface.  See MemoryObject.
212ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  class EDMemoryObject : public llvm::MemoryObject {
213ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  private:
214ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    EDByteReaderCallback Callback;
215ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    void *Arg;
216ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  public:
217ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    EDMemoryObject(EDByteReaderCallback callback,
218ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                   void *arg) : Callback(callback), Arg(arg) { }
219ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    ~EDMemoryObject() { }
220ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    uint64_t getBase() const { return 0x0; }
221ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    uint64_t getExtent() const { return (uint64_t)-1; }
222ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    int readByte(uint64_t address, uint8_t *ptr) const {
2238f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      if (!Callback)
224ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        return -1;
225ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
2268f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan      if (Callback(ptr, address, Arg))
227ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        return -1;
228ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
229ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      return 0;
230ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    }
231ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  };
232ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
233ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
234ee5dfd42f1361da9e44b768a12495be235d6043fSean CallananEDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
235ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                   uint64_t address,
236ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                   void *arg) {
237ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  EDMemoryObject memoryObject(byteReader, arg);
238ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
239ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  MCInst* inst = new MCInst;
240ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  uint64_t byteSize;
241ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
242ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!Disassembler->getInstruction(*inst,
243ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                    byteSize,
244ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                    memoryObject,
245ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                    address,
246ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                                    ErrorStream)) {
247ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    delete inst;
248ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return NULL;
2498f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  } else {
2500da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen    const llvm::EDInstInfo *thisInstInfo = NULL;
2518f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan
2520da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen    if (InstInfos) {
2530da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen      thisInstInfo = &InstInfos[inst->getOpcode()];
2540da9f13faa696759150fa29e42e5ee107ee0b712Shantonu Sen    }
255ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
256ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
257ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return sdInst;
258ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
259ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
260ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
2611b0fc9b4182d6bd0703cdfb3b0b91d1e093c946cEvan Chengvoid EDDisassembler::initMaps(const MCRegisterInfo &registerInfo) {
262ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  unsigned numRegisters = registerInfo.getNumRegs();
263ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  unsigned registerIndex;
264ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
265ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
266ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    const char* registerName = registerInfo.get(registerIndex).Name;
267ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
268ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    RegVec.push_back(registerName);
269ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    RegRMap[registerName] = registerIndex;
270ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
271ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
2728f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  switch (Key.Arch) {
2738f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  default:
2748f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
2758f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86:
2768f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86_64:
277ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    stackPointers.insert(registerIDWithName("SP"));
278ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    stackPointers.insert(registerIDWithName("ESP"));
279ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    stackPointers.insert(registerIDWithName("RSP"));
280ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
281ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    programCounters.insert(registerIDWithName("IP"));
282ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    programCounters.insert(registerIDWithName("EIP"));
283ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    programCounters.insert(registerIDWithName("RIP"));
2848f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
2858f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::arm:
2868f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::thumb:
2878f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    stackPointers.insert(registerIDWithName("SP"));
2888f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan
2898f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    programCounters.insert(registerIDWithName("PC"));
2908f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
291ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
292ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
293ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
294ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananconst char *EDDisassembler::nameWithRegisterID(unsigned registerID) const {
295ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (registerID >= RegVec.size())
296ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return NULL;
297ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  else
298ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return RegVec[registerID].c_str();
299ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
300ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
301ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananunsigned EDDisassembler::registerIDWithName(const char *name) const {
302ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  regrmap_t::const_iterator iter = RegRMap.find(std::string(name));
303ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (iter == RegRMap.end())
304ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return 0;
305ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  else
306ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    return (*iter).second;
307ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
308ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
309ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsStackPointer(unsigned registerID) {
310ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return (stackPointers.find(registerID) != stackPointers.end());
311ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
312ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
313ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananbool EDDisassembler::registerIsProgramCounter(unsigned registerID) {
314ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return (programCounters.find(registerID) != programCounters.end());
315ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
316ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
317d374087be5360a353a4239a155b1227057145f48Chris Lattnerint EDDisassembler::printInst(std::string &str, MCInst &inst) {
318ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  PrinterMutex.acquire();
319ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
320d374087be5360a353a4239a155b1227057145f48Chris Lattner  InstPrinter->printInst(&inst, *InstStream);
321ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstStream->flush();
322ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  str = *InstString;
323ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  InstString->clear();
324ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
325ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  PrinterMutex.release();
326ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
327ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return 0;
328ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
329ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
330457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callananstatic void diag_handler(const SMDiagnostic &diag,
331457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan                         void *context)
332457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan{
333457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan  if (context) {
334457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan    EDDisassembler *disassembler = static_cast<EDDisassembler*>(context);
335457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan    diag.Print("", disassembler->ErrorStream);
336457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan  }
337457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan}
338457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan
339ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
340ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                              SmallVectorImpl<AsmToken> &tokens,
341ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan                              const std::string &str) {
342ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  int ret = 0;
343ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
3448f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  switch (Key.Arch) {
3458f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  default:
3468f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    return -1;
3478f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86:
3488f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::x86_64:
3498f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::arm:
3508f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  case Triple::thumb:
3518f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan    break;
3528f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  }
3538f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan
354ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  const char *cStr = str.c_str();
355ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
356ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
357ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  StringRef instName;
358ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  SMLoc instLoc;
359ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
360ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  SourceMgr sourceMgr;
361457856c03f2f0edb2e218fc91851623a1e6dbdbbSean Callanan  sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this));
362ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
363203576aa0cb9d8bf2d2e4d910ebab4b7a63262aeEvan Cheng  MCContext context(*AsmInfo, *MRI, NULL);
364c18409aed80ba1c6c5998befd3c3c8edc865c423Chris Lattner  OwningPtr<MCStreamer> streamer(createNullStreamer(context));
3651b84cce77f8bccc905b4800927ce9016f76c1c40Jim Grosbach  OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr,
3669fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar                                                         context, *streamer,
3679fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar                                                         *AsmInfo));
368ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
369ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  StringRef triple = tripleFromArch(Key.Arch);
370ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(triple, "", ""));
37194b9550a32d189704a8eae55505edf62662c0534Evan Cheng  OwningPtr<MCTargetAsmParser>
37294b9550a32d189704a8eae55505edf62662c0534Evan Cheng    TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
373ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
3749fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar  AsmToken OpcodeToken = genericParser->Lex();
3759fbb37e10d3b2814877bb8d2893d863fe1da660bDaniel Dunbar  AsmToken NextToken = genericParser->Lex();  // consume next token, because specificParser expects us to
376a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan
3778f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  if (OpcodeToken.is(AsmToken::Identifier)) {
378ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    instName = OpcodeToken.getString();
379ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    instLoc = OpcodeToken.getLoc();
380a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan
381a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan    if (NextToken.isNot(AsmToken::Eof) &&
382a870256d7daaa807344a83b807a3e17df2f6852cSean Callanan        TargetParser->ParseInstruction(instName, instLoc, operands))
383ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      ret = -1;
3848f993b8c244bb5ec19d004a070eb9f32c5a29b1aSean Callanan  } else {
385ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    ret = -1;
386ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
387ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
388ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  ParserMutex.acquire();
389ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
390ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  if (!ret) {
391ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    GenericAsmLexer->setBuffer(buf);
392ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
393ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    while (SpecificAsmLexer->Lex(),
394ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan           SpecificAsmLexer->isNot(AsmToken::Eof) &&
395ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan           SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
396ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      if (SpecificAsmLexer->is(AsmToken::Error)) {
397ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        ret = -1;
398ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan        break;
399ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      }
400ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan      tokens.push_back(SpecificAsmLexer->getTok());
401ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan    }
402ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  }
403ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
404ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  ParserMutex.release();
405ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
406ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return ret;
407ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
408ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan
409ee5dfd42f1361da9e44b768a12495be235d6043fSean Callananint EDDisassembler::llvmSyntaxVariant() const {
410ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan  return LLVMSyntaxVariant;
411ee5dfd42f1361da9e44b768a12495be235d6043fSean Callanan}
412