1 /* 2 * Copyright 2011, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "Disassembler.h" 18 19 #include "Config.h" 20 21 #include "DebugHelper.h" 22 #include "ExecutionEngine/Compiler.h" 23 24 #include "llvm/MC/MCAsmInfo.h" 25 #include "llvm/MC/MCDisassembler.h" 26 #include "llvm/MC/MCInst.h" 27 #include "llvm/MC/MCInstPrinter.h" 28 29 #include "llvm/Support/MemoryObject.h" 30 #include "llvm/Support/raw_ostream.h" 31 32 #include "llvm/Target/TargetData.h" 33 #include "llvm/Target/TargetMachine.h" 34 #include "llvm/Target/TargetOptions.h" 35 #include "llvm/Target/TargetRegistry.h" 36 #include "llvm/Target/TargetSelect.h" 37 38 #include "llvm/LLVMContext.h" 39 40 #if USE_DISASSEMBLER 41 42 namespace { 43 44 class BufferMemoryObject : public llvm::MemoryObject { 45 private: 46 const uint8_t *mBytes; 47 uint64_t mLength; 48 49 public: 50 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) 51 : mBytes(Bytes), mLength(Length) { 52 } 53 54 virtual uint64_t getBase() const { return 0; } 55 virtual uint64_t getExtent() const { return mLength; } 56 57 virtual int readByte(uint64_t Addr, uint8_t *Byte) const { 58 if (Addr > getExtent()) 59 return -1; 60 *Byte = mBytes[Addr]; 61 return 0; 62 } 63 }; 64 65 } // namespace anonymous 66 67 namespace bcc { 68 69 void InitializeDisassembler() { 70 #if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN) 71 LLVMInitializeARMDisassembler(); 72 #endif 73 74 #if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN) || \ 75 defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN) 76 LLVMInitializeX86Disassembler(); 77 #endif 78 } 79 80 void Disassemble(char const *OutputFileName, 81 llvm::Target const *Target, 82 llvm::TargetMachine *TM, 83 std::string const &Name, 84 unsigned char const *Func, 85 size_t FuncSize) { 86 87 std::string ErrorInfo; 88 89 // Open the disassembler output file 90 llvm::raw_fd_ostream OS(OutputFileName, ErrorInfo, 91 llvm::raw_fd_ostream::F_Append); 92 93 if (!ErrorInfo.empty()) { 94 LOGE("Unable to open disassembler output file: %s\n", OutputFileName); 95 return; 96 } 97 98 // Disassemble the given function 99 OS << "Disassembled code: " << Name << "\n"; 100 101 const llvm::MCAsmInfo *AsmInfo; 102 const llvm::MCDisassembler *Disassmbler; 103 llvm::MCInstPrinter *IP; 104 105 AsmInfo = Target->createMCAsmInfo(Compiler::getTargetTriple()); 106 Disassmbler = Target->createMCDisassembler(); 107 IP = Target->createMCInstPrinter(AsmInfo->getAssemblerDialect(), 108 *AsmInfo); 109 110 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize); 111 112 uint64_t Size; 113 uint64_t Index; 114 115 for (Index = 0; Index < FuncSize; Index += Size) { 116 llvm::MCInst Inst; 117 118 if (Disassmbler->getInstruction(Inst, Size, *BufferMObj, Index, 119 /* REMOVED */ llvm::nulls())) { 120 OS.indent(4); 121 OS.write("0x", 2); 122 OS.write_hex((uint32_t)Func + Index); 123 OS.write(": 0x", 4); 124 OS.write_hex(*(uint32_t *)(Func + Index)); 125 IP->printInst(&Inst, OS); 126 OS << "\n"; 127 } else { 128 if (Size == 0) 129 Size = 1; // skip illegible bytes 130 } 131 } 132 133 OS << "\n"; 134 135 delete BufferMObj; 136 137 delete AsmInfo; 138 delete Disassmbler; 139 delete IP; 140 141 OS.close(); 142 } 143 144 } // namespace bcc 145 146 #endif // USE_DISASSEMBLER 147