1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "LLVMDisassembler.h" 28 29#if USE(LLVM_DISASSEMBLER) 30 31#include "InitializeLLVM.h" 32#include "LLVMAPI.h" 33#include "MacroAssemblerCodeRef.h" 34 35namespace JSC { 36 37static const unsigned symbolStringSize = 40; 38 39static const char *symbolLookupCallback( 40 void* opaque, uint64_t referenceValue, uint64_t* referenceType, uint64_t referencePC, 41 const char** referenceName) 42{ 43 // Set this if you want to debug an unexpected reference type. Currently we only encounter these 44 // if we try to disassemble garbage, since our code generator never uses them. These include things 45 // like PC-relative references. 46 static const bool crashOnUnexpected = false; 47 48 char* symbolString = static_cast<char*>(opaque); 49 50 switch (*referenceType) { 51 case LLVMDisassembler_ReferenceType_InOut_None: 52 return 0; 53 case LLVMDisassembler_ReferenceType_In_Branch: 54 *referenceName = 0; 55 *referenceType = LLVMDisassembler_ReferenceType_InOut_None; 56 snprintf( 57 symbolString, symbolStringSize, "0x%lx", 58 static_cast<unsigned long>(referenceValue)); 59 return symbolString; 60 default: 61 if (crashOnUnexpected) { 62 dataLog("referenceValue = ", referenceValue, "\n"); 63 dataLog("referenceType = ", RawPointer(referenceType), ", *referenceType = ", *referenceType, "\n"); 64 dataLog("referencePC = ", referencePC, "\n"); 65 dataLog("referenceName = ", RawPointer(referenceName), "\n"); 66 67 RELEASE_ASSERT_NOT_REACHED(); 68 } 69 70 *referenceName = "unimplemented reference type!"; 71 *referenceType = LLVMDisassembler_ReferenceType_InOut_None; 72 snprintf( 73 symbolString, symbolStringSize, "unimplemented:0x%lx", 74 static_cast<unsigned long>(referenceValue)); 75 return symbolString; 76 } 77} 78 79bool tryToDisassembleWithLLVM( 80 const MacroAssemblerCodePtr& codePtr, size_t size, const char* prefix, PrintStream& out, 81 InstructionSubsetHint) 82{ 83 initializeLLVM(); 84 85 const char* triple; 86#if CPU(X86_64) 87 triple = "x86_64-apple-darwin"; 88#elif CPU(X86) 89 triple = "x86-apple-darwin"; 90#elif CPU(ARM64) 91 triple = "arm64-apple-darwin"; 92#else 93#error "LLVM disassembler currently not supported on this CPU." 94#endif 95 96 char symbolString[symbolStringSize]; 97 98 LLVMDisasmContextRef disassemblyContext = 99 llvm->CreateDisasm(triple, symbolString, 0, 0, symbolLookupCallback); 100 RELEASE_ASSERT(disassemblyContext); 101 102 char pcString[20]; 103 char instructionString[1000]; 104 105 uint8_t* pc = static_cast<uint8_t*>(codePtr.executableAddress()); 106 uint8_t* end = pc + size; 107 108 while (pc < end) { 109 snprintf( 110 pcString, sizeof(pcString), "0x%lx", 111 static_cast<unsigned long>(bitwise_cast<uintptr_t>(pc))); 112 113 size_t instructionSize = llvm->DisasmInstruction( 114 disassemblyContext, pc, end - pc, bitwise_cast<uintptr_t>(pc), 115 instructionString, sizeof(instructionString)); 116 117 if (!instructionSize) 118 snprintf(instructionString, sizeof(instructionString), ".byte 0x%02x", *pc++); 119 else 120 pc += instructionSize; 121 122 out.printf("%s%16s: %s\n", prefix, pcString, instructionString); 123 } 124 125 llvm->DisasmDispose(disassemblyContext); 126 127 return true; 128} 129 130} // namespace JSC 131 132#endif // USE(LLVM_DISASSEMBLER) 133 134