relocInfo_x86.cpp revision 1879:f95d63e2154a
1/*
2 * Copyright (c) 1998, 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "asm/assembler.inline.hpp"
27#include "assembler_x86.inline.hpp"
28#include "code/relocInfo.hpp"
29#include "nativeInst_x86.hpp"
30#include "oops/oop.inline.hpp"
31#include "runtime/safepoint.hpp"
32
33
34void Relocation::pd_set_data_value(address x, intptr_t o) {
35#ifdef AMD64
36  x += o;
37  typedef Assembler::WhichOperand WhichOperand;
38  WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop
39  assert(which == Assembler::disp32_operand ||
40         which == Assembler::narrow_oop_operand ||
41         which == Assembler::imm_operand, "format unpacks ok");
42  if (which == Assembler::imm_operand) {
43    *pd_address_in_code() = x;
44  } else if (which == Assembler::narrow_oop_operand) {
45    address disp = Assembler::locate_operand(addr(), which);
46    *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
47  } else {
48    // Note:  Use runtime_call_type relocations for call32_operand.
49    address ip = addr();
50    address disp = Assembler::locate_operand(ip, which);
51    address next_ip = Assembler::locate_next_instruction(ip);
52    *(int32_t*) disp = x - next_ip;
53  }
54#else
55  *pd_address_in_code() = x + o;
56#endif // AMD64
57}
58
59
60address Relocation::pd_call_destination(address orig_addr) {
61  intptr_t adj = 0;
62  if (orig_addr != NULL) {
63    // We just moved this call instruction from orig_addr to addr().
64    // This means its target will appear to have grown by addr() - orig_addr.
65    adj = -( addr() - orig_addr );
66  }
67  NativeInstruction* ni = nativeInstruction_at(addr());
68  if (ni->is_call()) {
69    return nativeCall_at(addr())->destination() + adj;
70  } else if (ni->is_jump()) {
71    return nativeJump_at(addr())->jump_destination() + adj;
72  } else if (ni->is_cond_jump()) {
73    return nativeGeneralJump_at(addr())->jump_destination() + adj;
74  } else if (ni->is_mov_literal64()) {
75    return (address) ((NativeMovConstReg*)ni)->data();
76  } else {
77    ShouldNotReachHere();
78    return NULL;
79  }
80}
81
82
83void Relocation::pd_set_call_destination(address x) {
84  NativeInstruction* ni = nativeInstruction_at(addr());
85  if (ni->is_call()) {
86    nativeCall_at(addr())->set_destination(x);
87  } else if (ni->is_jump()) {
88    NativeJump* nj = nativeJump_at(addr());
89
90    // Unresolved jumps are recognized by a destination of -1
91    // However 64bit can't actually produce such an address
92    // and encodes a jump to self but jump_destination will
93    // return a -1 as the signal. We must not relocate this
94    // jmp or the ic code will not see it as unresolved.
95
96    if (nj->jump_destination() == (address) -1) {
97      x = addr(); // jump to self
98    }
99    nj->set_jump_destination(x);
100  } else if (ni->is_cond_jump()) {
101    // %%%% kludge this, for now, until we get a jump_destination method
102    address old_dest = nativeGeneralJump_at(addr())->jump_destination();
103    address disp = Assembler::locate_operand(addr(), Assembler::call32_operand);
104    *(jint*)disp += (x - old_dest);
105  } else if (ni->is_mov_literal64()) {
106    ((NativeMovConstReg*)ni)->set_data((intptr_t)x);
107  } else {
108    ShouldNotReachHere();
109  }
110}
111
112
113address* Relocation::pd_address_in_code() {
114  // All embedded Intel addresses are stored in 32-bit words.
115  // Since the addr points at the start of the instruction,
116  // we must parse the instruction a bit to find the embedded word.
117  assert(is_data(), "must be a DataRelocation");
118  typedef Assembler::WhichOperand WhichOperand;
119  WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
120#ifdef AMD64
121  assert(which == Assembler::disp32_operand ||
122         which == Assembler::call32_operand ||
123         which == Assembler::imm_operand, "format unpacks ok");
124  if (which != Assembler::imm_operand) {
125    // The "address" in the code is a displacement can't return it as
126    // and address* since it is really a jint*
127    ShouldNotReachHere();
128    return NULL;
129  }
130#else
131  assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
132#endif // AMD64
133  return (address*) Assembler::locate_operand(addr(), which);
134}
135
136
137address Relocation::pd_get_address_from_code() {
138#ifdef AMD64
139  // All embedded Intel addresses are stored in 32-bit words.
140  // Since the addr points at the start of the instruction,
141  // we must parse the instruction a bit to find the embedded word.
142  assert(is_data(), "must be a DataRelocation");
143  typedef Assembler::WhichOperand WhichOperand;
144  WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
145  assert(which == Assembler::disp32_operand ||
146         which == Assembler::call32_operand ||
147         which == Assembler::imm_operand, "format unpacks ok");
148  if (which != Assembler::imm_operand) {
149    address ip = addr();
150    address disp = Assembler::locate_operand(ip, which);
151    address next_ip = Assembler::locate_next_instruction(ip);
152    address a = next_ip + *(int32_t*) disp;
153    return a;
154  }
155#endif // AMD64
156  return *pd_address_in_code();
157}
158
159int Relocation::pd_breakpoint_size() {
160  // minimum breakpoint size, in short words
161  return NativeIllegalInstruction::instruction_size / sizeof(short);
162}
163
164void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) {
165  Untested("pd_swap_in_breakpoint");
166  if (instrs != NULL) {
167    assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data");
168    for (int i = 0; i < instrlen; i++) {
169      instrs[i] = ((short*)x)[i];
170    }
171  }
172  NativeIllegalInstruction::insert(x);
173}
174
175
176void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) {
177  Untested("pd_swap_out_breakpoint");
178  assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update");
179  NativeInstruction* ni = nativeInstruction_at(x);
180  *(short*)ni->addr_at(0) = instrs[0];
181}
182
183void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
184#ifdef _LP64
185  typedef Assembler::WhichOperand WhichOperand;
186  WhichOperand which = (WhichOperand) format();
187  // This format is imm but it is really disp32
188  which = Assembler::disp32_operand;
189  address orig_addr = old_addr_for(addr(), src, dest);
190  NativeInstruction* oni = nativeInstruction_at(orig_addr);
191  int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
192  // This poll_addr is incorrect by the size of the instruction it is irrelevant
193  intptr_t poll_addr = (intptr_t)oni + *orig_disp;
194
195  NativeInstruction* ni = nativeInstruction_at(addr());
196  intptr_t new_disp = poll_addr - (intptr_t) ni;
197
198  int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
199  * disp = (int32_t)new_disp;
200
201#endif // _LP64
202}
203
204void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
205#ifdef _LP64
206  typedef Assembler::WhichOperand WhichOperand;
207  WhichOperand which = (WhichOperand) format();
208  // This format is imm but it is really disp32
209  which = Assembler::disp32_operand;
210  address orig_addr = old_addr_for(addr(), src, dest);
211  NativeInstruction* oni = nativeInstruction_at(orig_addr);
212  int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
213  // This poll_addr is incorrect by the size of the instruction it is irrelevant
214  intptr_t poll_addr = (intptr_t)oni + *orig_disp;
215
216  NativeInstruction* ni = nativeInstruction_at(addr());
217  intptr_t new_disp = poll_addr - (intptr_t) ni;
218
219  int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
220  * disp = (int32_t)new_disp;
221#endif // _LP64
222}
223