1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)relocInfo_x86.cpp 1.19 07/09/17 09:28:01 JVM"
3 #endif
4 /*
5 * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 # include "incls/_precompiled.incl"
29 # include "incls/_relocInfo_x86.cpp.incl"
30
31
32 void Relocation::pd_set_data_value(address x, intptr_t o) {
33 #ifdef AMD64
34 x += o;
35 typedef Assembler::WhichOperand WhichOperand;
36 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32
37 assert(which == Assembler::disp32_operand ||
38 which == Assembler::imm64_operand, "format unpacks ok");
39 if (which == Assembler::imm64_operand) {
40 *pd_address_in_code() = x;
41 } else {
42 // Note: Use runtime_call_type relocations for call32_operand.
43 address ip = addr();
44 address disp = Assembler::locate_operand(ip, which);
45 address next_ip = Assembler::locate_next_instruction(ip);
46 *(int32_t*) disp = x - next_ip;
47 }
48 #else
49 *pd_address_in_code() = x + o;
50 #endif // AMD64
51 }
52
53
54 address Relocation::pd_call_destination(address orig_addr) {
55 intptr_t adj = 0;
56 if (orig_addr != NULL) {
57 // We just moved this call instruction from orig_addr to addr().
58 // This means its target will appear to have grown by addr() - orig_addr.
59 adj = -( addr() - orig_addr );
60 }
63 return nativeCall_at(addr())->destination() + adj;
64 } else if (ni->is_jump()) {
65 return nativeJump_at(addr())->jump_destination() + adj;
66 } else if (ni->is_cond_jump()) {
67 return nativeGeneralJump_at(addr())->jump_destination() + adj;
68 } else if (ni->is_mov_literal64()) {
69 return (address) ((NativeMovConstReg*)ni)->data();
70 } else {
71 ShouldNotReachHere();
72 return NULL;
73 }
74 }
75
76
77 void Relocation::pd_set_call_destination(address x) {
78 NativeInstruction* ni = nativeInstruction_at(addr());
79 if (ni->is_call()) {
80 nativeCall_at(addr())->set_destination(x);
81 } else if (ni->is_jump()) {
82 NativeJump* nj = nativeJump_at(addr());
83 #ifdef AMD64
84 if (nj->jump_destination() == (address) -1) {
85 x = (address) -1; // retain jump to self
86 }
87 #endif // AMD64
88 nj->set_jump_destination(x);
89 } else if (ni->is_cond_jump()) {
90 // %%%% kludge this, for now, until we get a jump_destination method
91 address old_dest = nativeGeneralJump_at(addr())->jump_destination();
92 address disp = Assembler::locate_operand(addr(), Assembler::call32_operand);
93 *(jint*)disp += (x - old_dest);
94 } else if (ni->is_mov_literal64()) {
95 ((NativeMovConstReg*)ni)->set_data((intptr_t)x);
96 } else {
97 ShouldNotReachHere();
98 }
99 }
100
101
102 address* Relocation::pd_address_in_code() {
103 // All embedded Intel addresses are stored in 32-bit words.
104 // Since the addr points at the start of the instruction,
105 // we must parse the instruction a bit to find the embedded word.
106 assert(is_data(), "must be a DataRelocation");
107 typedef Assembler::WhichOperand WhichOperand;
108 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32
109 #ifdef AMD64
110 assert(which == Assembler::disp32_operand ||
111 which == Assembler::call32_operand ||
112 which == Assembler::imm64_operand, "format unpacks ok");
113 if (which != Assembler::imm64_operand) {
114 // The "address" in the code is a displacement can't return it as
115 // and address* since it is really a jint*
116 ShouldNotReachHere();
117 return NULL;
118 }
119 #else
120 assert(which == Assembler::disp32_operand || which == Assembler::imm32_operand, "format unpacks ok");
121 #endif // AMD64
122 return (address*) Assembler::locate_operand(addr(), which);
123 }
124
125
126 address Relocation::pd_get_address_from_code() {
127 #ifdef AMD64
128 // All embedded Intel addresses are stored in 32-bit words.
129 // Since the addr points at the start of the instruction,
130 // we must parse the instruction a bit to find the embedded word.
131 assert(is_data(), "must be a DataRelocation");
132 typedef Assembler::WhichOperand WhichOperand;
133 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64/imm32
134 assert(which == Assembler::disp32_operand ||
135 which == Assembler::call32_operand ||
136 which == Assembler::imm64_operand, "format unpacks ok");
137 if (which != Assembler::imm64_operand) {
138 address ip = addr();
139 address disp = Assembler::locate_operand(ip, which);
140 address next_ip = Assembler::locate_next_instruction(ip);
141 address a = next_ip + *(int32_t*) disp;
142 return a;
143 }
144 #endif // AMD64
145 return *pd_address_in_code();
146 }
147
148 int Relocation::pd_breakpoint_size() {
149 // minimum breakpoint size, in short words
150 return NativeIllegalInstruction::instruction_size / sizeof(short);
151 }
152
153 void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) {
154 Untested("pd_swap_in_breakpoint");
155 if (instrs != NULL) {
156 assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data");
157 for (int i = 0; i < instrlen; i++) {
158 instrs[i] = ((short*)x)[i];
159 }
160 }
161 NativeIllegalInstruction::insert(x);
162 }
163
164
165 void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) {
166 Untested("pd_swap_out_breakpoint");
167 assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update");
168 NativeInstruction* ni = nativeInstruction_at(x);
169 *(short*)ni->addr_at(0) = instrs[0];
170 }
|
1 /*
2 * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 # include "incls/_precompiled.incl"
26 # include "incls/_relocInfo_x86.cpp.incl"
27
28
29 void Relocation::pd_set_data_value(address x, intptr_t o) {
30 #ifdef AMD64
31 x += o;
32 typedef Assembler::WhichOperand WhichOperand;
33 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop
34 assert(which == Assembler::disp32_operand ||
35 which == Assembler::narrow_oop_operand ||
36 which == Assembler::imm_operand, "format unpacks ok");
37 if (which == Assembler::imm_operand) {
38 *pd_address_in_code() = x;
39 } else if (which == Assembler::narrow_oop_operand) {
40 address disp = Assembler::locate_operand(addr(), which);
41 *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
42 } else {
43 // Note: Use runtime_call_type relocations for call32_operand.
44 address ip = addr();
45 address disp = Assembler::locate_operand(ip, which);
46 address next_ip = Assembler::locate_next_instruction(ip);
47 *(int32_t*) disp = x - next_ip;
48 }
49 #else
50 *pd_address_in_code() = x + o;
51 #endif // AMD64
52 }
53
54
55 address Relocation::pd_call_destination(address orig_addr) {
56 intptr_t adj = 0;
57 if (orig_addr != NULL) {
58 // We just moved this call instruction from orig_addr to addr().
59 // This means its target will appear to have grown by addr() - orig_addr.
60 adj = -( addr() - orig_addr );
61 }
64 return nativeCall_at(addr())->destination() + adj;
65 } else if (ni->is_jump()) {
66 return nativeJump_at(addr())->jump_destination() + adj;
67 } else if (ni->is_cond_jump()) {
68 return nativeGeneralJump_at(addr())->jump_destination() + adj;
69 } else if (ni->is_mov_literal64()) {
70 return (address) ((NativeMovConstReg*)ni)->data();
71 } else {
72 ShouldNotReachHere();
73 return NULL;
74 }
75 }
76
77
78 void Relocation::pd_set_call_destination(address x) {
79 NativeInstruction* ni = nativeInstruction_at(addr());
80 if (ni->is_call()) {
81 nativeCall_at(addr())->set_destination(x);
82 } else if (ni->is_jump()) {
83 NativeJump* nj = nativeJump_at(addr());
84
85 // Unresolved jumps are recognized by a destination of -1
86 // However 64bit can't actually produce such an address
87 // and encodes a jump to self but jump_destination will
88 // return a -1 as the signal. We must not relocate this
89 // jmp or the ic code will not see it as unresolved.
90
91 if (nj->jump_destination() == (address) -1) {
92 x = addr(); // jump to self
93 }
94 nj->set_jump_destination(x);
95 } else if (ni->is_cond_jump()) {
96 // %%%% kludge this, for now, until we get a jump_destination method
97 address old_dest = nativeGeneralJump_at(addr())->jump_destination();
98 address disp = Assembler::locate_operand(addr(), Assembler::call32_operand);
99 *(jint*)disp += (x - old_dest);
100 } else if (ni->is_mov_literal64()) {
101 ((NativeMovConstReg*)ni)->set_data((intptr_t)x);
102 } else {
103 ShouldNotReachHere();
104 }
105 }
106
107
108 address* Relocation::pd_address_in_code() {
109 // All embedded Intel addresses are stored in 32-bit words.
110 // Since the addr points at the start of the instruction,
111 // we must parse the instruction a bit to find the embedded word.
112 assert(is_data(), "must be a DataRelocation");
113 typedef Assembler::WhichOperand WhichOperand;
114 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
115 #ifdef AMD64
116 assert(which == Assembler::disp32_operand ||
117 which == Assembler::call32_operand ||
118 which == Assembler::imm_operand, "format unpacks ok");
119 if (which != Assembler::imm_operand) {
120 // The "address" in the code is a displacement can't return it as
121 // and address* since it is really a jint*
122 ShouldNotReachHere();
123 return NULL;
124 }
125 #else
126 assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
127 #endif // AMD64
128 return (address*) Assembler::locate_operand(addr(), which);
129 }
130
131
132 address Relocation::pd_get_address_from_code() {
133 #ifdef AMD64
134 // All embedded Intel addresses are stored in 32-bit words.
135 // Since the addr points at the start of the instruction,
136 // we must parse the instruction a bit to find the embedded word.
137 assert(is_data(), "must be a DataRelocation");
138 typedef Assembler::WhichOperand WhichOperand;
139 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
140 assert(which == Assembler::disp32_operand ||
141 which == Assembler::call32_operand ||
142 which == Assembler::imm_operand, "format unpacks ok");
143 if (which != Assembler::imm_operand) {
144 address ip = addr();
145 address disp = Assembler::locate_operand(ip, which);
146 address next_ip = Assembler::locate_next_instruction(ip);
147 address a = next_ip + *(int32_t*) disp;
148 return a;
149 }
150 #endif // AMD64
151 return *pd_address_in_code();
152 }
153
154 int Relocation::pd_breakpoint_size() {
155 // minimum breakpoint size, in short words
156 return NativeIllegalInstruction::instruction_size / sizeof(short);
157 }
158
159 void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) {
160 Untested("pd_swap_in_breakpoint");
161 if (instrs != NULL) {
162 assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data");
163 for (int i = 0; i < instrlen; i++) {
164 instrs[i] = ((short*)x)[i];
165 }
166 }
167 NativeIllegalInstruction::insert(x);
168 }
169
170
171 void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) {
172 Untested("pd_swap_out_breakpoint");
173 assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update");
174 NativeInstruction* ni = nativeInstruction_at(x);
175 *(short*)ni->addr_at(0) = instrs[0];
176 }
177
178 void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
179 #ifdef _LP64
180 typedef Assembler::WhichOperand WhichOperand;
181 WhichOperand which = (WhichOperand) format();
182 // This format is imm but it is really disp32
183 which = Assembler::disp32_operand;
184 address orig_addr = old_addr_for(addr(), src, dest);
185 NativeInstruction* oni = nativeInstruction_at(orig_addr);
186 int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
187 // This poll_addr is incorrect by the size of the instruction it is irrelevant
188 intptr_t poll_addr = (intptr_t)oni + *orig_disp;
189
190 NativeInstruction* ni = nativeInstruction_at(addr());
191 intptr_t new_disp = poll_addr - (intptr_t) ni;
192
193 int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
194 * disp = (int32_t)new_disp;
195
196 #endif // _LP64
197 }
198
199 void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
200 #ifdef _LP64
201 typedef Assembler::WhichOperand WhichOperand;
202 WhichOperand which = (WhichOperand) format();
203 // This format is imm but it is really disp32
204 which = Assembler::disp32_operand;
205 address orig_addr = old_addr_for(addr(), src, dest);
206 NativeInstruction* oni = nativeInstruction_at(orig_addr);
207 int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
208 // This poll_addr is incorrect by the size of the instruction it is irrelevant
209 intptr_t poll_addr = (intptr_t)oni + *orig_disp;
210
211 NativeInstruction* ni = nativeInstruction_at(addr());
212 intptr_t new_disp = poll_addr - (intptr_t) ni;
213
214 int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
215 * disp = (int32_t)new_disp;
216 #endif // _LP64
217 }
|