1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "linker/x86/relative_patcher_x86.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include "linker/linker_patch.h"
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker namespace art {
22*795d594fSAndroid Build Coastguard Worker namespace linker {
23*795d594fSAndroid Build Coastguard Worker
PatchPcRelativeReference(std::vector<uint8_t> * code,const LinkerPatch & patch,uint32_t patch_offset,uint32_t target_offset)24*795d594fSAndroid Build Coastguard Worker void X86RelativePatcher::PatchPcRelativeReference(std::vector<uint8_t>* code,
25*795d594fSAndroid Build Coastguard Worker const LinkerPatch& patch,
26*795d594fSAndroid Build Coastguard Worker uint32_t patch_offset,
27*795d594fSAndroid Build Coastguard Worker uint32_t target_offset) {
28*795d594fSAndroid Build Coastguard Worker uint32_t anchor_literal_offset = patch.PcInsnOffset();
29*795d594fSAndroid Build Coastguard Worker uint32_t literal_offset = patch.LiteralOffset();
30*795d594fSAndroid Build Coastguard Worker
31*795d594fSAndroid Build Coastguard Worker // Check that the anchor points to pop in a "call +0; pop <reg>" sequence.
32*795d594fSAndroid Build Coastguard Worker DCHECK_GE(anchor_literal_offset, 5u);
33*795d594fSAndroid Build Coastguard Worker DCHECK_LT(anchor_literal_offset, code->size());
34*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[anchor_literal_offset - 5u], 0xe8u);
35*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[anchor_literal_offset - 4u], 0x00u);
36*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[anchor_literal_offset - 3u], 0x00u);
37*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[anchor_literal_offset - 2u], 0x00u);
38*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[anchor_literal_offset - 1u], 0x00u);
39*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[anchor_literal_offset] & 0xf8u, 0x58u);
40*795d594fSAndroid Build Coastguard Worker
41*795d594fSAndroid Build Coastguard Worker // Check that the patched data contains kPlaceholder32BitOffset.
42*795d594fSAndroid Build Coastguard Worker // Must match CodeGeneratorX86_64::kPlaceholder32BitOffset.
43*795d594fSAndroid Build Coastguard Worker constexpr int kPlaceholder32BitOffset = 256;
44*795d594fSAndroid Build Coastguard Worker DCHECK_LE(literal_offset, code->size());
45*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[literal_offset + 0u], static_cast<uint8_t>(kPlaceholder32BitOffset >> 0));
46*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[literal_offset + 1u], static_cast<uint8_t>(kPlaceholder32BitOffset >> 8));
47*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[literal_offset + 2u], static_cast<uint8_t>(kPlaceholder32BitOffset >> 16));
48*795d594fSAndroid Build Coastguard Worker DCHECK_EQ((*code)[literal_offset + 3u], static_cast<uint8_t>(kPlaceholder32BitOffset >> 24));
49*795d594fSAndroid Build Coastguard Worker
50*795d594fSAndroid Build Coastguard Worker // Apply patch.
51*795d594fSAndroid Build Coastguard Worker uint32_t anchor_offset = patch_offset - literal_offset + anchor_literal_offset;
52*795d594fSAndroid Build Coastguard Worker uint32_t diff = target_offset - anchor_offset;
53*795d594fSAndroid Build Coastguard Worker (*code)[literal_offset + 0u] = static_cast<uint8_t>(diff >> 0);
54*795d594fSAndroid Build Coastguard Worker (*code)[literal_offset + 1u] = static_cast<uint8_t>(diff >> 8);
55*795d594fSAndroid Build Coastguard Worker (*code)[literal_offset + 2u] = static_cast<uint8_t>(diff >> 16);
56*795d594fSAndroid Build Coastguard Worker (*code)[literal_offset + 3u] = static_cast<uint8_t>(diff >> 24);
57*795d594fSAndroid Build Coastguard Worker }
58*795d594fSAndroid Build Coastguard Worker
PatchEntrypointCall(std::vector<uint8_t> * code,const LinkerPatch & patch,uint32_t patch_offset)59*795d594fSAndroid Build Coastguard Worker void X86RelativePatcher::PatchEntrypointCall([[maybe_unused]] std::vector<uint8_t>* code,
60*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] const LinkerPatch& patch,
61*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t patch_offset) {
62*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "UNIMPLEMENTED";
63*795d594fSAndroid Build Coastguard Worker }
64*795d594fSAndroid Build Coastguard Worker
PatchBakerReadBarrierBranch(std::vector<uint8_t> * code,const LinkerPatch & patch,uint32_t patch_offset)65*795d594fSAndroid Build Coastguard Worker void X86RelativePatcher::PatchBakerReadBarrierBranch([[maybe_unused]] std::vector<uint8_t>* code,
66*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] const LinkerPatch& patch,
67*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] uint32_t patch_offset) {
68*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "UNIMPLEMENTED";
69*795d594fSAndroid Build Coastguard Worker }
70*795d594fSAndroid Build Coastguard Worker
71*795d594fSAndroid Build Coastguard Worker } // namespace linker
72*795d594fSAndroid Build Coastguard Worker } // namespace art
73