OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 ASSERT(IsSupported(CMOV)); | 166 ASSERT(IsSupported(CMOV)); |
167 } | 167 } |
168 | 168 |
169 | 169 |
170 // ----------------------------------------------------------------------------- | 170 // ----------------------------------------------------------------------------- |
171 // Implementation of RelocInfo | 171 // Implementation of RelocInfo |
172 | 172 |
173 // Patch the code at the current PC with a call to the target address. | 173 // Patch the code at the current PC with a call to the target address. |
174 // Additional guard int3 instructions can be added if required. | 174 // Additional guard int3 instructions can be added if required. |
175 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { | 175 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { |
176 // Call instruction takes up 13 bytes and int3 takes up one byte. | 176 // Load register with immediate 64 and call through a register instructions |
177 static const int kCallInstructionSize = 13; | 177 // takes up 13 bytes and int3 takes up one byte. |
178 Address patch_site = pc_; | 178 static const int kCallCodeSize = 13; |
179 Memory::uint16_at(patch_site) = 0xBA49u; // movq r10, imm64 | 179 int code_size = kCallCodeSize + guard_bytes; |
180 // Write "0x00, call r10" starting at last byte of address. We overwrite | 180 |
181 // the 0x00 later, and this lets us write a uint32. | 181 // Create a code patcher. |
182 Memory::uint32_at(patch_site + 9) = 0xD2FF4900u; // 0x00, call r10 | 182 CodePatcher patcher(pc_, code_size); |
183 Memory::Address_at(patch_site + 2) = target; | 183 |
| 184 // Add a label for checking the size of the code used for returning. |
| 185 #ifdef DEBUG |
| 186 Label check_codesize; |
| 187 patcher.masm()->bind(&check_codesize); |
| 188 #endif |
| 189 |
| 190 // Patch the code. |
| 191 patcher.masm()->movq(r10, target, RelocInfo::NONE); |
| 192 patcher.masm()->call(r10); |
| 193 |
| 194 // Check that the size of the code generated is as expected. |
| 195 ASSERT_EQ(kCallCodeSize, |
| 196 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); |
184 | 197 |
185 // Add the requested number of int3 instructions after the call. | 198 // Add the requested number of int3 instructions after the call. |
186 for (int i = 0; i < guard_bytes; i++) { | 199 for (int i = 0; i < guard_bytes; i++) { |
187 *(patch_site + kCallInstructionSize + i) = 0xCC; // int3 | 200 patcher.masm()->int3(); |
188 } | 201 } |
189 | |
190 // Indicate that code has changed. | |
191 CPU::FlushICache(patch_site, kCallInstructionSize + guard_bytes); | |
192 } | 202 } |
193 | 203 |
194 | 204 |
195 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { | 205 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { |
196 // Patch the code at the current address with the supplied instructions. | 206 // Patch the code at the current address with the supplied instructions. |
197 for (int i = 0; i < instruction_count; i++) { | 207 for (int i = 0; i < instruction_count; i++) { |
198 *(pc_ + i) = *(instructions + i); | 208 *(pc_ + i) = *(instructions + i); |
199 } | 209 } |
| 210 |
| 211 // Indicate that code has changed. |
| 212 CPU::FlushICache(pc_, instruction_count); |
200 } | 213 } |
201 | 214 |
202 // ----------------------------------------------------------------------------- | 215 // ----------------------------------------------------------------------------- |
203 // Implementation of Operand | 216 // Implementation of Operand |
204 | 217 |
205 Operand::Operand(Register base, int32_t disp): rex_(0) { | 218 Operand::Operand(Register base, int32_t disp): rex_(0) { |
206 len_ = 1; | 219 len_ = 1; |
207 if (base.is(rsp) || base.is(r12)) { | 220 if (base.is(rsp) || base.is(r12)) { |
208 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). | 221 // SIB byte is needed to encode (rsp + offset) or (r12 + offset). |
209 set_sib(times_1, rsp, base); | 222 set_sib(times_1, rsp, base); |
(...skipping 2152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2362 RecordRelocInfo(RelocInfo::POSITION, current_position_); | 2375 RecordRelocInfo(RelocInfo::POSITION, current_position_); |
2363 written_position_ = current_position_; | 2376 written_position_ = current_position_; |
2364 } | 2377 } |
2365 } | 2378 } |
2366 | 2379 |
2367 | 2380 |
2368 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; | 2381 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; |
2369 | 2382 |
2370 | 2383 |
2371 } } // namespace v8::internal | 2384 } } // namespace v8::internal |
OLD | NEW |