Disassembler.cpp revision f11da3081765d3323381b16f2867b2f1df2b9cba
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
21f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien#include "DebugHelper.h"
229347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "ExecutionEngine/Compiler.h"
239347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
249347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCAsmInfo.h"
259347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCDisassembler.h"
269347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCInst.h"
279347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/MC/MCInstPrinter.h"
289347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
299347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Support/MemoryObject.h"
309347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Support/raw_ostream.h"
319347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
329347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetData.h"
339347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetMachine.h"
349347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetOptions.h"
359347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetRegistry.h"
369347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/Target/TargetSelect.h"
379347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
389347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#include "llvm/LLVMContext.h"
399347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
409347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if USE_DISASSEMBLER
419347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
429347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chiennamespace {
439347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
449347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienclass BufferMemoryObject : public llvm::MemoryObject {
459347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienprivate:
469347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const uint8_t *mBytes;
479347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  uint64_t mLength;
489347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
499347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienpublic:
509347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  BufferMemoryObject(const uint8_t *Bytes, uint64_t Length)
519347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    : mBytes(Bytes), mLength(Length) {
529347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
539347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
549347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  virtual uint64_t getBase() const { return 0; }
559347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  virtual uint64_t getExtent() const { return mLength; }
569347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
579347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  virtual int readByte(uint64_t Addr, uint8_t *Byte) const {
589347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    if (Addr > getExtent())
599347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      return -1;
609347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    *Byte = mBytes[Addr];
619347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    return 0;
629347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
639347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien};
649347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
659347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien} // namespace anonymous
669347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
679347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chiennamespace bcc {
689347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
699347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienvoid InitializeDisassembler() {
709347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
719347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeARMDisassembler();
729347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeARMAsmPrinter();
739347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
749347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
759347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
769347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86Disassembler();
779347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86AsmPrinter();
789347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
799347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
809347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
819347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86Disassembler();
829347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  LLVMInitializeX86AsmPrinter();
839347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif
849347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien}
859347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
869347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chienvoid Disassemble(char const *OutputFileName,
879347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 llvm::Target const *Target,
889347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 llvm::TargetMachine *TM,
899347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 std::string const &Name,
909347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 unsigned char const *Func,
919347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                 size_t FuncSize) {
929347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
939347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  std::string ErrorInfo;
949347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
95f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  // Open the disassembler output file
96f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  llvm::raw_fd_ostream OS(OutputFileName, ErrorInfo,
97f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien                          llvm::raw_fd_ostream::F_Append);
98f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien
99f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  if (!ErrorInfo.empty()) {
100f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien    LOGE("Unable to open disassembler output file: %s\n", OutputFileName);
1019347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    return;
1029347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
1039347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
104f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  // Disassemble the given function
105f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  OS << "Disassembled code: " << Name << "\n";
1069347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1079347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const llvm::MCAsmInfo *AsmInfo;
1089347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const llvm::MCDisassembler *Disassmbler;
1099347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  llvm::MCInstPrinter *IP;
1109347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1119347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  AsmInfo = Target->createAsmInfo(Compiler::getTargetTriple());
1129347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  Disassmbler = Target->createMCDisassembler();
1139347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  IP = Target->createMCInstPrinter(*TM,
1149347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                   AsmInfo->getAssemblerDialect(),
1159347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                   *AsmInfo);
1169347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1179347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize);
1189347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1199347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  uint64_t Size;
1209347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  uint64_t Index;
1219347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1229347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  for (Index = 0; Index < FuncSize; Index += Size) {
1239347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    llvm::MCInst Inst;
1249347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1259347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    if (Disassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
1269347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien                                    /* REMOVED */ llvm::nulls())) {
127f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      OS.indent(4);
128f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      OS.write("0x", 2);
129f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      OS.write_hex((uint32_t)Func + Index);
130f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      OS.write(": 0x", 4);
131f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      OS.write_hex(*(uint32_t *)(Func + Index));
132f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      IP->printInst(&Inst, OS);
133f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien      OS << "\n";
1349347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    } else {
1359347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      if (Size == 0)
1369347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien        Size = 1;  // skip illegible bytes
1379347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    }
1389347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  }
1399347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
140f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  OS << "\n";
141f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien
1429347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete BufferMObj;
1439347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1449347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete AsmInfo;
1459347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete Disassmbler;
1469347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien  delete IP;
1479347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
148f11da3081765d3323381b16f2867b2f1df2b9cbaLogan Chien  OS.close();
1499347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien}
1509347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1519347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien} // namespace bcc
1529347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
1539347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien#endif // USE_DISASSEMBLER
154