Disassembler.cpp revision c72c4ddfcd79c74f70713da91a69569451b5c19e
1/* 2 * Copyright 2011-2012, 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 "bcc/Support/Disassembler.h" 18 19#include <llvm/LLVMContext.h> 20 21#include <llvm/MC/MCAsmInfo.h> 22#include <llvm/MC/MCDisassembler.h> 23#include <llvm/MC/MCInst.h> 24#include <llvm/MC/MCInstPrinter.h> 25 26#include <llvm/Support/MemoryObject.h> 27#include <llvm/Support/TargetRegistry.h> 28#include <llvm/Support/TargetSelect.h> 29#include <llvm/Support/raw_ostream.h> 30 31#include <llvm/Target/TargetData.h> 32#include <llvm/Target/TargetMachine.h> 33#include <llvm/Target/TargetOptions.h> 34 35#include "bcc/Config/Config.h" 36#include "bcc/Support/DebugHelper.h" 37 38#if USE_DISASSEMBLER 39 40namespace { 41 42class BufferMemoryObject : public llvm::MemoryObject { 43private: 44 const uint8_t *mBytes; 45 uint64_t mLength; 46 47public: 48 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) 49 : mBytes(Bytes), mLength(Length) { 50 } 51 52 virtual uint64_t getBase() const { return 0; } 53 virtual uint64_t getExtent() const { return mLength; } 54 55 virtual int readByte(uint64_t Addr, uint8_t *Byte) const { 56 if (Addr > getExtent()) 57 return -1; 58 *Byte = mBytes[Addr]; 59 return 0; 60 } 61}; 62 63} // namespace anonymous 64 65namespace bcc { 66 67void InitializeDisassembler() { 68#if defined(PROVIDE_ARM_CODEGEN) 69 LLVMInitializeARMDisassembler(); 70#endif 71 72#if defined(PROVIDE_X86_CODEGEN) 73 LLVMInitializeX86Disassembler(); 74#endif 75} 76 77void Disassemble(char const *OutputFileName, 78 llvm::Target const *Target, 79 llvm::TargetMachine *TM, 80 std::string const &Name, 81 unsigned char const *Func, 82 size_t FuncSize) { 83 84 std::string ErrorInfo; 85 86 // Open the disassembler output file 87 llvm::raw_fd_ostream OS(OutputFileName, ErrorInfo, 88 llvm::raw_fd_ostream::F_Append); 89 90 if (!ErrorInfo.empty()) { 91 ALOGE("Unable to open disassembler output file: %s\n", OutputFileName); 92 return; 93 } 94 95 ALOGI("Writing LLVM disassembly to file: %s\n", OutputFileName); 96 // Disassemble the given function 97 OS << "Disassembled code: " << Name << "\n"; 98 99 const llvm::MCAsmInfo *AsmInfo; 100 const llvm::MCSubtargetInfo *SubtargetInfo; 101 const llvm::MCDisassembler *Disassembler; 102 llvm::MCInstPrinter *IP; 103 104 const std::string& TripleName(Compiler::getTargetTriple()); 105 106 AsmInfo = Target->createMCAsmInfo(Compiler::getTargetTriple()); 107 SubtargetInfo = Target->createMCSubtargetInfo(TripleName, "", ""); 108 Disassembler = Target->createMCDisassembler(*SubtargetInfo); 109 110 const llvm::MCInstrInfo *MII = Target->createMCInstrInfo(); 111 const llvm::MCRegisterInfo *MRI = Target->createMCRegInfo(TripleName); 112 113 IP = Target->createMCInstPrinter(AsmInfo->getAssemblerDialect(), 114 *AsmInfo, 115 *MII, 116 *MRI, 117 *SubtargetInfo); 118 119 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize); 120 121 uint64_t Size; 122 uint64_t Index; 123 124 for (Index = 0; Index < FuncSize; Index += Size) { 125 llvm::MCInst Inst; 126 127 if (Disassembler->getInstruction(Inst, Size, *BufferMObj, Index, 128 /* REMOVED */ llvm::nulls(), llvm::nulls())) { 129 OS.indent(4); 130 OS.write("0x", 2); 131 OS.write_hex((uint32_t)Func + Index); 132 OS.write(": 0x", 4); 133 OS.write_hex(*(uint32_t *)(Func + Index)); 134 IP->printInst(&Inst, OS, ""); 135 OS << "\n"; 136 } else { 137 if (Size == 0) 138 Size = 1; // skip illegible bytes 139 } 140 } 141 142 OS << "\n"; 143 144 delete BufferMObj; 145 146 delete AsmInfo; 147 delete Disassembler; 148 delete IP; 149 150 OS.close(); 151} 152 153} // namespace bcc 154 155#endif // USE_DISASSEMBLER 156