Revert "riscv64: Add relative patcher."
This reverts commit e4e39b2b1e51ff0ab69cd319f9135f0c40b02147.
Reason for revert: DroidMonitor-triggered revert due to breakage https://android-build.corp.google.com/artifact/submitted/10695075/aosp_cf_riscv64_phone-trunk_staging-userdebug/latest/view/logs%2Fbuild_error.log, bug b/297000339
Bug: b/297000339
Change-Id: Id414e31ae63569cc02728fc652cbd45c6a46528f
diff --git a/dex2oat/Android.bp b/dex2oat/Android.bp
index 2f37382..1807ed5 100644
--- a/dex2oat/Android.bp
+++ b/dex2oat/Android.bp
@@ -55,11 +55,6 @@
"linker/arm64/relative_patcher_arm64.cc",
],
},
- riscv64: {
- srcs: [
- "linker/riscv64/relative_patcher_riscv64.cc",
- ],
- },
x86: {
srcs: [
"linker/x86/relative_patcher_x86.cc",
@@ -528,11 +523,6 @@
"linker/arm64/relative_patcher_arm64_test.cc",
],
},
- riscv64: {
- srcs: [
- "linker/riscv64/relative_patcher_riscv64_test.cc",
- ],
- },
x86: {
srcs: [
"linker/x86/relative_patcher_x86_test.cc",
diff --git a/dex2oat/linker/arm/relative_patcher_thumb2.h b/dex2oat/linker/arm/relative_patcher_thumb2.h
index b3a3eb5..d360482 100644
--- a/dex2oat/linker/arm/relative_patcher_thumb2.h
+++ b/dex2oat/linker/arm/relative_patcher_thumb2.h
@@ -23,6 +23,10 @@
namespace art {
+namespace arm {
+class ArmVIXLAssembler;
+} // namespace arm
+
namespace linker {
class Thumb2RelativePatcher final : public ArmBaseRelativePatcher {
diff --git a/dex2oat/linker/arm64/relative_patcher_arm64.h b/dex2oat/linker/arm64/relative_patcher_arm64.h
index ce90b80..9ad2c96 100644
--- a/dex2oat/linker/arm64/relative_patcher_arm64.h
+++ b/dex2oat/linker/arm64/relative_patcher_arm64.h
@@ -22,6 +22,10 @@
namespace art {
+namespace arm64 {
+class Arm64Assembler;
+} // namespace arm64
+
namespace linker {
class Arm64RelativePatcher final : public ArmBaseRelativePatcher {
diff --git a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc
index 09fbfc7..ce61f43 100644
--- a/dex2oat/linker/arm64/relative_patcher_arm64_test.cc
+++ b/dex2oat/linker/arm64/relative_patcher_arm64_test.cc
@@ -82,7 +82,7 @@
// CBNZ x17, +0. Bits 5-23 are a placeholder for target offset from PC in units of 4-bytes.
static constexpr uint32_t kCbnzIP1Plus0Insn = 0xb5000011u;
- static void InsertInsn(std::vector<uint8_t>* code, size_t pos, uint32_t insn) {
+ void InsertInsn(std::vector<uint8_t>* code, size_t pos, uint32_t insn) {
CHECK_LE(pos, code->size());
const uint8_t insn_code[] = {
static_cast<uint8_t>(insn),
@@ -94,11 +94,11 @@
code->insert(code->begin() + pos, insn_code, insn_code + sizeof(insn_code));
}
- static void PushBackInsn(std::vector<uint8_t>* code, uint32_t insn) {
+ void PushBackInsn(std::vector<uint8_t>* code, uint32_t insn) {
InsertInsn(code, code->size(), insn);
}
- static std::vector<uint8_t> RawCode(std::initializer_list<uint32_t> insns) {
+ std::vector<uint8_t> RawCode(std::initializer_list<uint32_t> insns) {
std::vector<uint8_t> raw_code;
raw_code.reserve(insns.size() * 4u);
for (uint32_t insn : insns) {
@@ -235,7 +235,7 @@
return false;
}
- static std::vector<uint8_t> GenNops(size_t num_nops) {
+ std::vector<uint8_t> GenNops(size_t num_nops) {
std::vector<uint8_t> result;
result.reserve(num_nops * 4u);
for (size_t i = 0; i != num_nops; ++i) {
@@ -244,7 +244,7 @@
return result;
}
- static std::vector<uint8_t> GenNopsAndBl(size_t num_nops, uint32_t bl) {
+ std::vector<uint8_t> GenNopsAndBl(size_t num_nops, uint32_t bl) {
std::vector<uint8_t> result;
result.reserve(num_nops * 4u + 4u);
for (size_t i = 0; i != num_nops; ++i) {
@@ -933,7 +933,7 @@
[&](uint32_t adrp_offset, uint32_t string_offset) {
Reset();
/* ADD that uses the result register of "ADRP x0, addr" as both source and destination. */
- uint32_t add = kAddXInsn | (100 << 10) | (0u << 5) | 0u; /* ADD x0, x0, #100 */
+ uint32_t add = kSubXInsn | (100 << 10) | (0u << 5) | 0u; /* ADD x0, x0, #100 */
TestAdrpInsn2Add(add, adrp_offset, /*has_thunk=*/ false, string_offset);
},
{ 0x12345678u, 0xffffc840 });
diff --git a/dex2oat/linker/relative_patcher.cc b/dex2oat/linker/relative_patcher.cc
index 231c4a5..1c04812 100644
--- a/dex2oat/linker/relative_patcher.cc
+++ b/dex2oat/linker/relative_patcher.cc
@@ -23,9 +23,6 @@
#ifdef ART_ENABLE_CODEGEN_arm64
#include "linker/arm64/relative_patcher_arm64.h"
#endif
-#ifdef ART_ENABLE_CODEGEN_riscv64
-#include "linker/riscv64/relative_patcher_riscv64.h"
-#endif
#ifdef ART_ENABLE_CODEGEN_x86
#include "linker/x86/relative_patcher_x86.h"
#endif
@@ -121,13 +118,6 @@
target_provider,
features->AsArm64InstructionSetFeatures()));
#endif
-#ifdef ART_ENABLE_CODEGEN_riscv64
- case InstructionSet::kRiscv64:
- return std::unique_ptr<RelativePatcher>(
- new Riscv64RelativePatcher(thunk_provider,
- target_provider,
- features->AsRiscv64InstructionSetFeatures()));
-#endif
default:
return std::unique_ptr<RelativePatcher>(new RelativePatcherNone);
}
diff --git a/dex2oat/linker/relative_patcher_test.h b/dex2oat/linker/relative_patcher_test.h
index 1e9b0e1..2900523 100644
--- a/dex2oat/linker/relative_patcher_test.h
+++ b/dex2oat/linker/relative_patcher_test.h
@@ -68,7 +68,6 @@
patcher_.reset();
bss_begin_ = 0u;
string_index_to_offset_map_.clear();
- method_index_to_offset_map_.clear();
compiled_method_refs_.clear();
compiled_methods_.clear();
patched_code_.clear();
@@ -87,7 +86,6 @@
&method_offset_map_);
bss_begin_ = 0u;
string_index_to_offset_map_.clear();
- method_index_to_offset_map_.clear();
compiled_method_refs_.clear();
compiled_methods_.clear();
patched_code_.clear();
@@ -187,13 +185,6 @@
patch,
offset + patch.LiteralOffset(),
target_offset);
- } else if (patch.GetType() == LinkerPatch::Type::kMethodBssEntry) {
- uint32_t target_offset =
- bss_begin_ + method_index_to_offset_map_.Get(patch.TargetMethod().index);
- patcher_->PatchPcRelativeReference(&patched_code_,
- patch,
- offset + patch.LiteralOffset(),
- target_offset);
} else if (patch.GetType() == LinkerPatch::Type::kStringRelative) {
uint32_t target_offset =
string_index_to_offset_map_.Get(patch.TargetStringIndex().index_);
@@ -400,7 +391,6 @@
std::unique_ptr<RelativePatcher> patcher_;
uint32_t bss_begin_;
SafeMap<uint32_t, uint32_t> string_index_to_offset_map_;
- SafeMap<uint32_t, uint32_t> method_index_to_offset_map_;
std::vector<MethodReference> compiled_method_refs_;
std::vector<std::unique_ptr<CompiledMethod>> compiled_methods_;
std::vector<uint8_t> patched_code_;
diff --git a/dex2oat/linker/riscv64/relative_patcher_riscv64.cc b/dex2oat/linker/riscv64/relative_patcher_riscv64.cc
deleted file mode 100644
index a376003..0000000
--- a/dex2oat/linker/riscv64/relative_patcher_riscv64.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "relative_patcher_riscv64.h"
-
-#include "base/bit_utils.h"
-#include "linker/linker_patch.h"
-
-namespace art {
-namespace linker {
-
-Riscv64RelativePatcher::Riscv64RelativePatcher(
- [[maybe_unused]] RelativePatcherThunkProvider* thunk_provider,
- [[maybe_unused]] RelativePatcherTargetProvider* target_provider,
- [[maybe_unused]] const Riscv64InstructionSetFeatures* features)
- : RelativePatcher() {
-}
-
-uint32_t Riscv64RelativePatcher::ReserveSpace(
- uint32_t offset,
- [[maybe_unused]] const CompiledMethod* compiled_method,
- [[maybe_unused]] MethodReference method_ref) {
- // TODO(riscv64): Reduce code size for AOT by using shared trampolines for slow path
- // runtime calls across the entire oat file. These need space reserved here.
- return offset;
-}
-
-uint32_t Riscv64RelativePatcher::ReserveSpaceEnd(uint32_t offset) {
- // TODO(riscv64): Reduce code size for AOT by using shared trampolines for slow path
- // runtime calls across the entire oat file. These need space reserved here.
- return offset;
-}
-
-uint32_t Riscv64RelativePatcher::WriteThunks([[maybe_unused]] OutputStream* out, uint32_t offset) {
- // TODO(riscv64): Reduce code size for AOT by using shared trampolines for slow path
- // runtime calls across the entire oat file. These need to be written here.
- return offset;
-}
-
-void Riscv64RelativePatcher::PatchCall([[maybe_unused]] std::vector<uint8_t>* code,
- [[maybe_unused]] uint32_t literal_offset,
- [[maybe_unused]] uint32_t patch_offset,
- [[maybe_unused]] uint32_t target_offset) {
- // Direct calls are currently not used on any architecture.
- UNIMPLEMENTED(FATAL) << "Unsupported direct call.";
-}
-
-void Riscv64RelativePatcher::PatchPcRelativeReference(std::vector<uint8_t>* code,
- const LinkerPatch& patch,
- uint32_t patch_offset,
- uint32_t target_offset) {
- DCHECK_ALIGNED(patch_offset, 2u);
- DCHECK_ALIGNED(target_offset, 2u);
- uint32_t literal_offset = patch.LiteralOffset();
- uint32_t insn = GetInsn(code, literal_offset);
- uint32_t pc_insn_offset = patch.PcInsnOffset();
- uint32_t disp = target_offset - (patch_offset - literal_offset + pc_insn_offset);
- if (literal_offset == pc_insn_offset) {
- // Check it's an AUIPC with imm == 0x12345 (unset).
- DCHECK_EQ((insn & 0xfffff07fu), 0x12345017u)
- << literal_offset << ", " << pc_insn_offset << ", 0x" << std::hex << insn;
- insn = PatchAuipc(insn, disp);
- } else {
- DCHECK_EQ((insn & 0xfff00000u), 0x67800000u);
- CHECK((insn & 0x0000707fu) == 0x00000013u || // ADD
- (insn & 0x0000707fu) == 0x00006003u || // LWU
- (insn & 0x0000707fu) == 0x00003003u) // LD
- << "insn: 0x" << std::hex << insn << ", type: " << patch.GetType();
- // Check that pc_insn_offset points to AUIPC with matching register.
- DCHECK_EQ(GetInsn(code, pc_insn_offset) & 0x00000fffu,
- 0x00000017 | (((insn >> 15) & 0x1fu) << 7));
- uint32_t imm12 = disp & 0xfffu; // The instruction shall sign-extend this immediate.
- insn = (insn & ~(0xfffu << 20)) | (imm12 << 20);
- }
- SetInsn(code, literal_offset, insn);
-}
-
-void Riscv64RelativePatcher::PatchEntrypointCall([[maybe_unused]] std::vector<uint8_t>* code,
- [[maybe_unused]] const LinkerPatch& patch,
- [[maybe_unused]] uint32_t patch_offset) {
- // TODO(riscv64): Reduce code size for AOT by using shared trampolines for slow path
- // runtime calls across the entire oat file. Calls to these trapolines need to be patched here.
- UNIMPLEMENTED(FATAL) << "Shared entrypoint trampolines are not implemented.";
-}
-
-void Riscv64RelativePatcher::PatchBakerReadBarrierBranch(
- [[maybe_unused]] std::vector<uint8_t>* code,
- [[maybe_unused]] const LinkerPatch& patch,
- [[maybe_unused]] uint32_t patch_offset) {
- // Baker read barrier with introspection is not implemented.
- // Such implementation is impractical given the short reach of conditional branches.
- UNIMPLEMENTED(FATAL) << "Baker read barrier branches are not used on riscv64.";
-}
-
-std::vector<debug::MethodDebugInfo> Riscv64RelativePatcher::GenerateThunkDebugInfo(
- [[maybe_unused]] uint32_t executable_offset) {
- // TODO(riscv64): Reduce code size for AOT by using shared trampolines for slow path
- // runtime calls across the entire oat file. These need debug info generated here.
- UNIMPLEMENTED(FATAL) << "Shared entrypoint trampolines are not implemented.";
- UNREACHABLE();
-}
-
-uint32_t Riscv64RelativePatcher::PatchAuipc(uint32_t auipc, int32_t offset) {
- // The highest 0x800 values are out of range.
- DCHECK_LT(offset, 0x7ffff800);
- // Round `offset` to nearest 4KiB offset because short offset has range [-0x800, 0x800).
- int32_t near_offset = (offset + 0x800) & ~0xfff;
- // Extract the `imm20`.
- uint32_t imm20 = static_cast<uint32_t>(near_offset) >> 12;
- return (auipc & 0x00000fffu) | // Clear offset bits, keep AUIPC with destination reg.
- (imm20 << 12); // Encode the immediate.
-}
-
-void Riscv64RelativePatcher::SetInsn(std::vector<uint8_t>* code, uint32_t offset, uint32_t value) {
- DCHECK_LE(offset + 4u, code->size());
- DCHECK_ALIGNED(offset, 2u);
- uint8_t* addr = &(*code)[offset];
- addr[0] = (value >> 0) & 0xff;
- addr[1] = (value >> 8) & 0xff;
- addr[2] = (value >> 16) & 0xff;
- addr[3] = (value >> 24) & 0xff;
-}
-
-uint32_t Riscv64RelativePatcher::GetInsn(ArrayRef<const uint8_t> code, uint32_t offset) {
- DCHECK_LE(offset + 4u, code.size());
- DCHECK_ALIGNED(offset, 2u);
- const uint8_t* addr = &code[offset];
- return
- (static_cast<uint32_t>(addr[0]) << 0) +
- (static_cast<uint32_t>(addr[1]) << 8) +
- (static_cast<uint32_t>(addr[2]) << 16)+
- (static_cast<uint32_t>(addr[3]) << 24);
-}
-
-template <typename Alloc>
-uint32_t Riscv64RelativePatcher::GetInsn(std::vector<uint8_t, Alloc>* code, uint32_t offset) {
- return GetInsn(ArrayRef<const uint8_t>(*code), offset);
-}
-
-} // namespace linker
-} // namespace art
diff --git a/dex2oat/linker/riscv64/relative_patcher_riscv64.h b/dex2oat/linker/riscv64/relative_patcher_riscv64.h
deleted file mode 100644
index 0f70aa8..0000000
--- a/dex2oat/linker/riscv64/relative_patcher_riscv64.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_DEX2OAT_LINKER_RISCV64_RELATIVE_PATCHER_RISCV64_H_
-#define ART_DEX2OAT_LINKER_RISCV64_RELATIVE_PATCHER_RISCV64_H_
-
-#include "base/array_ref.h"
-#include "linker/relative_patcher.h"
-
-namespace art {
-
-namespace linker {
-
-class Riscv64RelativePatcher final : public RelativePatcher {
- public:
- Riscv64RelativePatcher(RelativePatcherThunkProvider* thunk_provider,
- RelativePatcherTargetProvider* target_provider,
- const Riscv64InstructionSetFeatures* features);
-
- uint32_t ReserveSpace(uint32_t offset,
- const CompiledMethod* compiled_method,
- MethodReference method_ref) override;
- uint32_t ReserveSpaceEnd(uint32_t offset) override;
- uint32_t WriteThunks(OutputStream* out, uint32_t offset) override;
- void PatchCall(std::vector<uint8_t>* code,
- uint32_t literal_offset,
- uint32_t patch_offset,
- uint32_t target_offset) override;
- void PatchPcRelativeReference(std::vector<uint8_t>* code,
- const LinkerPatch& patch,
- uint32_t patch_offset,
- uint32_t target_offset) override;
- void PatchEntrypointCall(std::vector<uint8_t>* code,
- const LinkerPatch& patch,
- uint32_t patch_offset) override;
- void PatchBakerReadBarrierBranch(std::vector<uint8_t>* code,
- const LinkerPatch& patch,
- uint32_t patch_offset) override;
- std::vector<debug::MethodDebugInfo> GenerateThunkDebugInfo(
- uint32_t executable_offset) override;
-
- private:
- static uint32_t PatchAuipc(uint32_t auipc, int32_t offset);
-
- static void SetInsn(std::vector<uint8_t>* code, uint32_t offset, uint32_t value);
- static uint32_t GetInsn(ArrayRef<const uint8_t> code, uint32_t offset);
- template <typename Alloc>
- uint32_t GetInsn(std::vector<uint8_t, Alloc>* code, uint32_t offset);
-
- DISALLOW_COPY_AND_ASSIGN(Riscv64RelativePatcher);
-};
-
-} // namespace linker
-} // namespace art
-
-#endif // ART_DEX2OAT_LINKER_RISCV64_RELATIVE_PATCHER_RISCV64_H_
diff --git a/dex2oat/linker/riscv64/relative_patcher_riscv64_test.cc b/dex2oat/linker/riscv64/relative_patcher_riscv64_test.cc
deleted file mode 100644
index 9e30ffd..0000000
--- a/dex2oat/linker/riscv64/relative_patcher_riscv64_test.cc
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "relative_patcher_riscv64.h"
-
-#include "oat_quick_method_header.h"
-#include "linker/linker_patch.h"
-#include "linker/relative_patcher_test.h"
-
-namespace art {
-namespace linker {
-
-class Riscv64RelativePatcherTest : public RelativePatcherTest {
- public:
- Riscv64RelativePatcherTest()
- : RelativePatcherTest(InstructionSet::kRiscv64, "default") { }
-
- protected:
- // C.NOP instruction.
- static constexpr uint32_t kCNopInsn = 0x0001u;
- static constexpr size_t kCNopSize = 2u;
-
- // Placeholder instructions with unset (zero) registers and immediates.
- static constexpr uint32_t kAuipcInsn = 0x00000017u;
- static constexpr uint32_t kAddiInsn = 0x00000013u;
- static constexpr uint32_t kLwuInsn = 0x00006003u;
- static constexpr uint32_t kLdInsn = 0x00003003u;
-
- // Placeholder offset encoded in AUIPC and used before patching.
- static constexpr uint32_t kUnpatchedOffset = 0x12345678u;
-
- static void PushBackInsn16(std::vector<uint8_t>* code, uint32_t insn16) {
- const uint8_t insn_code[] = {
- static_cast<uint8_t>(insn16),
- static_cast<uint8_t>(insn16 >> 8),
- };
- code->insert(code->end(), insn_code, insn_code + sizeof(insn_code));
- }
-
- static void PushBackInsn32(std::vector<uint8_t>* code, uint32_t insn32) {
- const uint8_t insn_code[] = {
- static_cast<uint8_t>(insn32),
- static_cast<uint8_t>(insn32 >> 8),
- static_cast<uint8_t>(insn32 >> 16),
- static_cast<uint8_t>(insn32 >> 24),
- };
- code->insert(code->end(), insn_code, insn_code + sizeof(insn_code));
- }
-
- uint32_t GetMethodOffset(uint32_t method_idx) {
- auto result = method_offset_map_.FindMethodOffset(MethodRef(method_idx));
- CHECK(result.first);
- CHECK_ALIGNED(result.second, 4u);
- return result.second;
- }
-
- static constexpr uint32_t ExtractRs1ToRd(uint32_t insn) {
- // The `rs1` is in bits 15..19 and we need to move it to bits 7..11.
- return (insn >> (15 - 7)) & (0x1fu << 7);
- }
-
- std::vector<uint8_t> GenNopsAndAuipcAndUse(size_t start_cnops,
- size_t mid_cnops,
- uint32_t method_offset,
- uint32_t target_offset,
- uint32_t use_insn) {
- CHECK_ALIGNED(method_offset, 4u);
- uint32_t auipc_offset = method_offset + start_cnops * kCNopSize;
- uint32_t offset = target_offset - auipc_offset;
- if (offset != /* unpatched */ 0x12345678u) {
- CHECK_ALIGNED(target_offset, 4u);
- }
- CHECK_EQ(use_insn & 0xfff00000u, 0u);
- // Prepare `imm12` for `use_insn` and `imm20` for AUIPC, adjusted for sign-extension of `imm12`.
- uint32_t imm12 = offset & 0xfffu;
- uint32_t imm20 = (offset >> 12) + ((offset >> 11) & 1u);
- // Prepare the AUIPC and use instruction.
- DCHECK_EQ(use_insn & 0xfff00000u, 0u); // Check that `imm12` in `use_insn` is empty.
- use_insn |= imm12 << 20; // Update `imm12` in `use_insn`.
- uint32_t auipc = kAuipcInsn | // AUIPC rd, imm20
- ExtractRs1ToRd(use_insn) | // where `rd` is `rs1` from `use_insn`.
- (imm20 << 12);
- // Create the code.
- std::vector<uint8_t> result;
- result.reserve((start_cnops + mid_cnops) * kCNopSize + 8u);
- for (size_t i = 0; i != start_cnops; ++i) {
- PushBackInsn16(&result, kCNopInsn);
- }
- PushBackInsn32(&result, auipc);
- for (size_t i = 0; i != mid_cnops; ++i) {
- PushBackInsn16(&result, kCNopInsn);
- }
- PushBackInsn32(&result, use_insn);
- return result;
- }
-
- std::vector<uint8_t> GenNopsAndAuipcAndUseUnpatched(size_t start_cnops,
- size_t mid_cnops,
- uint32_t use_insn) {
- uint32_t target_offset = start_cnops * kCNopSize + kUnpatchedOffset;
- return GenNopsAndAuipcAndUse(start_cnops, mid_cnops, 0u, target_offset, use_insn);
- }
-
- void TestNopsAuipcAddi(size_t start_cnops, size_t mid_cnops, uint32_t string_offset) {
- constexpr uint32_t kStringIndex = 1u;
- string_index_to_offset_map_.Put(kStringIndex, string_offset);
- constexpr uint32_t kAddi = kAddiInsn | (10 << 15) | (11 << 7); // ADDI A1, A0, <unfilled>
- auto code = GenNopsAndAuipcAndUseUnpatched(start_cnops, mid_cnops, kAddi);
- size_t auipc_offset = start_cnops * kCNopSize;
- size_t addi_offset = auipc_offset + 4u + mid_cnops * kCNopSize;
- const LinkerPatch patches[] = {
- LinkerPatch::RelativeStringPatch(auipc_offset, nullptr, auipc_offset, kStringIndex),
- LinkerPatch::RelativeStringPatch(addi_offset, nullptr, auipc_offset, kStringIndex),
- };
- AddCompiledMethod(MethodRef(1u),
- ArrayRef<const uint8_t>(code),
- ArrayRef<const LinkerPatch>(patches));
- Link();
-
- uint32_t method1_offset = GetMethodOffset(1u);
- auto expected_code =
- GenNopsAndAuipcAndUse(start_cnops, mid_cnops, method1_offset, string_offset, kAddi);
- EXPECT_TRUE(CheckLinkedMethod(MethodRef(1u), ArrayRef<const uint8_t>(expected_code)));
- }
-
- void TestNopsAuipcLwu(
- size_t start_cnops, size_t mid_cnops, uint32_t bss_begin, uint32_t string_entry_offset) {
- constexpr uint32_t kStringIndex = 1u;
- string_index_to_offset_map_.Put(kStringIndex, string_entry_offset);
- bss_begin_ = bss_begin;
- constexpr uint32_t kLwu = kLwuInsn | (10 << 15) | (10 << 7); // LWU A0, A0, <unfilled>
- auto code = GenNopsAndAuipcAndUseUnpatched(start_cnops, mid_cnops, kLwu);
- size_t auipc_offset = start_cnops * kCNopSize;
- size_t lwu_offset = auipc_offset + 4u + mid_cnops * kCNopSize;
- const LinkerPatch patches[] = {
- LinkerPatch::StringBssEntryPatch(auipc_offset, nullptr, auipc_offset, kStringIndex),
- LinkerPatch::StringBssEntryPatch(lwu_offset, nullptr, auipc_offset, kStringIndex),
- };
- AddCompiledMethod(MethodRef(1u),
- ArrayRef<const uint8_t>(code),
- ArrayRef<const LinkerPatch>(patches));
- Link();
-
- uint32_t method1_offset = GetMethodOffset(1u);
- uint32_t target_offset = bss_begin_ + string_entry_offset;
- auto expected_code =
- GenNopsAndAuipcAndUse(start_cnops, mid_cnops, method1_offset, target_offset, kLwu);
- EXPECT_TRUE(CheckLinkedMethod(MethodRef(1u), ArrayRef<const uint8_t>(expected_code)));
- }
-
- void TestNopsAuipcLd(
- size_t start_cnops, size_t mid_cnops, uint32_t bss_begin, uint32_t method_entry_offset) {
- constexpr uint32_t kMethodIndex = 100u;
- method_index_to_offset_map_.Put(kMethodIndex, method_entry_offset);
- bss_begin_ = bss_begin;
- constexpr uint32_t kLd = kLdInsn | (11 << 15) | (10 << 7); // LD A0, A1, <unfilled>
- auto code = GenNopsAndAuipcAndUseUnpatched(start_cnops, mid_cnops, kLd);
- size_t auipc_offset = start_cnops * kCNopSize;
- size_t ld_offset = auipc_offset + 4u + mid_cnops * kCNopSize;
- const LinkerPatch patches[] = {
- LinkerPatch::MethodBssEntryPatch(auipc_offset, nullptr, auipc_offset, kMethodIndex),
- LinkerPatch::MethodBssEntryPatch(ld_offset, nullptr, auipc_offset, kMethodIndex),
- };
- AddCompiledMethod(MethodRef(1u),
- ArrayRef<const uint8_t>(code),
- ArrayRef<const LinkerPatch>(patches));
- Link();
-
- uint32_t method1_offset = GetMethodOffset(1u);
- uint32_t target_offset = bss_begin_ + method_entry_offset;
- auto expected_code =
- GenNopsAndAuipcAndUse(start_cnops, mid_cnops, method1_offset, target_offset, kLd);
- EXPECT_TRUE(CheckLinkedMethod(MethodRef(1u), ArrayRef<const uint8_t>(expected_code)));
- }
-};
-
-TEST_F(Riscv64RelativePatcherTest, StringReference) {
- for (size_t start_cnops : {0, 1, 2, 3, 4, 5, 6, 7}) {
- for (size_t mid_cnops : {0, 1, 2, 3, 4, 5, 6, 7}) {
- for (uint32_t string_offset : { 0x12345678u, -0x12345678u, 0x123457fcu, 0x12345800u}) {
- Reset();
- TestNopsAuipcAddi(start_cnops, mid_cnops, string_offset);
- }
- }
- }
-}
-
-TEST_F(Riscv64RelativePatcherTest, StringBssEntry) {
- for (size_t start_cnops : {0, 1, 2, 3, 4, 5, 6, 7}) {
- for (size_t mid_cnops : {0, 1, 2, 3, 4, 5, 6, 7}) {
- for (uint32_t bss_begin : { 0x12345678u, -0x12345678u, 0x10000000u, 0x12345000u }) {
- for (uint32_t string_entry_offset : { 0x1234u, 0x4444u, 0x37fcu, 0x3800u }) {
- Reset();
- TestNopsAuipcLwu(start_cnops, mid_cnops, bss_begin, string_entry_offset);
- }
- }
- }
- }
-}
-
-TEST_F(Riscv64RelativePatcherTest, MethodBssEntry) {
- for (size_t start_cnops : {0, 1, 2, 3, 4, 5, 6, 7}) {
- for (size_t mid_cnops : {0, 1, 2, 3, 4, 5, 6, 7}) {
- for (uint32_t bss_begin : { 0x12345678u, -0x12345678u, 0x10000000u, 0x12345000u }) {
- for (uint32_t method_entry_offset : { 0x1234u, 0x4444u, 0x37f8u, 0x3800u }) {
- Reset();
- TestNopsAuipcLd(start_cnops, mid_cnops, bss_begin, method_entry_offset);
- }
- }
- }
- }
-}
-
-} // namespace linker
-} // namespace art