23 */ 24 25 #include "precompiled.hpp" 26 #include "asm/macroAssembler.hpp" 27 #include "code/compiledIC.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "nativeInst_x86.hpp" 30 #include "oops/oop.inline.hpp" 31 #include "runtime/handles.hpp" 32 #include "runtime/sharedRuntime.hpp" 33 #include "runtime/stubRoutines.hpp" 34 #include "utilities/ostream.hpp" 35 #ifdef COMPILER1 36 #include "c1/c1_Runtime1.hpp" 37 #endif 38 39 void NativeInstruction::wrote(int offset) { 40 ICache::invalidate_word(addr_at(offset)); 41 } 42 43 void NativeLoadGot::report_and_fail() const { 44 tty->print_cr("Addr: " INTPTR_FORMAT, p2i(instruction_address())); 45 fatal("not a indirect rip mov to rbx"); 46 } 47 48 void NativeLoadGot::verify() const { 49 if (has_rex) { 50 int rex = ubyte_at(0); 51 if (rex != rex_prefix) { 52 report_and_fail(); 53 } 54 } 55 56 int inst = ubyte_at(rex_size); 57 if (inst != instruction_code) { 58 report_and_fail(); 59 } 60 int modrm = ubyte_at(rex_size + 1); 61 if (modrm != modrm_rbx_code && modrm != modrm_rax_code) { 62 report_and_fail(); 63 } 64 } 65 66 intptr_t NativeLoadGot::data() const { 67 return *(intptr_t *) got_address(); 68 } 69 70 address NativePltCall::destination() const { 71 NativeGotJump* jump = nativeGotJump_at(plt_jump()); 72 return jump->destination(); 73 } 74 75 address NativePltCall::plt_entry() const { 76 return return_address() + displacement(); 77 } 78 79 address NativePltCall::plt_jump() const { 80 address entry = plt_entry(); 81 // Virtual PLT code has move instruction first 82 if (((NativeGotJump*)entry)->is_GotJump()) { 83 return entry; 84 } else { 132 NativeGotJump* jump = nativeGotJump_at(method_loader->next_instruction_address()); 133 method_loader->set_data(0); 134 jump->set_jump_destination((address)-1); 135 } 136 137 void NativePltCall::verify() const { 138 // Make sure code pattern is actually a call rip+off32 instruction. 139 int inst = ubyte_at(0); 140 if (inst != instruction_code) { 141 tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()), 142 inst); 143 fatal("not a call rip+off32"); 144 } 145 } 146 147 address NativeGotJump::destination() const { 148 address *got_entry = (address *) got_address(); 149 return *got_entry; 150 } 151 152 void NativeGotJump::verify() const { 153 int inst = ubyte_at(0); 154 if (inst != instruction_code) { 155 tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()), 156 inst); 157 fatal("not a indirect rip jump"); 158 } 159 } 160 161 void NativeCall::verify() { 162 // Make sure code pattern is actually a call imm32 instruction. 163 int inst = ubyte_at(0); 164 if (inst != instruction_code) { 165 tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()), 166 inst); 167 fatal("not a call disp32"); 168 } 169 } 170 171 address NativeCall::destination() const { 172 // Getting the destination of a call isn't safe because that call can 173 // be getting patched while you're calling this. There's only special 174 // places where this can be called but not automatically verifiable by 175 // checking which locks are held. The solution is true atomic patching 176 // on x86, nyi. 177 return return_address() + displacement(); 178 } 179 | 23 */ 24 25 #include "precompiled.hpp" 26 #include "asm/macroAssembler.hpp" 27 #include "code/compiledIC.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "nativeInst_x86.hpp" 30 #include "oops/oop.inline.hpp" 31 #include "runtime/handles.hpp" 32 #include "runtime/sharedRuntime.hpp" 33 #include "runtime/stubRoutines.hpp" 34 #include "utilities/ostream.hpp" 35 #ifdef COMPILER1 36 #include "c1/c1_Runtime1.hpp" 37 #endif 38 39 void NativeInstruction::wrote(int offset) { 40 ICache::invalidate_word(addr_at(offset)); 41 } 42 43 #ifdef ASSERT 44 void NativeLoadGot::report_and_fail() const { 45 tty->print_cr("Addr: " INTPTR_FORMAT " Code: %x %x %x", p2i(instruction_address()), 46 (has_rex ? ubyte_at(0) : 0), ubyte_at(rex_size), ubyte_at(rex_size + 1)); 47 fatal("not a indirect rip mov to rbx"); 48 } 49 50 void NativeLoadGot::verify() const { 51 if (has_rex) { 52 int rex = ubyte_at(0); 53 if (rex != rex_prefix && rex != rex_b_prefix) { 54 report_and_fail(); 55 } 56 } 57 58 int inst = ubyte_at(rex_size); 59 if (inst != instruction_code) { 60 report_and_fail(); 61 } 62 int modrm = ubyte_at(rex_size + 1); 63 if (modrm != modrm_rbx_code && modrm != modrm_rax_code) { 64 report_and_fail(); 65 } 66 } 67 #endif 68 69 intptr_t NativeLoadGot::data() const { 70 return *(intptr_t *) got_address(); 71 } 72 73 address NativePltCall::destination() const { 74 NativeGotJump* jump = nativeGotJump_at(plt_jump()); 75 return jump->destination(); 76 } 77 78 address NativePltCall::plt_entry() const { 79 return return_address() + displacement(); 80 } 81 82 address NativePltCall::plt_jump() const { 83 address entry = plt_entry(); 84 // Virtual PLT code has move instruction first 85 if (((NativeGotJump*)entry)->is_GotJump()) { 86 return entry; 87 } else { 135 NativeGotJump* jump = nativeGotJump_at(method_loader->next_instruction_address()); 136 method_loader->set_data(0); 137 jump->set_jump_destination((address)-1); 138 } 139 140 void NativePltCall::verify() const { 141 // Make sure code pattern is actually a call rip+off32 instruction. 142 int inst = ubyte_at(0); 143 if (inst != instruction_code) { 144 tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()), 145 inst); 146 fatal("not a call rip+off32"); 147 } 148 } 149 150 address NativeGotJump::destination() const { 151 address *got_entry = (address *) got_address(); 152 return *got_entry; 153 } 154 155 #ifdef ASSERT 156 void NativeGotJump::report_and_fail() const { 157 tty->print_cr("Addr: " INTPTR_FORMAT " Code: %x %x %x", p2i(instruction_address()), 158 (has_rex() ? ubyte_at(0) : 0), ubyte_at(rex_size()), ubyte_at(rex_size() + 1)); 159 fatal("not a indirect rip jump"); 160 } 161 162 void NativeGotJump::verify() const { 163 if (has_rex()) { 164 int rex = ubyte_at(0); 165 if (rex != rex_prefix) { 166 report_and_fail(); 167 } 168 } 169 int inst = ubyte_at(rex_size()); 170 if (inst != instruction_code) { 171 report_and_fail(); 172 } 173 int modrm = ubyte_at(rex_size() + 1); 174 if (modrm != modrm_code) { 175 report_and_fail(); 176 } 177 } 178 #endif 179 180 void NativeCall::verify() { 181 // Make sure code pattern is actually a call imm32 instruction. 182 int inst = ubyte_at(0); 183 if (inst != instruction_code) { 184 tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()), 185 inst); 186 fatal("not a call disp32"); 187 } 188 } 189 190 address NativeCall::destination() const { 191 // Getting the destination of a call isn't safe because that call can 192 // be getting patched while you're calling this. There's only special 193 // places where this can be called but not automatically verifiable by 194 // checking which locks are held. The solution is true atomic patching 195 // on x86, nyi. 196 return return_address() + displacement(); 197 } 198 |