[clang] [compiler-rt] [llvm] [XRay][RISCV] RISCV support for XRay (PR #117368)
Craig Topper via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 4 11:33:05 PST 2024
================
@@ -0,0 +1,266 @@
+//===-- xray_riscv.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of XRay, a dynamic runtime instrumentation system.
+//
+// Implementation of RISC-V specific routines (32- and 64-bit).
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common.h"
+#include "xray_defs.h"
+#include "xray_interface_internal.h"
+#include <atomic>
+
+namespace __xray {
+
+// The machine codes for some instructions used in runtime patching.
+enum PatchOpcodes : uint32_t {
+ PO_ADDI = 0x00000013, // addi rd, rs1, imm
+ PO_ADD = 0x00000033, // add rd, rs1, rs2
+ PO_SW = 0x00002023, // sw rs2, imm(rs1)
+ PO_SD = 0x00003023, // sd rs2, imm(rs1)
+ PO_LUI = 0x00000037, // lui rd, imm
+ PO_OR = 0x00006033, // or rd, rs1, rs2
+ PO_SLLI = 0x00001013, // slli rd, rs1, shamt
+ PO_JALR = 0x00000067, // jalr rd, rs1
+ PO_LW = 0x00002003, // lw rd, imm(rs1)
+ PO_LD = 0x00003003, // ld rd, imm(rs1)
+ PO_J = 0x0000006f, // jal imm
+ PO_NOP = PO_ADDI, // addi x0, x0, 0
+};
+
+enum RegNum : uint32_t {
+ RN_X0 = 0,
+ RN_RA = 1,
+ RN_SP = 2,
+ RN_T1 = 6,
+ RN_A0 = 10,
+};
+
+static inline uint32_t encodeRTypeInstruction(uint32_t Opcode, uint32_t Rs1,
+ uint32_t Rs2, uint32_t Rd) {
+ return Rs2 << 20 | Rs1 << 15 | Rd << 7 | Opcode;
+}
+
+static inline uint32_t encodeITypeInstruction(uint32_t Opcode, uint32_t Rs1,
+ uint32_t Rd, uint32_t Imm) {
+ return Imm << 20 | Rs1 << 15 | Rd << 7 | Opcode;
+}
+
+static inline uint32_t encodeSTypeInstruction(uint32_t Opcode, uint32_t Rs1,
+ uint32_t Rs2, uint32_t Imm) {
+ uint32_t ImmMSB = (Imm & 0xfe0) << 25;
+ uint32_t ImmLSB = (Imm & 0x01f) << 7;
+ return ImmMSB | Rs2 << 20 | Rs1 << 15 | ImmLSB | Opcode;
+}
+
+static inline uint32_t encodeUTypeInstruction(uint32_t Opcode, uint32_t Rd,
+ uint32_t Imm) {
+ return Imm << 12 | Rd << 7 | Opcode;
+}
+
+static inline uint32_t encodeJTypeInstruction(uint32_t Opcode, uint32_t Rd,
+ uint32_t Imm) {
+ uint32_t ImmMSB = (Imm & 0x100000) << 31;
+ uint32_t ImmLSB = (Imm & 0x7fe) << 21;
+ uint32_t Imm11 = (Imm & 0x800) << 20;
+ uint32_t Imm1912 = (Imm & 0xff000) << 12;
+ return ImmMSB | ImmLSB | Imm11 | Imm1912 | Rd << 7 | Opcode;
+}
+
+static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; }
+static uint32_t lo12(uint32_t val) { return val & 0xfff; }
+
+static inline bool patchSled(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled,
+ void (*TracingHook)()) XRAY_NEVER_INSTRUMENT {
+ // When |Enable| == true,
+ // We replace the following compile-time stub (sled):
+ //
+ // xray_sled_n:
+ // J .tmpN
+ // 25 or 33 C.NOPs (50 or 66 bytes)
+ // .tmpN
+ //
+ // With one of the following runtime patches:
+ //
+ // xray_sled_n (32-bit):
+ // addi sp, sp, -16 ;create stack frame
+ // sw ra, 12(sp) ;save return address
+ // sw t1, 8(sp) ;save register t1
----------------
topperc wrote:
Do we need to save t1? It's not used elsewhere in the sled
https://github.com/llvm/llvm-project/pull/117368
More information about the cfe-commits
mailing list