|
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 "depChecker_ppc.hpp" |
|
30 #include "gc/cms/concurrentMarkSweepGeneration.inline.hpp" |
|
31 #include "gc/cms/parOopClosures.inline.hpp" |
|
32 #include "gc/shared/collectedHeap.hpp" |
|
33 #include "gc/shared/cardTableBarrierSet.hpp" |
|
34 #include "gc/shared/genOopClosures.inline.hpp" |
|
35 #include "oops/oop.inline.hpp" |
|
36 #include "runtime/handles.inline.hpp" |
|
37 #include "runtime/stubCodeGenerator.hpp" |
|
38 #include "runtime/stubRoutines.hpp" |
|
39 |
|
40 // Macro to print instruction bits. |
|
41 // numbering of instruction bits on ppc64 is (highest) 0 1 ... 30 31 (lowest). |
|
42 #define print_instruction_bits(st, instruction, start_bit, end_bit) \ |
|
43 { assert((start_bit) <= (end_bit), "sanity check"); \ |
|
44 for (int i=(31-(start_bit));i>=(31-(end_bit));i--) { \ |
|
45 (st)->print("%d", ((instruction) >> i) & 0x1); \ |
|
46 } \ |
|
47 } |
|
48 |
|
49 // Macro to decode "bo" instruction bits. |
|
50 #define print_decoded_bo_bits(env, instruction, end_bit) \ |
|
51 { int bo_bits = (instruction >> (31 - (end_bit))) & 0x1f; \ |
|
52 if ( ((bo_bits & 0x1c) == 0x4) || ((bo_bits & 0x1c) == 0xc) ) { \ |
|
53 switch (bo_bits & 0x3) { \ |
|
54 case (0 << 1) | (0 << 0): env->print("[no_hint]"); break; \ |
|
55 case (0 << 1) | (1 << 0): env->print("[reserved]"); break; \ |
|
56 case (1 << 1) | (0 << 0): env->print("[not_taken]"); break; \ |
|
57 case (1 << 1) | (1 << 0): env->print("[taken]"); break; \ |
|
58 default: break; \ |
|
59 } \ |
|
60 } else if ( ((bo_bits & 0x14) == 0x10) ) { \ |
|
61 switch (bo_bits & 0x9) { \ |
|
62 case (0 << 3) | (0 << 0): env->print("[no_hint]"); break; \ |
|
63 case (0 << 3) | (1 << 0): env->print("[reserved]"); break; \ |
|
64 case (1 << 3) | (0 << 0): env->print("[not_taken]"); break; \ |
|
65 case (1 << 3) | (1 << 0): env->print("[taken]"); break; \ |
|
66 default: break; \ |
|
67 } \ |
|
68 } \ |
|
69 } |
|
70 |
|
71 // Macro to decode "bh" instruction bits. |
|
72 #define print_decoded_bh_bits(env, instruction, end_bit, is_bclr) \ |
|
73 { int bh_bits = (instruction >> (31 - (end_bit))) & 0x3; \ |
|
74 if (is_bclr) { \ |
|
75 switch (bh_bits) { \ |
|
76 case (0 << 1) | (0 << 0): env->print("[subroutine_return]"); break; \ |
|
77 case (0 << 1) | (1 << 0): env->print("[not_return_but_same]"); break; \ |
|
78 case (1 << 1) | (0 << 0): env->print("[reserved]"); break; \ |
|
79 case (1 << 1) | (1 << 0): env->print("[not_predictable]"); break; \ |
|
80 default: break; \ |
|
81 } \ |
|
82 } else { \ |
|
83 switch (bh_bits) { \ |
|
84 case (0 << 1) | (0 << 0): env->print("[not_return_but_same]"); break; \ |
|
85 case (0 << 1) | (1 << 0): env->print("[reserved]"); break; \ |
|
86 case (1 << 1) | (0 << 0): env->print("[reserved]"); break; \ |
|
87 case (1 << 1) | (1 << 0): env->print("[not_predictable]"); break; \ |
|
88 default: break; \ |
|
89 } \ |
|
90 } \ |
|
91 } |
|
92 |
|
93 address Disassembler::find_prev_instr(address here, int n_instr) { |
|
94 if (!os::is_readable_pointer(here)) return NULL; // obviously a bad location to decode |
|
95 |
|
96 // Find most distant possible starting point. |
|
97 // Narrow down because we don't want to SEGV while printing. |
|
98 address start = here - n_instr*Assembler::instr_maxlen(); // starting point can't be further away. |
|
99 while ((start < here) && !os::is_readable_range(start, here)) { |
|
100 start = align_down(start, os::min_page_size()) + os::min_page_size(); |
|
101 } |
|
102 if (start >= here) { |
|
103 // Strange. Can only happen with here on page boundary. |
|
104 return NULL; |
|
105 } |
|
106 return start; |
|
107 } |
|
108 |
|
109 address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin ) { |
|
110 if (is_abstract()) { |
|
111 // The disassembler library was not loaded (yet), |
|
112 // use AbstractDisassembler's decode method. |
|
113 return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen()); |
|
114 } |
|
115 |
|
116 // Currently, "special decoding" doesn't work when decoding error files. |
|
117 // When decoding an instruction from a hs_err file, the given |
|
118 // instruction address 'start' points to the instruction's virtual address |
|
119 // which is not equal to the address where the instruction is located. |
|
120 // Therefore, we will either crash or decode garbage. |
|
121 if (is_decode_error_file()) { |
|
122 return here; |
|
123 } |
|
124 |
|
125 //---< Decode some well-known "instructions" >--- |
|
126 |
|
127 address next; |
|
128 uint32_t instruction = *(uint32_t*)here; |
|
129 |
|
130 // Align at next tab position. |
|
131 const uint tabspacing = 8; |
|
132 const uint pos = st->position(); |
|
133 const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing; |
|
134 st->fill_to(aligned_pos); |
|
135 |
|
136 if (instruction == 0x0) { |
|
137 st->print("illtrap .data 0x0"); |
|
138 next = here + Assembler::instr_len(here); |
|
139 } else if (instruction == 0xbadbabe) { |
|
140 st->print(".data 0xbadbabe"); |
|
141 next = here + Assembler::instr_len(here); |
|
142 } else if (Assembler::is_endgroup(instruction)) { |
|
143 st->print("endgroup"); |
|
144 next = here + Assembler::instr_len(here); |
|
145 } else { |
|
146 next = here; |
|
147 } |
|
148 return next; |
|
149 } |
|
150 |
|
151 // print annotations (instruction control bits) |
|
152 void Disassembler::annotate(address here, outputStream* st) { |
|
153 // Currently, annotation doesn't work when decoding error files. |
|
154 // When decoding an instruction from a hs_err file, the given |
|
155 // instruction address 'start' points to the instruction's virtual address |
|
156 // which is not equal to the address where the instruction is located. |
|
157 // Therefore, we will either crash or decode garbage. |
|
158 if (is_decode_error_file()) { |
|
159 return; |
|
160 } |
|
161 |
|
162 uint32_t instruction = *(uint32_t*)here; |
|
163 |
|
164 // Align at next tab position. |
|
165 const uint tabspacing = 8; |
|
166 const uint pos = st->position(); |
|
167 const uint aligned_pos = ((pos+tabspacing-1)/tabspacing)*tabspacing; |
|
168 |
|
169 if (MacroAssembler::is_bcxx(instruction)) { |
|
170 st->print(",bo=0b"); |
|
171 print_instruction_bits(st, instruction, 6, 10); |
|
172 print_decoded_bo_bits(st, instruction, 10); |
|
173 } else if (MacroAssembler::is_bctr(instruction) || |
|
174 MacroAssembler::is_bctrl(instruction) || |
|
175 MacroAssembler::is_bclr(instruction)) { |
|
176 st->fill_to(aligned_pos); |
|
177 st->print("bo=0b"); |
|
178 print_instruction_bits(st, instruction, 6, 10); |
|
179 print_decoded_bo_bits(st, instruction, 10); |
|
180 st->print(",bh=0b"); |
|
181 print_instruction_bits(st, instruction, 19, 20); |
|
182 print_decoded_bh_bits(st, instruction, 20, |
|
183 !(MacroAssembler::is_bctr(instruction) || |
|
184 MacroAssembler::is_bctrl(instruction))); |
|
185 } else if (MacroAssembler::is_trap_should_not_reach_here(instruction)) { |
|
186 st->fill_to(aligned_pos + tabspacing); |
|
187 st->print(";trap: should not reach here"); |
|
188 } else if (MacroAssembler::is_trap_null_check(instruction)) { |
|
189 st->fill_to(aligned_pos + tabspacing); |
|
190 st->print(";trap: null check"); |
|
191 } else if (MacroAssembler::is_trap_range_check(instruction)) { |
|
192 st->fill_to(aligned_pos + tabspacing); |
|
193 st->print(";trap: range check"); |
|
194 } else if (MacroAssembler::is_trap_ic_miss_check(instruction)) { |
|
195 st->fill_to(aligned_pos + tabspacing); |
|
196 st->print(";trap: ic miss check"); |
|
197 } else if (MacroAssembler::is_trap_zombie_not_entrant(instruction)) { |
|
198 st->fill_to(aligned_pos + tabspacing); |
|
199 st->print(";trap: zombie"); |
|
200 } |
|
201 } |