jdk

Форк
0
/
relocInfo_x86.cpp 
194 строки · 7.2 Кб
1
/*
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.
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/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"
37

38

39
void Relocation::pd_set_data_value(address x, bool verify_only) {
40
#ifdef AMD64
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) {
47
    if (verify_only) {
48
      guarantee(*pd_address_in_code() == x, "instructions must match");
49
    } else {
50
      *pd_address_in_code() = x;
51
    }
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));
57
      if (verify_only) {
58
        guarantee(*(uint32_t*) disp == encoded, "instructions must match");
59
      } else {
60
        *(int32_t*) disp = encoded;
61
      }
62
    } else {
63
      if (verify_only) {
64
        guarantee(*(uint32_t*) disp == CompressedKlassPointers::encode((Klass*)x), "instructions must match");
65
      } else {
66
        *(int32_t*) disp = CompressedKlassPointers::encode((Klass*)x);
67
      }
68
    }
69
  } else {
70
    // Note:  Use runtime_call_type relocations for call32_operand.
71
    address ip = addr();
72
    address disp = Assembler::locate_operand(ip, which);
73
    address next_ip = Assembler::locate_next_instruction(ip);
74
    if (verify_only) {
75
      guarantee(*(int32_t*) disp == (x - next_ip), "instructions must match");
76
    } else {
77
      *(int32_t*) disp = checked_cast<int32_t>(x - next_ip);
78
    }
79
  }
80
#else
81
  if (verify_only) {
82
    guarantee(*pd_address_in_code() == x, "instructions must match");
83
  } else {
84
    *pd_address_in_code() = x;
85
  }
86
#endif // AMD64
87
}
88

89

90
address Relocation::pd_call_destination(address orig_addr) {
91
  intptr_t adj = 0;
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 );
96
  }
97
  NativeInstruction* ni = nativeInstruction_at(addr());
98
  if (ni->is_call()) {
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
104
    }
105
    return dest + adj;
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();
110
  } else {
111
    ShouldNotReachHere();
112
    return nullptr;
113
  }
114
}
115

116

117
void Relocation::pd_set_call_destination(address x) {
118
  NativeInstruction* ni = nativeInstruction_at(addr());
119
  if (ni->is_call()) {
120
    nativeCall_at(addr())->set_destination(x);
121
  } else if (ni->is_jump()) {
122
    NativeJump* nj = nativeJump_at(addr());
123

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.
129

130
    if (nj->jump_destination() == (address) -1) {
131
      x = addr(); // jump to self
132
    }
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);
141
  } else {
142
    ShouldNotReachHere();
143
  }
144
}
145

146

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
154
#ifdef AMD64
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");
161
#else
162
  assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok");
163
#endif // AMD64
164
  return (address*) Assembler::locate_operand(addr(), which);
165
}
166

167

168
address Relocation::pd_get_address_from_code() {
169
#ifdef AMD64
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) {
180
    address ip = addr();
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;
184
    return a;
185
  }
186
#endif // AMD64
187
  return *pd_address_in_code();
188
}
189

190
void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
191
}
192

193
void metadata_Relocation::pd_fix_value(address x) {
194
}
195

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.