1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/x86/vm/relocInfo_x86.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,167 @@ 1.4 +/* 1.5 + * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_relocInfo_x86.cpp.incl" 1.30 + 1.31 + 1.32 +void Relocation::pd_set_data_value(address x, intptr_t o) { 1.33 +#ifdef AMD64 1.34 + x += o; 1.35 + typedef Assembler::WhichOperand WhichOperand; 1.36 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32 1.37 + assert(which == Assembler::disp32_operand || 1.38 + which == Assembler::imm64_operand, "format unpacks ok"); 1.39 + if (which == Assembler::imm64_operand) { 1.40 + *pd_address_in_code() = x; 1.41 + } else { 1.42 + // Note: Use runtime_call_type relocations for call32_operand. 1.43 + address ip = addr(); 1.44 + address disp = Assembler::locate_operand(ip, which); 1.45 + address next_ip = Assembler::locate_next_instruction(ip); 1.46 + *(int32_t*) disp = x - next_ip; 1.47 + } 1.48 +#else 1.49 + *pd_address_in_code() = x + o; 1.50 +#endif // AMD64 1.51 +} 1.52 + 1.53 + 1.54 +address Relocation::pd_call_destination(address orig_addr) { 1.55 + intptr_t adj = 0; 1.56 + if (orig_addr != NULL) { 1.57 + // We just moved this call instruction from orig_addr to addr(). 1.58 + // This means its target will appear to have grown by addr() - orig_addr. 1.59 + adj = -( addr() - orig_addr ); 1.60 + } 1.61 + NativeInstruction* ni = nativeInstruction_at(addr()); 1.62 + if (ni->is_call()) { 1.63 + return nativeCall_at(addr())->destination() + adj; 1.64 + } else if (ni->is_jump()) { 1.65 + return nativeJump_at(addr())->jump_destination() + adj; 1.66 + } else if (ni->is_cond_jump()) { 1.67 + return nativeGeneralJump_at(addr())->jump_destination() + adj; 1.68 + } else if (ni->is_mov_literal64()) { 1.69 + return (address) ((NativeMovConstReg*)ni)->data(); 1.70 + } else { 1.71 + ShouldNotReachHere(); 1.72 + return NULL; 1.73 + } 1.74 +} 1.75 + 1.76 + 1.77 +void Relocation::pd_set_call_destination(address x) { 1.78 + NativeInstruction* ni = nativeInstruction_at(addr()); 1.79 + if (ni->is_call()) { 1.80 + nativeCall_at(addr())->set_destination(x); 1.81 + } else if (ni->is_jump()) { 1.82 + NativeJump* nj = nativeJump_at(addr()); 1.83 +#ifdef AMD64 1.84 + if (nj->jump_destination() == (address) -1) { 1.85 + x = (address) -1; // retain jump to self 1.86 + } 1.87 +#endif // AMD64 1.88 + nj->set_jump_destination(x); 1.89 + } else if (ni->is_cond_jump()) { 1.90 + // %%%% kludge this, for now, until we get a jump_destination method 1.91 + address old_dest = nativeGeneralJump_at(addr())->jump_destination(); 1.92 + address disp = Assembler::locate_operand(addr(), Assembler::call32_operand); 1.93 + *(jint*)disp += (x - old_dest); 1.94 + } else if (ni->is_mov_literal64()) { 1.95 + ((NativeMovConstReg*)ni)->set_data((intptr_t)x); 1.96 + } else { 1.97 + ShouldNotReachHere(); 1.98 + } 1.99 +} 1.100 + 1.101 + 1.102 +address* Relocation::pd_address_in_code() { 1.103 + // All embedded Intel addresses are stored in 32-bit words. 1.104 + // Since the addr points at the start of the instruction, 1.105 + // we must parse the instruction a bit to find the embedded word. 1.106 + assert(is_data(), "must be a DataRelocation"); 1.107 + typedef Assembler::WhichOperand WhichOperand; 1.108 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32 1.109 +#ifdef AMD64 1.110 + assert(which == Assembler::disp32_operand || 1.111 + which == Assembler::call32_operand || 1.112 + which == Assembler::imm64_operand, "format unpacks ok"); 1.113 + if (which != Assembler::imm64_operand) { 1.114 + // The "address" in the code is a displacement can't return it as 1.115 + // and address* since it is really a jint* 1.116 + ShouldNotReachHere(); 1.117 + return NULL; 1.118 + } 1.119 +#else 1.120 + assert(which == Assembler::disp32_operand || which == Assembler::imm32_operand, "format unpacks ok"); 1.121 +#endif // AMD64 1.122 + return (address*) Assembler::locate_operand(addr(), which); 1.123 +} 1.124 + 1.125 + 1.126 +address Relocation::pd_get_address_from_code() { 1.127 +#ifdef AMD64 1.128 + // All embedded Intel addresses are stored in 32-bit words. 1.129 + // Since the addr points at the start of the instruction, 1.130 + // we must parse the instruction a bit to find the embedded word. 1.131 + assert(is_data(), "must be a DataRelocation"); 1.132 + typedef Assembler::WhichOperand WhichOperand; 1.133 + WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32 1.134 + assert(which == Assembler::disp32_operand || 1.135 + which == Assembler::call32_operand || 1.136 + which == Assembler::imm64_operand, "format unpacks ok"); 1.137 + if (which != Assembler::imm64_operand) { 1.138 + address ip = addr(); 1.139 + address disp = Assembler::locate_operand(ip, which); 1.140 + address next_ip = Assembler::locate_next_instruction(ip); 1.141 + address a = next_ip + *(int32_t*) disp; 1.142 + return a; 1.143 + } 1.144 +#endif // AMD64 1.145 + return *pd_address_in_code(); 1.146 +} 1.147 + 1.148 +int Relocation::pd_breakpoint_size() { 1.149 + // minimum breakpoint size, in short words 1.150 + return NativeIllegalInstruction::instruction_size / sizeof(short); 1.151 +} 1.152 + 1.153 +void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) { 1.154 + Untested("pd_swap_in_breakpoint"); 1.155 + if (instrs != NULL) { 1.156 + assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data"); 1.157 + for (int i = 0; i < instrlen; i++) { 1.158 + instrs[i] = ((short*)x)[i]; 1.159 + } 1.160 + } 1.161 + NativeIllegalInstruction::insert(x); 1.162 +} 1.163 + 1.164 + 1.165 +void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) { 1.166 + Untested("pd_swap_out_breakpoint"); 1.167 + assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update"); 1.168 + NativeInstruction* ni = nativeInstruction_at(x); 1.169 + *(short*)ni->addr_at(0) = instrs[0]; 1.170 +}