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