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