1/*
2 * Copyright (C) 2018 Yusuke Suzuki <[email protected]>.
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
28#if ENABLE(DISASSEMBLER) && USE(CAPSTONE)
29
30#include "MacroAssemblerCodeRef.h"
31#include "Options.h"
32#include <capstone/capstone.h>
33
34namespace JSC {
35
36bool tryToDisassemble(const MacroAssemblerCodePtr<DisassemblyPtrTag>& codePtr, size_t size, const char* prefix, PrintStream& out)
37{
38 csh handle;
39 cs_insn* instructions;
40
41#if CPU(X86)
42 if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
43 return false;
44#elif CPU(X86_64)
45 if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
46 return false;
47#elif CPU(ARM_THUMB2)
48 if (cs_open(CS_ARCH_ARM, CS_MODE_THUMB, &handle) != CS_ERR_OK)
49 return false;
50#elif CPU(ARM64)
51 if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &handle) != CS_ERR_OK)
52 return false;
53#elif CPU(MIPS)
54 if (cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32, &handle) != CS_ERR_OK)
55 return false;
56#else
57 return false;
58#endif
59
60#if CPU(X86) || CPU(X86_64)
61 if (cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT) != CS_ERR_OK) {
62 cs_close(&handle);
63 return false;
64 }
65#endif
66
67 size_t count = cs_disasm(handle, codePtr.dataLocation<unsigned char*>(), size, codePtr.dataLocation<uintptr_t>(), 0, &instructions);
68 if (count > 0) {
69 for (size_t i = 0; i < count; ++i) {
70 auto& instruction = instructions[i];
71 char pcString[20];
72 snprintf(pcString, sizeof(pcString), "0x%llx", static_cast<unsigned long long>(instruction.address));
73 out.printf("%s%16s: %s %s\n", prefix, pcString, instruction.mnemonic, instruction.op_str);
74 }
75 cs_free(instructions, count);
76 }
77 cs_close(&handle);
78 return true;
79}
80
81} // namespace JSC
82
83#endif // ENABLE(DISASSEMBLER) && USE(CAPSTONE)
84