Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/cpu/ppc/disassembler_ppc.cpp
40930 views
1
/*
2
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2019 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#include "asm/macroAssembler.inline.hpp"
27
#include "code/codeCache.hpp"
28
#include "compiler/disassembler.hpp"
29
#include "gc/shared/collectedHeap.hpp"
30
#include "gc/shared/cardTableBarrierSet.hpp"
31
#include "gc/shared/genOopClosures.inline.hpp"
32
#include "oops/oop.inline.hpp"
33
#include "runtime/handles.inline.hpp"
34
#include "runtime/stubCodeGenerator.hpp"
35
#include "runtime/stubRoutines.hpp"
36
37
// Macro to print instruction bits.
38
// numbering of instruction bits on ppc64 is (highest) 0 1 ... 30 31 (lowest).
39
#define print_instruction_bits(st, instruction, start_bit, end_bit) \
40
{ assert((start_bit) <= (end_bit), "sanity check"); \
41
for (int i=(31-(start_bit));i>=(31-(end_bit));i--) { \
42
(st)->print("%d", ((instruction) >> i) & 0x1); \
43
} \
44
}
45
46
// Macro to decode "bo" instruction bits.
47
#define print_decoded_bo_bits(env, instruction, end_bit) \
48
{ int bo_bits = (instruction >> (31 - (end_bit))) & 0x1f; \
49
if ( ((bo_bits & 0x1c) == 0x4) || ((bo_bits & 0x1c) == 0xc) ) { \
50
switch (bo_bits & 0x3) { \
51
case (0 << 1) | (0 << 0): env->print("[no_hint]"); break; \
52
case (0 << 1) | (1 << 0): env->print("[reserved]"); break; \
53
case (1 << 1) | (0 << 0): env->print("[not_taken]"); break; \
54
case (1 << 1) | (1 << 0): env->print("[taken]"); break; \
55
default: break; \
56
} \
57
} else if ( ((bo_bits & 0x14) == 0x10) ) { \
58
switch (bo_bits & 0x9) { \
59
case (0 << 3) | (0 << 0): env->print("[no_hint]"); break; \
60
case (0 << 3) | (1 << 0): env->print("[reserved]"); break; \
61
case (1 << 3) | (0 << 0): env->print("[not_taken]"); break; \
62
case (1 << 3) | (1 << 0): env->print("[taken]"); break; \
63
default: break; \
64
} \
65
} \
66
}
67
68
// Macro to decode "bh" instruction bits.
69
#define print_decoded_bh_bits(env, instruction, end_bit, is_bclr) \
70
{ int bh_bits = (instruction >> (31 - (end_bit))) & 0x3; \
71
if (is_bclr) { \
72
switch (bh_bits) { \
73
case (0 << 1) | (0 << 0): env->print("[subroutine_return]"); break; \
74
case (0 << 1) | (1 << 0): env->print("[not_return_but_same]"); break; \
75
case (1 << 1) | (0 << 0): env->print("[reserved]"); break; \
76
case (1 << 1) | (1 << 0): env->print("[not_predictable]"); break; \
77
default: break; \
78
} \
79
} else { \
80
switch (bh_bits) { \
81
case (0 << 1) | (0 << 0): env->print("[not_return_but_same]"); break; \
82
case (0 << 1) | (1 << 0): env->print("[reserved]"); break; \
83
case (1 << 1) | (0 << 0): env->print("[reserved]"); break; \
84
case (1 << 1) | (1 << 0): env->print("[not_predictable]"); break; \
85
default: break; \
86
} \
87
} \
88
}
89
90
address Disassembler::find_prev_instr(address here, int n_instr) {
91
if (!os::is_readable_pointer(here)) return NULL; // obviously a bad location to decode
92
93
// Find most distant possible starting point.
94
// Narrow down because we don't want to SEGV while printing.
95
address start = here - n_instr*Assembler::instr_maxlen(); // starting point can't be further away.
96
while ((start < here) && !os::is_readable_range(start, here)) {
97
start = align_down(start, os::min_page_size()) + os::min_page_size();
98
}
99
if (start >= here) {
100
// Strange. Can only happen with here on page boundary.
101
return NULL;
102
}
103
return start;
104
}
105
106
address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin ) {
107
if (is_abstract()) {
108
// The disassembler library was not loaded (yet),
109
// use AbstractDisassembler's decode method.
110
return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen());
111
}
112
113
// Currently, "special decoding" doesn't work when decoding error files.
114
// When decoding an instruction from a hs_err file, the given
115
// instruction address 'start' points to the instruction's virtual address
116
// which is not equal to the address where the instruction is located.
117
// Therefore, we will either crash or decode garbage.
118
if (is_decode_error_file()) {
119
return here;
120
}
121
122
//---< Decode some well-known "instructions" >---
123
124
address next;
125
uint32_t instruction = *(uint32_t*)here;
126
127
// Align at next tab position.
128
const uint tabspacing = 8;
129
const uint pos = st->position();
130
const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing;
131
st->fill_to(aligned_pos);
132
133
if (instruction == 0x0) {
134
st->print("illtrap .data 0x0");
135
next = here + Assembler::instr_len(here);
136
} else if (instruction == 0xbadbabe) {
137
st->print(".data 0xbadbabe");
138
next = here + Assembler::instr_len(here);
139
} else if (Assembler::is_endgroup(instruction)) {
140
st->print("endgroup");
141
next = here + Assembler::instr_len(here);
142
} else {
143
next = here;
144
}
145
return next;
146
}
147
148
// print annotations (instruction control bits)
149
void Disassembler::annotate(address here, outputStream* st) {
150
// Currently, annotation doesn't work when decoding error files.
151
// When decoding an instruction from a hs_err file, the given
152
// instruction address 'start' points to the instruction's virtual address
153
// which is not equal to the address where the instruction is located.
154
// Therefore, we will either crash or decode garbage.
155
if (is_decode_error_file()) {
156
return;
157
}
158
159
uint32_t instruction = *(uint32_t*)here;
160
161
// Align at next tab position.
162
const uint tabspacing = 8;
163
const uint pos = st->position();
164
const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing;
165
166
int stop_type = -1;
167
168
if (MacroAssembler::is_bcxx(instruction)) {
169
st->print(",bo=0b");
170
print_instruction_bits(st, instruction, 6, 10);
171
print_decoded_bo_bits(st, instruction, 10);
172
} else if (MacroAssembler::is_bctr(instruction) ||
173
MacroAssembler::is_bctrl(instruction) ||
174
MacroAssembler::is_bclr(instruction)) {
175
st->fill_to(aligned_pos);
176
st->print("bo=0b");
177
print_instruction_bits(st, instruction, 6, 10);
178
print_decoded_bo_bits(st, instruction, 10);
179
st->print(",bh=0b");
180
print_instruction_bits(st, instruction, 19, 20);
181
print_decoded_bh_bits(st, instruction, 20,
182
!(MacroAssembler::is_bctr(instruction) ||
183
MacroAssembler::is_bctrl(instruction)));
184
} else if (MacroAssembler::is_trap_null_check(instruction)) {
185
st->fill_to(aligned_pos + tabspacing);
186
st->print(";trap: null check");
187
} else if (MacroAssembler::is_trap_range_check(instruction)) {
188
st->fill_to(aligned_pos + tabspacing);
189
st->print(";trap: range check");
190
} else if (MacroAssembler::is_trap_ic_miss_check(instruction)) {
191
st->fill_to(aligned_pos + tabspacing);
192
st->print(";trap: ic miss check");
193
} else if ((stop_type = MacroAssembler::tdi_get_si16(instruction, Assembler::traptoUnconditional, 0)) != -1) {
194
bool msg_present = (stop_type & MacroAssembler::stop_msg_present);
195
stop_type = (stop_type &~ MacroAssembler::stop_msg_present);
196
const char **detail_msg_ptr = (const char**)(here + 4);
197
st->fill_to(aligned_pos + tabspacing);
198
st->print(";trap: stop type %d: %s", stop_type, msg_present ? *detail_msg_ptr : "no details provided");
199
}
200
}
201
202