2
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
25
#include "precompiled.hpp"
26
#include "asm/macroAssembler.hpp"
27
#include "code/relocInfo.hpp"
28
#include "memory/universe.hpp"
29
#include "nativeInst_x86.hpp"
30
#include "oops/compressedKlass.inline.hpp"
31
#include "oops/compressedOops.inline.hpp"
32
#include "oops/klass.inline.hpp"
33
#include "oops/oop.inline.hpp"
34
#include "runtime/safepoint.hpp"
35
#include "runtime/safepointMechanism.hpp"
36
#include "utilities/checkedCast.hpp"
39
void Relocation::pd_set_data_value(address x, bool verify_only) {
41
typedef Assembler::WhichOperand WhichOperand;
42
WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm, call32, narrow oop
43
assert(which == Assembler::disp32_operand ||
44
which == Assembler::narrow_oop_operand ||
45
which == Assembler::imm_operand, "format unpacks ok");
46
if (which == Assembler::imm_operand) {
48
guarantee(*pd_address_in_code() == x, "instructions must match");
50
*pd_address_in_code() = x;
52
} else if (which == Assembler::narrow_oop_operand) {
53
address disp = Assembler::locate_operand(addr(), which);
54
// both compressed oops and compressed classes look the same
55
if (CompressedOops::is_in((void*)x)) {
56
uint32_t encoded = CompressedOops::narrow_oop_value(cast_to_oop(x));
58
guarantee(*(uint32_t*) disp == encoded, "instructions must match");
60
*(int32_t*) disp = encoded;
64
guarantee(*(uint32_t*) disp == CompressedKlassPointers::encode((Klass*)x), "instructions must match");
66
*(int32_t*) disp = CompressedKlassPointers::encode((Klass*)x);
70
// Note: Use runtime_call_type relocations for call32_operand.
72
address disp = Assembler::locate_operand(ip, which);
73
address next_ip = Assembler::locate_next_instruction(ip);
75
guarantee(*(int32_t*) disp == (x - next_ip), "instructions must match");
77
*(int32_t*) disp = checked_cast<int32_t>(x - next_ip);
82
guarantee(*pd_address_in_code() == x, "instructions must match");
84
*pd_address_in_code() = x;
90
address Relocation::pd_call_destination(address orig_addr) {
92
if (orig_addr != nullptr) {
93
// We just moved this call instruction from orig_addr to addr().
94
// This means its target will appear to have grown by addr() - orig_addr.
95
adj = -( addr() - orig_addr );
97
NativeInstruction* ni = nativeInstruction_at(addr());
99
return nativeCall_at(addr())->destination() + adj;
100
} else if (ni->is_jump()) {
101
address dest = nativeJump_at(addr())->jump_destination();
102
if (dest == (address) -1) {
103
return addr(); // jump to self
106
} else if (ni->is_cond_jump()) {
107
return nativeGeneralJump_at(addr())->jump_destination() + adj;
108
} else if (ni->is_mov_literal64()) {
109
return (address) ((NativeMovConstReg*)ni)->data();
111
ShouldNotReachHere();
117
void Relocation::pd_set_call_destination(address x) {
118
NativeInstruction* ni = nativeInstruction_at(addr());
120
nativeCall_at(addr())->set_destination(x);
121
} else if (ni->is_jump()) {
122
NativeJump* nj = nativeJump_at(addr());
124
// Unresolved jumps are recognized by a destination of -1
125
// However 64bit can't actually produce such an address
126
// and encodes a jump to self but jump_destination will
127
// return a -1 as the signal. We must not relocate this
128
// jmp or the ic code will not see it as unresolved.
130
if (nj->jump_destination() == (address) -1) {
131
x = addr(); // jump to self
133
nj->set_jump_destination(x);
134
} else if (ni->is_cond_jump()) {
135
// %%%% kludge this, for now, until we get a jump_destination method
136
address old_dest = nativeGeneralJump_at(addr())->jump_destination();
137
address disp = Assembler::locate_operand(addr(), Assembler::call32_operand);
138
*(jint*)disp += checked_cast<jint>(x - old_dest);
139
} else if (ni->is_mov_literal64()) {
140
((NativeMovConstReg*)ni)->set_data((intptr_t)x);
142
ShouldNotReachHere();
147
address* Relocation::pd_address_in_code() {
148
// All embedded Intel addresses are stored in 32-bit words.
149
// Since the addr points at the start of the instruction,
150
// we must parse the instruction a bit to find the embedded word.
151
assert(is_data(), "must be a DataRelocation");
152
typedef Assembler::WhichOperand WhichOperand;
153
WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
155
assert(which == Assembler::disp32_operand ||
156
which == Assembler::call32_operand ||
157
which == Assembler::imm_operand, "format unpacks ok");
158
// The "address" in the code is a displacement can't return it as
159
// and address* since it is really a jint*
160
guarantee(which == Assembler::imm_operand, "must be immediate operand");
162
assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
164
return (address*) Assembler::locate_operand(addr(), which);
168
address Relocation::pd_get_address_from_code() {
170
// All embedded Intel addresses are stored in 32-bit words.
171
// Since the addr points at the start of the instruction,
172
// we must parse the instruction a bit to find the embedded word.
173
assert(is_data(), "must be a DataRelocation");
174
typedef Assembler::WhichOperand WhichOperand;
175
WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm/imm32
176
assert(which == Assembler::disp32_operand ||
177
which == Assembler::call32_operand ||
178
which == Assembler::imm_operand, "format unpacks ok");
179
if (which != Assembler::imm_operand) {
181
address disp = Assembler::locate_operand(ip, which);
182
address next_ip = Assembler::locate_next_instruction(ip);
183
address a = next_ip + *(int32_t*) disp;
187
return *pd_address_in_code();
190
void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
193
void metadata_Relocation::pd_fix_value(address x) {