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 }