2  * Copyright (C) 2013 Apple Inc. All rights reserved. 
   4  * Redistribution and use in source and binary forms, with or without 
   5  * modification, are permitted provided that the following conditions 
   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. 
  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.  
  27 #include "LLVMDisassembler.h" 
  29 #if USE(LLVM_DISASSEMBLER) 
  31 #include "InitializeLLVM.h" 
  33 #include "MacroAssemblerCodeRef.h" 
  37 static const unsigned symbolStringSize 
= 40; 
  39 static const char *symbolLookupCallback( 
  40     void* opaque
, uint64_t referenceValue
, uint64_t* referenceType
, uint64_t referencePC
, 
  41     const char** referenceName
) 
  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; 
  48     char* symbolString 
= static_cast<char*>(opaque
); 
  50     switch (*referenceType
) { 
  51     case LLVMDisassembler_ReferenceType_InOut_None
: 
  53     case LLVMDisassembler_ReferenceType_In_Branch
: 
  55         *referenceType 
= LLVMDisassembler_ReferenceType_InOut_None
; 
  57             symbolString
, symbolStringSize
, "0x%lx", 
  58             static_cast<unsigned long>(referenceValue
)); 
  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"); 
  67             RELEASE_ASSERT_NOT_REACHED(); 
  70         *referenceName 
= "unimplemented reference type!"; 
  71         *referenceType 
= LLVMDisassembler_ReferenceType_InOut_None
; 
  73             symbolString
, symbolStringSize
, "unimplemented:0x%lx", 
  74             static_cast<unsigned long>(referenceValue
)); 
  79 bool tryToDisassembleWithLLVM( 
  80     const MacroAssemblerCodePtr
& codePtr
, size_t size
, const char* prefix
, PrintStream
& out
, 
  81     InstructionSubsetHint
) 
  87     triple 
= "x86_64-apple-darwin"; 
  89     triple 
= "x86-apple-darwin"; 
  91     triple 
= "arm64-apple-darwin"; 
  93 #error "LLVM disassembler currently not supported on this CPU." 
  96     char symbolString
[symbolStringSize
]; 
  98     LLVMDisasmContextRef disassemblyContext 
= 
  99         llvm
->CreateDisasm(triple
, symbolString
, 0, 0, symbolLookupCallback
); 
 100     RELEASE_ASSERT(disassemblyContext
); 
 103     char instructionString
[1000]; 
 105     uint8_t* pc 
= static_cast<uint8_t*>(codePtr
.executableAddress()); 
 106     uint8_t* end 
= pc 
+ size
; 
 110             pcString
, sizeof(pcString
), "0x%lx", 
 111             static_cast<unsigned long>(bitwise_cast
<uintptr_t>(pc
))); 
 113         size_t instructionSize 
= llvm
->DisasmInstruction( 
 114             disassemblyContext
, pc
, end 
- pc
, bitwise_cast
<uintptr_t>(pc
), 
 115             instructionString
, sizeof(instructionString
)); 
 117         if (!instructionSize
) 
 118             snprintf(instructionString
, sizeof(instructionString
), ".byte 0x%02x", *pc
++); 
 120             pc 
+= instructionSize
; 
 122         out
.printf("%s%16s: %s\n", prefix
, pcString
, instructionString
); 
 125     llvm
->DisasmDispose(disassemblyContext
); 
 132 #endif // USE(LLVM_DISASSEMBLER)