Disassembler.cpp revision 9347e0bdf9d9cb691c3681ea06c87716b6251af4
19347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien/*
29347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * Copyright 2011, The Android Open Source Project
39347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien *
49347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * Licensed under the Apache License, Version 2.0 (the "License");
59347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * you may not use this file except in compliance with the License.
69347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * You may obtain a copy of the License at
79347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien *
89347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien *     http://www.apache.org/licenses/LICENSE-2.0
99347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien *
109347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * Unless required by applicable law or agreed to in writing, software
119347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * distributed under the License is distributed on an "AS IS" BASIS,
129347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * See the License for the specific language governing permissions and
149347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien * limitations under the License.
159347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien */
169347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
179347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "Disassembler.h"
189347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
199347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "Config.h"
209347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
219347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "ExecutionEngine/Compiler.h"
229347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
239347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCAsmInfo.h"
249347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCDisassembler.h"
259347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCInst.h"
269347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCInstPrinter.h"
279347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
289347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Support/MemoryObject.h"
299347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Support/raw_ostream.h"
309347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
319347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetData.h"
329347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetMachine.h"
339347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetOptions.h"
349347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetRegistry.h"
359347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetSelect.h"
369347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
379347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/LLVMContext.h"
389347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
399347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if USE_DISASSEMBLER
409347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
419347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chiennamespace {
429347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
439347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienclass BufferMemoryObject : public llvm::MemoryObject {
449347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienprivate:
459347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const uint8_t *mBytes;
469347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  uint64_t mLength;
479347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
489347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienpublic:
499347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  BufferMemoryObject(const uint8_t *Bytes, uint64_t Length)
509347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    : mBytes(Bytes), mLength(Length) {
519347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
529347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
539347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  virtual uint64_t getBase() const { return 0; }
549347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  virtual uint64_t getExtent() const { return mLength; }
559347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
569347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  virtual int readByte(uint64_t Addr, uint8_t *Byte) const {
579347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    if (Addr > getExtent())
589347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      return -1;
599347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    *Byte = mBytes[Addr];
609347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    return 0;
619347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
629347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien};
639347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
649347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien} // namespace anonymous
659347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
669347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chiennamespace bcc {
679347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
689347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienvoid InitializeDisassembler() {
699347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
709347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeARMDisassembler();
719347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeARMAsmPrinter();
729347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
739347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
749347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
759347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86Disassembler();
769347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86AsmPrinter();
779347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
789347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
799347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
809347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86Disassembler();
819347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86AsmPrinter();
829347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
839347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien}
849347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
859347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienvoid Disassemble(char const *OutputFileName,
869347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 llvm::Target const *Target,
879347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 llvm::TargetMachine *TM,
889347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 std::string const &Name,
899347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 unsigned char const *Func,
909347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 size_t FuncSize) {
919347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  llvm::raw_ostream *OS;
929347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
939347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if USE_DISASSEMBLER_FILE
949347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  std::string ErrorInfo;
959347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  OS = new llvm::raw_fd_ostream(OutputFileName, ErrorInfo,
969347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                llvm::raw_fd_ostream::F_Append);
979347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
989347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  if (!ErrorInfo.empty()) {    // some errors occurred
999347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    // LOGE("Error in creating disassembly file");
1009347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    delete OS;
1019347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    return;
1029347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
1039347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#else
1049347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  OS = &llvm::outs();
1059347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
1069347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1079347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  *OS << "Disassembled code: " << Name << "\n";
1089347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1099347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const llvm::MCAsmInfo *AsmInfo;
1109347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const llvm::MCDisassembler *Disassmbler;
1119347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  llvm::MCInstPrinter *IP;
1129347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1139347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  AsmInfo = Target->createAsmInfo(Compiler::getTargetTriple());
1149347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  Disassmbler = Target->createMCDisassembler();
1159347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  IP = Target->createMCInstPrinter(*TM,
1169347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                   AsmInfo->getAssemblerDialect(),
1179347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                   *AsmInfo);
1189347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1199347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize);
1209347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1219347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  uint64_t Size;
1229347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  uint64_t Index;
1239347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1249347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  for (Index = 0; Index < FuncSize; Index += Size) {
1259347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    llvm::MCInst Inst;
1269347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1279347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    if (Disassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
1289347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                    /* REMOVED */ llvm::nulls())) {
1299347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      OS->indent(4);
1309347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      OS->write("0x", 2);
1319347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      OS->write_hex((uint32_t)Func + Index);
1329347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      OS->write(": 0x", 4);
1339347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      OS->write_hex(*(uint32_t *)(Func + Index));
1349347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      IP->printInst(&Inst, *OS);
1359347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      *OS << "\n";
1369347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    } else {
1379347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      if (Size == 0)
1389347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien        Size = 1;  // skip illegible bytes
1399347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    }
1409347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
1419347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1429347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  *OS << "\n";
1439347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete BufferMObj;
1449347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1459347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete AsmInfo;
1469347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete Disassmbler;
1479347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete IP;
1489347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1499347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if USE_DISASSEMBLER_FILE
1509347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  ((llvm::raw_fd_ostream*)OS)->close();
1519347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete OS;
1529347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
1539347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien}
1549347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1559347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien} // namespace bcc
1569347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1579347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif // USE_DISASSEMBLER
158