annotate tools/llvm-readobj/ARMWinEHPrinter.cpp @ 171:66f3bfe93da9

git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 11:07:02 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
171
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===-- ARMWinEHPrinter.cpp - Windows on ARM EH Data Printer ----*- C++ -*-===//
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 // Windows on ARM uses a series of serialised data structures (RuntimeFunction)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 // to create a table of information for unwinding. In order to conserve space,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 // there are two different ways that this data is represented.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 // For functions with canonical forms for the prologue and epilogue, the data
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 // can be stored in a "packed" form. In this case, the data is packed into the
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 // RuntimeFunction's remaining 30-bits and can fully describe the entire frame.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 // +---------------------------------------+
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 // | Function Entry Address |
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 // +---------------------------------------+
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 // | Packed Form Data |
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 // +---------------------------------------+
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 // This layout is parsed by Decoder::dumpPackedEntry. No unwind bytecode is
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 // associated with such a frame as they can be derived from the provided data.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 // The decoder does not synthesize this data as it is unnecessary for the
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 // purposes of validation, with the synthesis being required only by a proper
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 // unwinder.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 // For functions that are large or do not match canonical forms, the data is
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 // split up into two portions, with the actual data residing in the "exception
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 // data" table (.xdata) with a reference to the entry from the "procedure data"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 // (.pdata) entry.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 // The exception data contains information about the frame setup, all of the
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 // epilogue scopes (for functions for which there are multiple exit points) and
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 // the associated exception handler. Additionally, the entry contains byte-code
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 // describing how to unwind the function (c.f. Decoder::decodeOpcodes).
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 // +---------------------------------------+
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 // | Function Entry Address |
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 // +---------------------------------------+
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 // | Exception Data Entry Address |
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 // +---------------------------------------+
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 // This layout is parsed by Decoder::dumpUnpackedEntry. Such an entry must
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 // first resolve the exception data entry address. This structure
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 // (ExceptionDataRecord) has a variable sized header
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 // (c.f. ARM::WinEH::HeaderWords) and encodes most of the same information as
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 // the packed form. However, because this information is insufficient to
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 // synthesize the unwinding, there are associated unwinding bytecode which make
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 // up the bulk of the Decoder.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 // The decoder itself is table-driven, using the first byte to determine the
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 // opcode and dispatching to the associated printing routine. The bytecode
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 // itself is a variable length instruction encoding that can fully describe the
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 // state of the stack and the necessary operations for unwinding to the
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 // beginning of the frame.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 //
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 // The byte-code maintains a 1-1 instruction mapping, indicating both the width
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 // of the instruction (Thumb2 instructions are variable length, 16 or 32 bits
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 // wide) allowing the program to unwind from any point in the prologue, body, or
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 // epilogue of the function.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 #include "ARMWinEHPrinter.h"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 #include "Error.h"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 #include "llvm/ADT/STLExtras.h"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 #include "llvm/ADT/StringExtras.h"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 #include "llvm/Support/ARMWinEH.h"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 #include "llvm/Support/Format.h"
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 using namespace llvm;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 using namespace llvm::object;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 using namespace llvm::support;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 namespace llvm {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 raw_ostream &operator<<(raw_ostream &OS, const ARM::WinEH::ReturnType &RT) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 switch (RT) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 case ARM::WinEH::ReturnType::RT_POP:
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 OS << "pop {pc}";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 case ARM::WinEH::ReturnType::RT_B:
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 OS << "b target";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 case ARM::WinEH::ReturnType::RT_BW:
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 OS << "b.w target";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 case ARM::WinEH::ReturnType::RT_NoEpilogue:
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 OS << "(no epilogue)";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 return OS;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 static std::string formatSymbol(StringRef Name, uint64_t Address,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 uint64_t Offset = 0) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 std::string Buffer;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 raw_string_ostream OS(Buffer);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 if (!Name.empty())
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 OS << Name << " ";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 if (Offset)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 OS << format("+0x%X (0x%" PRIX64 ")", Offset, Address);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 else if (!Name.empty())
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 OS << format("(0x%" PRIX64 ")", Address);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 OS << format("0x%" PRIX64, Address);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 return OS.str();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 namespace llvm {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 namespace ARM {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 namespace WinEH {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 const size_t Decoder::PDataEntrySize = sizeof(RuntimeFunction);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 // TODO name the uops more appropriately
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 const Decoder::RingEntry Decoder::Ring[] = {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 { 0x80, 0x00, 1, &Decoder::opcode_0xxxxxxx }, // UOP_STACK_FREE (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 { 0xc0, 0x80, 2, &Decoder::opcode_10Lxxxxx }, // UOP_POP (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 { 0xf0, 0xc0, 1, &Decoder::opcode_1100xxxx }, // UOP_STACK_SAVE (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 { 0xf8, 0xd0, 1, &Decoder::opcode_11010Lxx }, // UOP_POP (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 { 0xf8, 0xd8, 1, &Decoder::opcode_11011Lxx }, // UOP_POP (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 { 0xf8, 0xe0, 1, &Decoder::opcode_11100xxx }, // UOP_VPOP (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 { 0xfc, 0xe8, 2, &Decoder::opcode_111010xx }, // UOP_STACK_FREE (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 { 0xfe, 0xec, 2, &Decoder::opcode_1110110L }, // UOP_POP (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 { 0xff, 0xee, 2, &Decoder::opcode_11101110 }, // UOP_MICROSOFT_SPECIFIC (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 // UOP_PUSH_MACHINE_FRAME
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 // UOP_PUSH_CONTEXT
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 // UOP_PUSH_TRAP_FRAME
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 // UOP_REDZONE_RESTORE_LR
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 { 0xff, 0xef, 2, &Decoder::opcode_11101111 }, // UOP_LDRPC_POSTINC (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 { 0xff, 0xf5, 2, &Decoder::opcode_11110101 }, // UOP_VPOP (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 { 0xff, 0xf6, 2, &Decoder::opcode_11110110 }, // UOP_VPOP (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 { 0xff, 0xf7, 3, &Decoder::opcode_11110111 }, // UOP_STACK_RESTORE (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 { 0xff, 0xf8, 4, &Decoder::opcode_11111000 }, // UOP_STACK_RESTORE (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 { 0xff, 0xf9, 3, &Decoder::opcode_11111001 }, // UOP_STACK_RESTORE (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 { 0xff, 0xfa, 4, &Decoder::opcode_11111010 }, // UOP_STACK_RESTORE (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 { 0xff, 0xfb, 1, &Decoder::opcode_11111011 }, // UOP_NOP (16-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 { 0xff, 0xfc, 1, &Decoder::opcode_11111100 }, // UOP_NOP (32-bit)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 { 0xff, 0xfd, 1, &Decoder::opcode_11111101 }, // UOP_NOP (16-bit) / END
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 { 0xff, 0xfe, 1, &Decoder::opcode_11111110 }, // UOP_NOP (32-bit) / END
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 { 0xff, 0xff, 1, &Decoder::opcode_11111111 }, // UOP_END
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 };
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 // Unwind opcodes for ARM64.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 const Decoder::RingEntry Decoder::Ring64[] = {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 { 0xe0, 0x00, 1, &Decoder::opcode_alloc_s },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 { 0xe0, 0x20, 1, &Decoder::opcode_save_r19r20_x },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 { 0xc0, 0x40, 1, &Decoder::opcode_save_fplr },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 { 0xc0, 0x80, 1, &Decoder::opcode_save_fplr_x },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 { 0xf8, 0xc0, 2, &Decoder::opcode_alloc_m },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 { 0xfc, 0xc8, 2, &Decoder::opcode_save_regp },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 { 0xfc, 0xcc, 2, &Decoder::opcode_save_regp_x },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 { 0xfc, 0xd0, 2, &Decoder::opcode_save_reg },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 { 0xfe, 0xd4, 2, &Decoder::opcode_save_reg_x },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 { 0xfe, 0xd6, 2, &Decoder::opcode_save_lrpair },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 { 0xfe, 0xd8, 2, &Decoder::opcode_save_fregp },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 { 0xfe, 0xda, 2, &Decoder::opcode_save_fregp_x },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 { 0xfe, 0xdc, 2, &Decoder::opcode_save_freg },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 { 0xff, 0xde, 2, &Decoder::opcode_save_freg_x },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 { 0xff, 0xe0, 4, &Decoder::opcode_alloc_l },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 { 0xff, 0xe1, 1, &Decoder::opcode_setfp },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 { 0xff, 0xe2, 2, &Decoder::opcode_addfp },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 { 0xff, 0xe3, 1, &Decoder::opcode_nop },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 { 0xff, 0xe4, 1, &Decoder::opcode_end },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 { 0xff, 0xe5, 1, &Decoder::opcode_end_c },
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 };
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 void Decoder::printRegisters(const std::pair<uint16_t, uint32_t> &RegisterMask) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 static const char * const GPRRegisterNames[16] = {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 "r11", "ip", "sp", "lr", "pc",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 };
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 const uint16_t GPRMask = std::get<0>(RegisterMask);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 const uint16_t VFPMask = std::get<1>(RegisterMask);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 OS << '{';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 bool Comma = false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 for (unsigned RI = 0, RE = 11; RI < RE; ++RI) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 if (GPRMask & (1 << RI)) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 if (Comma)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 OS << ", ";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 OS << GPRRegisterNames[RI];
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 Comma = true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 for (unsigned RI = 0, RE = 32; RI < RE; ++RI) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 if (VFPMask & (1 << RI)) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 if (Comma)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 OS << ", ";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 OS << "d" << unsigned(RI);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 Comma = true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 for (unsigned RI = 11, RE = 16; RI < RE; ++RI) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 if (GPRMask & (1 << RI)) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 if (Comma)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 OS << ", ";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 OS << GPRRegisterNames[RI];
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 Comma = true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 OS << '}';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 ErrorOr<object::SectionRef>
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 for (const auto &Section : COFF.sections()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 uint64_t Address = Section.getAddress();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 uint64_t Size = Section.getSize();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 if (VA >= Address && (VA - Address) <= Size)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 return Section;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 return readobj_error::unknown_symbol;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 ErrorOr<object::SymbolRef> Decoder::getSymbol(const COFFObjectFile &COFF,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 uint64_t VA, bool FunctionOnly) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 for (const auto &Symbol : COFF.symbols()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 Expected<SymbolRef::Type> Type = Symbol.getType();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 if (!Type)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 return errorToErrorCode(Type.takeError());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 if (FunctionOnly && *Type != SymbolRef::ST_Function)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 continue;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 Expected<uint64_t> Address = Symbol.getAddress();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 if (!Address)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 return errorToErrorCode(Address.takeError());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 if (*Address == VA)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 return Symbol;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 return readobj_error::unknown_symbol;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 const SectionRef &Section,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 uint64_t Offset) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 for (const auto &Relocation : Section.relocations()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 uint64_t RelocationOffset = Relocation.getOffset();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 if (RelocationOffset == Offset)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 return *Relocation.getSymbol();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 return readobj_error::unknown_symbol;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 bool Decoder::opcode_0xxxxxxx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 uint8_t Imm = OC[Offset] & 0x7f;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 SW.startLine() << format("0x%02x ; %s sp, #(%u * 4)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 static_cast<const char *>(Prologue ? "sub" : "add"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 Imm);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
262
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 bool Decoder::opcode_10Lxxxxx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 unsigned Link = (OC[Offset] & 0x20) >> 5;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 uint16_t RegisterMask = (Link << (Prologue ? 14 : 15))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 | ((OC[Offset + 0] & 0x1f) << 8)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 | ((OC[Offset + 1] & 0xff) << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 assert((~RegisterMask & (1 << 13)) && "sp must not be set");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 assert((~RegisterMask & (1 << (Prologue ? 15 : 14))) && "pc must not be set");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
271
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 SW.startLine() << format("0x%02x 0x%02x ; %s.w ",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 OC[Offset + 0], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
274 Prologue ? "push" : "pop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 printRegisters(std::make_pair(RegisterMask, 0));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
277
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
281
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 bool Decoder::opcode_1100xxxx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 SW.startLine() << format("0x%02x ; mov r%u, sp\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
286 OC[Offset], OC[Offset] & 0xf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 SW.startLine() << format("0x%02x ; mov sp, r%u\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 OC[Offset], OC[Offset] & 0xf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
293
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 bool Decoder::opcode_11010Lxx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 unsigned Link = (OC[Offset] & 0x4) >> 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 unsigned Count = (OC[Offset] & 0x3);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
298
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 uint16_t GPRMask = (Link << (Prologue ? 14 : 15))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 | (((1 << (Count + 1)) - 1) << 4);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
301
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 SW.startLine() << format("0x%02x ; %s ", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 Prologue ? "push" : "pop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 printRegisters(std::make_pair(GPRMask, 0));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
306
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
310
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 bool Decoder::opcode_11011Lxx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 unsigned Link = (OC[Offset] & 0x4) >> 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 unsigned Count = (OC[Offset] & 0x3) + 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
315
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 uint16_t GPRMask = (Link << (Prologue ? 14 : 15))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 | (((1 << (Count + 1)) - 1) << 4);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
318
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 SW.startLine() << format("0x%02x ; %s.w ", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 Prologue ? "push" : "pop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 printRegisters(std::make_pair(GPRMask, 0));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
323
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
327
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 bool Decoder::opcode_11100xxx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 unsigned High = (OC[Offset] & 0x7);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 uint32_t VFPMask = (((1 << (High + 1)) - 1) << 8);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
332
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 SW.startLine() << format("0x%02x ; %s ", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 Prologue ? "vpush" : "vpop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 printRegisters(std::make_pair(0, VFPMask));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
337
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
341
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 bool Decoder::opcode_111010xx(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 uint16_t Imm = ((OC[Offset + 0] & 0x03) << 8) | ((OC[Offset + 1] & 0xff) << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
345
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 SW.startLine() << format("0x%02x 0x%02x ; %s.w sp, #(%u * 4)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 OC[Offset + 0], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 static_cast<const char *>(Prologue ? "sub" : "add"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 Imm);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
350
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
354
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 bool Decoder::opcode_1110110L(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 uint8_t GPRMask = ((OC[Offset + 0] & 0x01) << (Prologue ? 14 : 15))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 | ((OC[Offset + 1] & 0xff) << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
359
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 SW.startLine() << format("0x%02x 0x%02x ; %s ", OC[Offset + 0],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 OC[Offset + 1], Prologue ? "push" : "pop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 printRegisters(std::make_pair(GPRMask, 0));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
364
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 bool Decoder::opcode_11101110(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 assert(!Prologue && "may not be used in prologue");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
372
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 if (OC[Offset + 1] & 0xf0)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 SW.startLine() << format("0x%02x 0x%02x ; reserved\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 OC[Offset + 0], OC[Offset + 1]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 SW.startLine()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 << format("0x%02x 0x%02x ; microsoft-specific (type: %u)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] & 0x0f);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
380
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
384
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 bool Decoder::opcode_11101111(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 assert(!Prologue && "may not be used in prologue");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
388
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 if (OC[Offset + 1] & 0xf0)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 SW.startLine() << format("0x%02x 0x%02x ; reserved\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
391 OC[Offset + 0], OC[Offset + 1]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 SW.startLine()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 << format("0x%02x 0x%02x ; ldr.w lr, [sp], #%u\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 OC[Offset + 0], OC[Offset + 1], OC[Offset + 1] << 2);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
396
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
400
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 bool Decoder::opcode_11110101(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 uint32_t VFPMask = ((1 << (End - Start)) - 1) << Start;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
406
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 SW.startLine() << format("0x%02x 0x%02x ; %s ", OC[Offset + 0],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 OC[Offset + 1], Prologue ? "vpush" : "vpop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 printRegisters(std::make_pair(0, VFPMask));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
411
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
415
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 bool Decoder::opcode_11110110(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 unsigned Start = (OC[Offset + 1] & 0xf0) >> 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 unsigned End = (OC[Offset + 1] & 0x0f) >> 0;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 uint32_t VFPMask = ((1 << (End - Start)) - 1) << 16;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
421
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 SW.startLine() << format("0x%02x 0x%02x ; %s ", OC[Offset + 0],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
423 OC[Offset + 1], Prologue ? "vpush" : "vpop");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 printRegisters(std::make_pair(0, VFPMask));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
426
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
430
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 bool Decoder::opcode_11110111(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
434
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 SW.startLine() << format("0x%02x 0x%02x 0x%02x ; %s sp, sp, #(%u * 4)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
436 OC[Offset + 0], OC[Offset + 1], OC[Offset + 2],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 static_cast<const char *>(Prologue ? "sub" : "add"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 Imm);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
439
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 Offset += 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
443
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 bool Decoder::opcode_11111000(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 uint32_t Imm = (OC[Offset + 1] << 16)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 | (OC[Offset + 2] << 8)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 | (OC[Offset + 3] << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
449
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 SW.startLine()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 << format("0x%02x 0x%02x 0x%02x 0x%02x ; %s sp, sp, #(%u * 4)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 OC[Offset + 0], OC[Offset + 1], OC[Offset + 2], OC[Offset + 3],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
454
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 Offset += 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
458
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 bool Decoder::opcode_11111001(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 uint32_t Imm = (OC[Offset + 1] << 8) | (OC[Offset + 2] << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
462
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 SW.startLine()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 << format("0x%02x 0x%02x 0x%02x ; %s.w sp, sp, #(%u * 4)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 OC[Offset + 0], OC[Offset + 1], OC[Offset + 2],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
466 static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
467
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 Offset += 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
471
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 bool Decoder::opcode_11111010(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 uint32_t Imm = (OC[Offset + 1] << 16)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 | (OC[Offset + 2] << 8)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 | (OC[Offset + 3] << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
477
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 SW.startLine()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
479 << format("0x%02x 0x%02x 0x%02x 0x%02x ; %s.w sp, sp, #(%u * 4)\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 OC[Offset + 0], OC[Offset + 1], OC[Offset + 2], OC[Offset + 3],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
481 static_cast<const char *>(Prologue ? "sub" : "add"), Imm);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
482
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 Offset += 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
486
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 bool Decoder::opcode_11111011(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 SW.startLine() << format("0x%02x ; nop\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
493
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 bool Decoder::opcode_11111100(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 SW.startLine() << format("0x%02x ; nop.w\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
500
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
501 bool Decoder::opcode_11111101(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 SW.startLine() << format("0x%02x ; b\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
504 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
507
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 bool Decoder::opcode_11111110(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 SW.startLine() << format("0x%02x ; b.w\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
512 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
514
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 bool Decoder::opcode_11111111(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
520
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 // ARM64 unwind codes start here.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 bool Decoder::opcode_alloc_s(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 uint32_t NumBytes = (OC[Offset] & 0x1F) << 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 SW.startLine() << format("0x%02x ; %s sp, #%u\n", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 static_cast<const char *>(Prologue ? "sub" : "add"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 NumBytes);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
531
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
532 bool Decoder::opcode_save_r19r20_x(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 uint32_t Off = (OC[Offset] & 0x1F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 "0x%02x ; stp x19, x20, [sp, #-%u]!\n", OC[Offset], Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 "0x%02x ; ldp x19, x20, [sp], #%u\n", OC[Offset], Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
544
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 bool Decoder::opcode_save_fplr(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 uint32_t Off = (OC[Offset] & 0x3F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 "0x%02x ; %s x29, x30, [sp, #%u]\n", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 static_cast<const char *>(Prologue ? "stp" : "ldp"), Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
554
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 bool Decoder::opcode_save_fplr_x(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 uint32_t Off = ((OC[Offset] & 0x3F) + 1) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 "0x%02x ; stp x29, x30, [sp, #-%u]!\n", OC[Offset], Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 "0x%02x ; ldp x29, x30, [sp], #%u\n", OC[Offset], Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
567
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 bool Decoder::opcode_alloc_m(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 uint32_t NumBytes = ((OC[Offset] & 0x07) << 8);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 NumBytes |= (OC[Offset + 1] & 0xFF);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 NumBytes <<= 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 SW.startLine() << format("0x%02x%02x ; %s sp, #%u\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 static_cast<const char *>(Prologue ? "sub" : "add"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 NumBytes);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
579 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
580
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 bool Decoder::opcode_save_regp(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 uint32_t Reg = ((OC[Offset] & 0x03) << 8);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 Reg += 19;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 "0x%02x%02x ; %s x%u, x%u, [sp, #%u]\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 static_cast<const char *>(Prologue ? "stp" : "ldp"), Reg, Reg + 1, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
595
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
596 bool Decoder::opcode_save_regp_x(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 uint32_t Reg = ((OC[Offset] & 0x03) << 8);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 Reg += 19;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 uint32_t Off = ((OC[Offset + 1] & 0x3F) + 1) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 "0x%02x%02x ; stp x%u, x%u, [sp, #-%u]!\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 OC[Offset], OC[Offset + 1], Reg,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 Reg + 1, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 "0x%02x%02x ; ldp x%u, x%u, [sp], #%u\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 OC[Offset], OC[Offset + 1], Reg,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 Reg + 1, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
616
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 bool Decoder::opcode_save_reg(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 uint32_t Reg = (OC[Offset] & 0x03) << 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 Reg += 19;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
624 SW.startLine() << format("0x%02x%02x ; %s x%u, [sp, #%u]\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
625 OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
626 static_cast<const char *>(Prologue ? "str" : "ldr"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
628 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
631
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
632 bool Decoder::opcode_save_reg_x(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 uint32_t Reg = (OC[Offset] & 0x01) << 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 Reg |= (OC[Offset + 1] & 0xE0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 Reg >>= 5;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 Reg += 19;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 uint32_t Off = ((OC[Offset + 1] & 0x1F) + 1) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 SW.startLine() << format("0x%02x%02x ; str x%u, [sp, #%u]!\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 OC[Offset], OC[Offset + 1], Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
642 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 SW.startLine() << format("0x%02x%02x ; ldr x%u, [sp], #%u\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
644 OC[Offset], OC[Offset + 1], Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
646 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
648
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 bool Decoder::opcode_save_lrpair(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
651 uint32_t Reg = (OC[Offset] & 0x01) << 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 Reg *= 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 Reg += 19;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 SW.startLine() << format("0x%02x%02x ; %s x%u, lr, [sp, #%u]\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
658 OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 static_cast<const char *>(Prologue ? "stp" : "ldp"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
664
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 bool Decoder::opcode_save_fregp(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 uint32_t Reg = (OC[Offset] & 0x01) << 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 Reg += 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 SW.startLine() << format("0x%02x%02x ; %s d%u, d%u, [sp, #%u]\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 static_cast<const char *>(Prologue ? "stp" : "ldp"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 Reg, Reg + 1, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
679
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 bool Decoder::opcode_save_fregp_x(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 uint32_t Reg = (OC[Offset] & 0x01) << 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
683 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 Reg += 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 uint32_t Off = ((OC[Offset + 1] & 0x3F) + 1) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 "0x%02x%02x ; stp d%u, d%u, [sp, #-%u]!\n", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 OC[Offset + 1], Reg, Reg + 1, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 "0x%02x%02x ; ldp d%u, d%u, [sp], #%u\n", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 OC[Offset + 1], Reg, Reg + 1, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
696 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
698
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 bool Decoder::opcode_save_freg(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 uint32_t Reg = (OC[Offset] & 0x01) << 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
702 Reg |= (OC[Offset + 1] & 0xC0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 Reg >>= 6;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 Reg += 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 uint32_t Off = (OC[Offset + 1] & 0x3F) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 SW.startLine() << format("0x%02x%02x ; %s d%u, [sp, #%u]\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 static_cast<const char *>(Prologue ? "str" : "ldr"),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
713
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 bool Decoder::opcode_save_freg_x(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 uint32_t Reg = ((OC[Offset + 1] & 0xE0) >> 5) + 8;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 uint32_t Off = ((OC[Offset + 1] & 0x1F) + 1) << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 if (Prologue)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 "0x%02x%02x ; str d%u, [sp, #-%u]!\n", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 OC[Offset + 1], Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 else
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 "0x%02x%02x ; ldr d%u, [sp], #%u\n", OC[Offset],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 OC[Offset + 1], Reg, Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
729
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 bool Decoder::opcode_alloc_l(const uint8_t *OC, unsigned &Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 unsigned Length, bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 unsigned Off =
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 (OC[Offset + 1] << 16) | (OC[Offset + 2] << 8) | (OC[Offset + 3] << 0);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 Off <<= 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 SW.startLine() << format(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 "0x%02x%02x%02x%02x ; %s sp, #%u\n", OC[Offset], OC[Offset + 1],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 OC[Offset + 2], OC[Offset + 3],
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 static_cast<const char *>(Prologue ? "sub" : "add"), Off);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 Offset += 4;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
742
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 bool Decoder::opcode_setfp(const uint8_t *OC, unsigned &Offset, unsigned Length,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 SW.startLine() << format("0x%02x ; mov fp, sp\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
749
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
750 bool Decoder::opcode_addfp(const uint8_t *OC, unsigned &Offset, unsigned Length,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 unsigned NumBytes = OC[Offset + 1] << 3;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 SW.startLine() << format("0x%02x%02x ; add fp, sp, #%u\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 OC[Offset], OC[Offset + 1], NumBytes);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 Offset += 2;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
758
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 bool Decoder::opcode_nop(const uint8_t *OC, unsigned &Offset, unsigned Length,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
760 bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 SW.startLine() << format("0x%02x ; nop\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
764 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
765
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 bool Decoder::opcode_end(const uint8_t *OC, unsigned &Offset, unsigned Length,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
767 bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 SW.startLine() << format("0x%02x ; end\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
770 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
771 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
772
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 bool Decoder::opcode_end_c(const uint8_t *OC, unsigned &Offset, unsigned Length,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 SW.startLine() << format("0x%02x ; end_c\n", OC[Offset]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
776 ++Offset;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
779
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 bool Prologue) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 const RingEntry* DecodeRing = isAArch64 ? Ring64 : Ring;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 bool Terminated = false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
785 for (unsigned OI = Offset, OE = Opcodes.size(); !Terminated && OI < OE; ) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 for (unsigned DI = 0;; ++DI) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 if ((isAArch64 && (DI >= array_lengthof(Ring64))) ||
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
788 (!isAArch64 && (DI >= array_lengthof(Ring)))) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 SW.startLine() << format("0x%02x ; Bad opcode!\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 Opcodes.data()[OI]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 ++OI;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
793 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
794
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
795 if ((Opcodes[OI] & DecodeRing[DI].Mask) == DecodeRing[DI].Value) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 if (OI + DecodeRing[DI].Length > OE) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 SW.startLine() << format("Opcode 0x%02x goes past the unwind data\n",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 Opcodes[OI]);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 OI += DecodeRing[DI].Length;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
801 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 Terminated =
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 (this->*DecodeRing[DI].Routine)(Opcodes.data(), OI, 0, Prologue);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
805 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
806 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
807 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
809
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
811 const SectionRef &Section,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
812 uint64_t FunctionAddress, uint64_t VA) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
813 ArrayRef<uint8_t> Contents;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
814 if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
816
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
817 uint64_t SectionVA = Section.getAddress();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 uint64_t Offset = VA - SectionVA;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 const ulittle32_t *Data =
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
821
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 // Sanity check to ensure that the .xdata header is present.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
823 // A header is one or two words, followed by at least one word to describe
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 // the unwind codes. Applicable to both ARM and AArch64.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 if (Contents.size() - Offset < 8)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
826 report_fatal_error(".xdata must be at least 8 bytes in size");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
827
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 const ExceptionDataRecord XData(Data, isAArch64);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 DictScope XRS(SW, "ExceptionData");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
830 SW.printNumber("FunctionLength",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
831 isAArch64 ? XData.FunctionLengthInBytesAArch64() :
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
832 XData.FunctionLengthInBytesARM());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
833 SW.printNumber("Version", XData.Vers());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
834 SW.printBoolean("ExceptionData", XData.X());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
835 SW.printBoolean("EpiloguePacked", XData.E());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 if (!isAArch64)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
837 SW.printBoolean("Fragment", XData.F());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
838 SW.printNumber(XData.E() ? "EpilogueOffset" : "EpilogueScopes",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
839 XData.EpilogueCount());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 uint64_t ByteCodeLength = XData.CodeWords() * sizeof(uint32_t);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 SW.printNumber("ByteCodeLength", ByteCodeLength);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
842
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
843 if ((int64_t)(Contents.size() - Offset - 4 * HeaderWords(XData) -
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
844 (XData.E() ? 0 : XData.EpilogueCount() * 4) -
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
845 (XData.X() ? 8 : 0)) < (int64_t)ByteCodeLength) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
846 SW.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
847 report_fatal_error("Malformed unwind data");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
848 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
849
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
850 if (XData.E()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
851 ArrayRef<uint8_t> UC = XData.UnwindByteCode();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
852 if (isAArch64 || !XData.F()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
853 ListScope PS(SW, "Prologue");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
854 decodeOpcodes(UC, 0, /*Prologue=*/true);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
856 if (XData.EpilogueCount()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
857 ListScope ES(SW, "Epilogue");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
858 decodeOpcodes(UC, XData.EpilogueCount(), /*Prologue=*/false);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
859 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
860 } else {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
861 {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
862 ListScope PS(SW, "Prologue");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 decodeOpcodes(XData.UnwindByteCode(), 0, /*Prologue=*/true);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
865 ArrayRef<ulittle32_t> EpilogueScopes = XData.EpilogueScopes();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
866 ListScope ESS(SW, "EpilogueScopes");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
867 for (const EpilogueScope ES : EpilogueScopes) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
868 DictScope ESES(SW, "EpilogueScope");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
869 SW.printNumber("StartOffset", ES.EpilogueStartOffset());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
870 if (!isAArch64)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
871 SW.printNumber("Condition", ES.Condition());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
872 SW.printNumber("EpilogueStartIndex",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
873 isAArch64 ? ES.EpilogueStartIndexAArch64()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
874 : ES.EpilogueStartIndexARM());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
875 if (ES.ES & ~0xffc3ffff)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
876 SW.printNumber("ReservedBits", (ES.ES >> 18) & 0xF);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
877
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
878 ListScope Opcodes(SW, "Opcodes");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
879 decodeOpcodes(XData.UnwindByteCode(),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 isAArch64 ? ES.EpilogueStartIndexAArch64()
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
881 : ES.EpilogueStartIndexARM(),
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 /*Prologue=*/false);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
883 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
884 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
885
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
886 if (XData.X()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
887 const uint32_t Address = XData.ExceptionHandlerRVA();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
888 const uint32_t Parameter = XData.ExceptionHandlerParameter();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
889 const size_t HandlerOffset = HeaderWords(XData)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
890 + (XData.E() ? 0 : XData.EpilogueCount())
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
891 + XData.CodeWords();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
892
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
893 ErrorOr<SymbolRef> Symbol = getRelocatedSymbol(
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
894 COFF, Section, Offset + HandlerOffset * sizeof(uint32_t));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
895 if (!Symbol)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
896 Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
897 if (!Symbol) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
898 ListScope EHS(SW, "ExceptionHandler");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
899 SW.printString("Routine", "(null)");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
900 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
901 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
902
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
903 Expected<StringRef> Name = Symbol->getName();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
904 if (!Name) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
905 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
906 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
907 logAllUnhandledErrors(Name.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
908 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
910 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
911
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 ListScope EHS(SW, "ExceptionHandler");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 SW.printString("Routine", formatSymbol(*Name, Address));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
914 SW.printHex("Parameter", Parameter);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
916
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
917 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
918 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
919
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
920 bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
921 const SectionRef Section, uint64_t Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
922 unsigned Index, const RuntimeFunction &RF) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
923 assert(RF.Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
924 "packed entry cannot be treated as an unpacked entry");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
925
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
927 if (!Function)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
929
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
930 ErrorOr<SymbolRef> XDataRecord = getRelocatedSymbol(COFF, Section, Offset + 4);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 if (!XDataRecord)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 XDataRecord = getSymbol(COFF, RF.ExceptionInformationRVA());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
933
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 if (!RF.BeginAddress && !Function)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
935 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
936 if (!RF.UnwindData && !XDataRecord)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
937 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
938
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
939 StringRef FunctionName;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
940 uint64_t FunctionAddress;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
941 if (Function) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
942 Expected<StringRef> FunctionNameOrErr = Function->getName();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
943 if (!FunctionNameOrErr) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
944 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
947 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 FunctionName = *FunctionNameOrErr;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
951 Expected<uint64_t> FunctionAddressOrErr = Function->getAddress();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 if (!FunctionAddressOrErr) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 logAllUnhandledErrors(FunctionAddressOrErr.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
959 FunctionAddress = *FunctionAddressOrErr;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
960 } else {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 FunctionAddress = COFF.getImageBase() + RF.BeginAddress;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
962 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
963
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
964 SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
965
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
966 if (XDataRecord) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
967 Expected<StringRef> Name = XDataRecord->getName();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
968 if (!Name) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
969 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
970 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
971 logAllUnhandledErrors(Name.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
972 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
973 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
974 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
975
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
976 Expected<uint64_t> AddressOrErr = XDataRecord->getAddress();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
977 if (!AddressOrErr) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
978 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
979 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
980 logAllUnhandledErrors(AddressOrErr.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
981 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
982 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
983 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
984 uint64_t Address = *AddressOrErr;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
985
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
986 SW.printString("ExceptionRecord", formatSymbol(*Name, Address));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
987
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
988 Expected<section_iterator> SIOrErr = XDataRecord->getSection();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
989 if (!SIOrErr) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
990 // TODO: Actually report errors helpfully.
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
991 consumeError(SIOrErr.takeError());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
992 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
993 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
994 section_iterator SI = *SIOrErr;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
995
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
996 // FIXME: Do we need to add an offset from the relocation?
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
997 return dumpXDataRecord(COFF, *SI, FunctionAddress,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
998 RF.ExceptionInformationRVA());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
999 } else {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1000 uint64_t Address = COFF.getImageBase() + RF.ExceptionInformationRVA();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1001 SW.printString("ExceptionRecord", formatSymbol("", Address));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1002
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1003 ErrorOr<SectionRef> Section = getSectionContaining(COFF, Address);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1004 if (!Section)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1005 return false;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1006
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1007 return dumpXDataRecord(COFF, *Section, FunctionAddress, Address);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1009 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1011 bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1012 const SectionRef Section, uint64_t Offset,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1013 unsigned Index, const RuntimeFunction &RF) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014 assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed ||
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1015 RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016 "unpacked entry cannot be treated as a packed entry");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1019 if (!Function)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1020 Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1022 StringRef FunctionName;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1023 uint64_t FunctionAddress;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1024 if (Function) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1025 Expected<StringRef> FunctionNameOrErr = Function->getName();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1026 if (!FunctionNameOrErr) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1027 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1028 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1029 logAllUnhandledErrors(FunctionNameOrErr.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1030 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1031 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1032 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1033 FunctionName = *FunctionNameOrErr;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1034 Expected<uint64_t> FunctionAddressOrErr = Function->getAddress();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1035 if (!FunctionAddressOrErr) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1036 std::string Buf;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1037 llvm::raw_string_ostream OS(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1038 logAllUnhandledErrors(FunctionAddressOrErr.takeError(), OS);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1039 OS.flush();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1040 report_fatal_error(Buf);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1041 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1042 FunctionAddress = *FunctionAddressOrErr;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1043 } else {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1044 FunctionAddress = COFF.getPE32Header()->ImageBase + RF.BeginAddress;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1045 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1046
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1047 SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1048 if (!isAArch64)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1049 SW.printBoolean("Fragment",
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1050 RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1051 SW.printNumber("FunctionLength", RF.FunctionLength());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1052 SW.startLine() << "ReturnType: " << RF.Ret() << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1053 SW.printBoolean("HomedParameters", RF.H());
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1054 SW.startLine() << "SavedRegisters: ";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1055 printRegisters(SavedRegisterMask(RF));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1056 OS << '\n';
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057 SW.printNumber("StackAdjustment", StackAdjustment(RF) << 2);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1059 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1060 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1061
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1062 bool Decoder::dumpProcedureDataEntry(const COFFObjectFile &COFF,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1063 const SectionRef Section, unsigned Index,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1064 ArrayRef<uint8_t> Contents) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1065 uint64_t Offset = PDataEntrySize * Index;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1066 const ulittle32_t *Data =
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1067 reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1068
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1069 const RuntimeFunction Entry(Data);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1070 DictScope RFS(SW, "RuntimeFunction");
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1071 if (Entry.Flag() == RuntimeFunctionFlag::RFF_Unpacked)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1072 return dumpUnpackedEntry(COFF, Section, Offset, Index, Entry);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1073 if (isAArch64) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1074 SW.startLine() << "Packed unwind data not yet supported for ARM64\n";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1075 return true;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 return dumpPackedEntry(COFF, Section, Offset, Index, Entry);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 void Decoder::dumpProcedureData(const COFFObjectFile &COFF,
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1081 const SectionRef Section) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1082 ArrayRef<uint8_t> Contents;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1083 if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1084 return;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1085
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1086 if (Contents.size() % PDataEntrySize) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1087 errs() << ".pdata content is not " << PDataEntrySize << "-byte aligned\n";
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1088 return;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1089 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1090
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091 for (unsigned EI = 0, EE = Contents.size() / PDataEntrySize; EI < EE; ++EI)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 if (!dumpProcedureDataEntry(COFF, Section, EI, Contents))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093 break;
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 Error Decoder::dumpProcedureData(const COFFObjectFile &COFF) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 for (const auto &Section : COFF.sections()) {
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 Expected<StringRef> NameOrErr =
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099 COFF.getSectionName(COFF.getCOFFSection(Section));
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 if (!NameOrErr)
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1101 return NameOrErr.takeError();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1102
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1103 if (NameOrErr->startswith(".pdata"))
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1104 dumpProcedureData(COFF, Section);
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1105 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106 return Error::success();
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1107 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1108 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109 }
66f3bfe93da9 git version 2c4ca6832fa6b306ee6a7010bfb80a3f2596f824
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 }