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