添加龙芯架构支持

Signed-off-by: herengui <herengui@kylinsec.com.cn>
(cherry picked from commit 0081fd7d85dec5664aeeff1fe3eb709c26fac43c)
This commit is contained in:
herengui 2023-08-10 14:54:54 +08:00 committed by openeuler-sync-bot
parent 9151ebdbf7
commit 09a1e99260
3 changed files with 4070 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,790 @@
From 4ba7d34a059c3ce0738940f293fded7f3096d016 Mon Sep 17 00:00:00 2001
From: herengui <herengui@kylinsec.com.cn>
Date: Thu, 31 Aug 2023 09:46:51 +0800
Subject: [PATCH 1001/1001] add loongarch64 support not upstream new
Signed-off-by: herengui <herengui@kylinsec.com.cn>
---
lib/builtins/loongarch/fp_mode.c | 61 ++++++
...ommon_interceptors_vfork_loongarch64.inc.S | 57 ++++++
.../sanitizer_syscall_linux_loongarch64.inc | 168 +++++++++++++++++
lib/tsan/rtl/tsan_rtl_loongarch64.S | 142 ++++++++++++++
lib/xray/xray_loongarch.cpp | 173 ++++++++++++++++++
lib/xray/xray_trampoline_loongarch.S | 129 +++++++++++++
6 files changed, 730 insertions(+)
create mode 100644 lib/builtins/loongarch/fp_mode.c
create mode 100644 lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S
create mode 100644 lib/sanitizer_common/sanitizer_syscall_linux_loongarch64.inc
create mode 100644 lib/tsan/rtl/tsan_rtl_loongarch64.S
create mode 100644 lib/xray/xray_loongarch.cpp
create mode 100644 lib/xray/xray_trampoline_loongarch.S
diff --git a/compiler-rt.orig/lib/builtins/loongarch/fp_mode.c b/compiler-rt.new/lib/builtins/loongarch/fp_mode.c
new file mode 100644
index 0000000..6471cc3
--- /dev/null
+++ b/compiler-rt.new/lib/builtins/loongarch/fp_mode.c
@@ -0,0 +1,61 @@
+//=== lib/builtins/loongarch/fp_mode.c - Floaing-point mode utilities -*- 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
+//
+//===----------------------------------------------------------------------===//
+#include "../fp_mode.h"
+
+#define LOONGARCH_TONEAREST 0x0000
+#define LOONGARCH_TOWARDZERO 0x0100
+#define LOONGARCH_UPWARD 0x0200
+#define LOONGARCH_DOWNWARD 0x0300
+
+#define LOONGARCH_RMODE_MASK \
+ (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | LOONGARCH_UPWARD | \
+ LOONGARCH_DOWNWARD)
+
+#define LOONGARCH_INEXACT 0x10000
+
+FE_ROUND_MODE __fe_getround(void) {
+#if __loongarch_frlen != 0
+ int fcsr;
+#if __clang__
+ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r"(fcsr));
+#else
+ /* FIXME: gcc cannot recognise $fcsr0, use $r0 as a workaround. */
+ __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r"(fcsr));
+#endif
+ fcsr &= LOONGARCH_RMODE_MASK;
+ switch (fcsr) {
+ case LOONGARCH_TOWARDZERO:
+ return FE_TOWARDZERO;
+ case LOONGARCH_DOWNWARD:
+ return FE_DOWNWARD;
+ case LOONGARCH_UPWARD:
+ return FE_UPWARD;
+ case LOONGARCH_TONEAREST:
+ default:
+ return FE_TONEAREST;
+ }
+#else
+ return FE_TONEAREST;
+#endif
+}
+
+int __fe_raise_inexact(void) {
+#if __loongarch_frlen != 0
+ int fcsr;
+#if __clang__
+ __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r"(fcsr));
+ __asm__ __volatile__("movgr2fcsr $fcr0, %0" ::"r"(fcsr | LOONGARCH_INEXACT));
+#else
+ /* FIXME: gcc cannot recognise $fcsr0, use $r0 as a workaround. */
+ __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r"(fcsr));
+ __asm__ __volatile__("movgr2fcsr $r0, %0" ::"r"(fcsr | LOONGARCH_INEXACT));
+#endif
+#endif
+ return 0;
+}
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S b/compiler-rt.new/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S
new file mode 100644
index 0000000..dae72b5
--- /dev/null
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S
@@ -0,0 +1,57 @@
+#if defined(__loongarch64) && defined(__linux__)
+
+#include "sanitizer_common/sanitizer_asm.h"
+
+ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA)
+ASM_HIDDEN(_ZN14__interception10real_vforkE)
+
+.text
+.globl ASM_WRAPPER_NAME(vfork)
+ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
+ASM_WRAPPER_NAME(vfork):
+ // Save ra in the off-stack spill area.
+ // allocate space on stack
+ addi.d $sp, $sp, -16
+ // store $ra value
+ st.d $ra, $sp, 8
+ bl COMMON_INTERCEPTOR_SPILL_AREA
+ // restore previous values from stack
+ ld.d $ra, $sp, 8
+ // adjust stack
+ addi.d $sp, $sp, 16
+ // store $ra by $a0
+ st.d $ra, $a0, 0
+
+ // Call real vfork. This may return twice. User code that runs between the first and the second return
+ // may clobber the stack frame of the interceptor; that's why it does not have a frame.
+ la.local $a0, _ZN14__interception10real_vforkE
+ ld.d $a0, $a0, 0
+ jirl $ra, $a0, 0
+
+ // adjust stack
+ addi.d $sp, $sp, -16
+ // store $a0 by adjusted stack
+ st.d $a0, $sp, 8
+ // jump to exit label if $a0 is 0
+ beqz $a0, .L_exit
+
+ // $a0 != 0 => parent process. Clear stack shadow.
+ // put old $sp to $a0
+ addi.d $a0, $sp, 16
+ bl %plt(COMMON_INTERCEPTOR_HANDLE_VFORK)
+
+.L_exit:
+ // Restore $ra
+ bl COMMON_INTERCEPTOR_SPILL_AREA
+ ld.d $ra, $a0, 0
+ // load value by stack
+ ld.d $a0, $sp, 8
+ // adjust stack
+ addi.d $sp, $sp, 16
+ jr $ra
+ASM_SIZE(vfork)
+
+.weak vfork
+.set vfork, ASM_WRAPPER_NAME(vfork)
+
+#endif
diff --git a/compiler-rt.orig/lib/sanitizer_common/sanitizer_syscall_linux_loongarch64.inc b/compiler-rt.new/lib/sanitizer_common/sanitizer_syscall_linux_loongarch64.inc
new file mode 100644
index 0000000..0d8d530
--- /dev/null
+++ b/compiler-rt.new/lib/sanitizer_common/sanitizer_syscall_linux_loongarch64.inc
@@ -0,0 +1,168 @@
+//===-- sanitizer_syscall_linux_loongarch64.inc -----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementations of internal_syscall and internal_iserror for
+// Linux/loongarch64.
+//
+//===----------------------------------------------------------------------===//
+
+// About local register variables:
+// https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables
+//
+// Kernel ABI...
+// syscall number is passed in a7
+// (http://man7.org/linux/man-pages/man2/syscall.2.html) results are return in
+// a0 and a1 (http://man7.org/linux/man-pages/man2/syscall.2.html) arguments
+// are passed in: a0-a7 (confirmed by inspecting glibc sources).
+#define SYSCALL(name) __NR_##name
+
+#define INTERNAL_SYSCALL_CLOBBERS \
+ "memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8"
+
+static uptr __internal_syscall(u64 nr) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0");
+ __asm__ volatile("syscall 0\n\t"
+ : "=r"(a0)
+ : "r"(a7)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall0(n) (__internal_syscall)(n)
+
+static uptr __internal_syscall(u64 nr, u64 arg1) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall1(n, a1) (__internal_syscall)(n, (u64)(a1))
+
+static uptr __internal_syscall(u64 nr, u64 arg1, long arg2) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ register u64 a1 asm("a1") = arg2;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall2(n, a1, a2) \
+ (__internal_syscall)(n, (u64)(a1), (long)(a2))
+
+static uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ register u64 a1 asm("a1") = arg2;
+ register u64 a2 asm("a2") = arg3;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall3(n, a1, a2, a3) \
+ (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3))
+
+static uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3,
+ u64 arg4) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ register u64 a1 asm("a1") = arg2;
+ register u64 a2 asm("a2") = arg3;
+ register u64 a3 asm("a3") = arg4;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall4(n, a1, a2, a3, a4) \
+ (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4))
+
+static uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3, u64 arg4,
+ long arg5) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ register u64 a1 asm("a1") = arg2;
+ register u64 a2 asm("a2") = arg3;
+ register u64 a3 asm("a3") = arg4;
+ register u64 a4 asm("a4") = arg5;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall5(n, a1, a2, a3, a4, a5) \
+ (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4), \
+ (u64)(a5))
+
+static uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3, u64 arg4,
+ long arg5, long arg6) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ register u64 a1 asm("a1") = arg2;
+ register u64 a2 asm("a2") = arg3;
+ register u64 a3 asm("a3") = arg4;
+ register u64 a4 asm("a4") = arg5;
+ register u64 a5 asm("a5") = arg6;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \
+ (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4), \
+ (u64)(a5), (long)(a6))
+
+static uptr __internal_syscall(u64 nr, u64 arg1, long arg2, long arg3, u64 arg4,
+ long arg5, long arg6, long arg7) {
+ register u64 a7 asm("a7") = nr;
+ register u64 a0 asm("a0") = arg1;
+ register u64 a1 asm("a1") = arg2;
+ register u64 a2 asm("a2") = arg3;
+ register u64 a3 asm("a3") = arg4;
+ register u64 a4 asm("a4") = arg5;
+ register u64 a5 asm("a5") = arg6;
+ register u64 a6 asm("a6") = arg7;
+ __asm__ volatile("syscall 0\n\t"
+ : "+r"(a0)
+ : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5),
+ "r"(a6)
+ : INTERNAL_SYSCALL_CLOBBERS);
+ return a0;
+}
+#define __internal_syscall7(n, a1, a2, a3, a4, a5, a6, a7) \
+ (__internal_syscall)(n, (u64)(a1), (long)(a2), (long)(a3), (long)(a4), \
+ (u64)(a5), (long)(a6), (long)(a7))
+
+#define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n
+#define __SYSCALL_NARGS(...) \
+ __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, )
+#define __SYSCALL_CONCAT_X(a, b) a##b
+#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b)
+#define __SYSCALL_DISP(b, ...) \
+ __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
+
+#define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__)
+
+// Helper function used to avoid clobbering of errno.
+bool internal_iserror(uptr retval, int *internal_errno) {
+ if (retval >= (uptr)-4095) {
+ if (internal_errno)
+ *internal_errno = -retval;
+ return true;
+ }
+ return false;
+}
diff --git a/compiler-rt.orig/lib/tsan/rtl/tsan_rtl_loongarch64.S b/compiler-rt.new/lib/tsan/rtl/tsan_rtl_loongarch64.S
new file mode 100644
index 0000000..66b16e4
--- /dev/null
+++ b/compiler-rt.new/lib/tsan/rtl/tsan_rtl_loongarch64.S
@@ -0,0 +1,142 @@
+.section .text
+
+.hidden __tsan_setjmp
+.comm _ZN14__interception11real_setjmpE,8,8
+.globl setjmp
+.type setjmp, @function
+setjmp:
+
+ # save env parameters
+ addi.d $sp, $sp, -32
+ st.d $ra, $sp, 24
+ st.d $fp, $sp, 16
+
+ # save jmp_buf
+ st.d $a0, $sp, 0
+
+ # obtain $sp and call tsan interceptor
+ addi.d $a0, $sp, 32
+ bl __tsan_setjmp
+
+ # restore jmp_buf
+ ld.d $a0, $sp, 0
+
+ # load libc setjmp to t0
+ la.got $t0, _ZN14__interception11real_setjmpE
+
+ # restore env parameters
+ ld.d $fp, $sp, 16
+ ld.d $ra, $sp, 24
+ addi.d $sp, $sp, 32
+
+ # tail jump to libc setjmp
+ ld.d $t0, $t0, 0
+ jr $t0
+
+.size setjmp, .-setjmp
+
+.globl _setjmp
+.comm _ZN14__interception12real__setjmpE,8,8
+.type _setjmp, @function
+_setjmp:
+
+ # Save env parameters
+ addi.d $sp, $sp, -32
+ st.d $ra, $sp, 24
+ st.d $fp, $sp, 16
+
+ # save jmp_buf
+ st.d $a0, $sp, 0
+
+ # obtain $sp and call tsan interceptor
+ addi.d $a0, $sp, 32
+ bl __tsan_setjmp
+
+ # restore jmp_buf
+ ld.d $a0, $sp, 0
+
+ # load libc setjmp to t0
+ la.got $t0, _ZN14__interception12real__setjmpE
+
+ # restore env parameters
+ ld.d $fp, $sp, 16
+ ld.d $ra, $sp, 24
+ addi.d $sp, $sp, 32
+
+ # tail jump to libc setjmp
+ ld.d $t0, $t0, 0
+ jr $t0
+
+.size _setjmp, .-_setjmp
+
+.globl sigsetjmp
+.comm _ZN14__interception14real_sigsetjmpE,8,8
+.type sigsetjmp, @function
+sigsetjmp:
+
+ # Save env parameters
+ addi.d $sp, $sp, -32
+ st.d $ra, $sp, 24
+ st.d $fp, $sp, 16
+
+ # save jmp_buf and savesigs
+ st.d $a0, $sp, 0
+ st.d $a1, $sp, 8
+
+ # obtain $sp and call tsan interceptor
+ addi.d $a0, $sp, 32
+ bl __tsan_setjmp
+
+ # restore jmp_buf and savesigs
+ ld.d $a0, $sp, 0
+ ld.d $a1, $sp, 8
+
+ # load libc setjmp to t0
+ la.got $t0, _ZN14__interception14real_sigsetjmpE
+
+ # restore env parameters
+ ld.d $fp, $sp, 16
+ ld.d $ra, $sp, 24
+ addi.d $sp, $sp, 32
+
+ # tail jump to libc setjmp
+ ld.d $t0, $t0, 0
+ jr $t0
+
+.size sigsetjmp, .-sigsetjmp
+
+.comm _ZN14__interception16real___sigsetjmpE,8,8
+.globl __sigsetjmp
+.type __sigsetjmp, @function
+__sigsetjmp:
+
+ # Save env parameters
+ addi.d $sp, $sp, -32
+ st.d $ra, $sp, 24
+ st.d $fp, $sp, 16
+
+ # save jmp_buf and savesigs
+ st.d $a0, $sp, 0
+ st.d $a1, $sp, 8
+
+ # obtain $sp and call tsan interceptor
+ addi.d $a0, $sp, 32
+ bl __tsan_setjmp
+
+ # restore jmp_buf and savesigs
+ ld.d $a0, $sp, 0
+ ld.d $a1, $sp, 8
+
+ # load libc setjmp to t0
+ la.got $t0, _ZN14__interception16real___sigsetjmpE
+
+ # restore env parameters
+ ld.d $fp, $sp, 16
+ ld.d $ra, $sp, 24
+ addi.d $sp, $sp, 32
+
+ # tail jump to libc setjmp
+ ld.d $t0, $t0, 0
+ jr $t0
+
+.size __sigsetjmp, .-__sigsetjmp
diff --git a/compiler-rt.orig/lib/xray/xray_loongarch.cpp b/compiler-rt.new/lib/xray/xray_loongarch.cpp
new file mode 100644
index 0000000..c72bb2d
--- /dev/null
+++ b/compiler-rt.new/lib/xray/xray_loongarch.cpp
@@ -0,0 +1,173 @@
+//===-- xray_loongarch.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 loongarch-specific routines.
+//
+//===----------------------------------------------------------------------===//
+#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_ADDID = 0x02c00000, // addi.d rt, rs, imm
+ PO_SD = 0x29c00000, // st.d rt, base, offset
+ PO_LU12IW = 0x14000000, // lu12i.w rt, imm
+ PO_ORI = 0x03800000, // ori rt, rs, imm
+ PO_LU32ID = 0x16000000, // lu32i.d rd, imm
+ PO_LU52ID = 0x03000000, // lu52i.d rd, rj, imm
+ PO_JIRL = 0x4c000000, // jirl rd, rj, 0
+ PO_LD = 0x28c00000, // ld.d rt, base, offset
+ PO_B44 = 0x50002c00, // b #44
+};
+
+enum RegNum : uint32_t {
+ RN_T0 = 0xC,
+ RN_T1 = 0xD,
+ RN_RA = 0x1,
+ RN_SP = 0x3,
+};
+
+// addi.d lu521.d ori ld.d st.d
+inline static uint32_t
+encodeInstruction_i12(uint32_t Opcode, uint32_t Rd, uint32_t Rj,
+ uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+ return (Opcode | Rj << 5 | Rd | Imm << 10);
+}
+
+// lu12i.w lu32i.d
+inline static uint32_t
+encodeInstruction_si20(uint32_t Opcode, uint32_t Rd,
+ uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+ return (Opcode | Rd | Imm << 5);
+}
+
+// jirl
+inline static uint32_t
+encodeInstruction_si16(uint32_t Opcode, uint32_t Rd, uint32_t Rj,
+ uint32_t Imm) XRAY_NEVER_INSTRUMENT {
+ return (Opcode | Rj << 5 | Rd | Imm << 10);
+}
+
+inline static 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:
+ // B .tmpN
+ // 11 NOPs (44 bytes)
+ // .tmpN
+ //
+ // With the following runtime patch:
+ // xray_sled_n (64-bit):
+ // addi.d sp,sp, -16 ;create stack frame
+ // st.d ra, sp, 8 ;save return address
+ // lu12i.w t0,%%abs_hi20(__xray_FunctionEntry/Exit)
+ // ori %1,t0,%%abs_lo12(__xray_FunctionEntry/Exit)
+ // lu32i.d t0,%%abs64_lo20(__xray_FunctionEntry/Exit)
+ // lu52i.d t0,t0,%%abs64_hi12(__xray_FunctionEntry/Exit)
+ // lu12i.w t1,%%abs_hi20(function_id)
+ // ori %1,t1,%%abs_lo12(function_id) ;pass function id
+ // jirl ra, t0, 0 ;call Tracing hook
+ // ld.d ra, sp, 8 ;restore return address
+ // addi.d sp, sp, 16 ;delete stack frame
+ //
+ // Replacement of the first 4-byte instruction should be the last and atomic
+ // operation, so that the user code which reaches the sled concurrently
+ // either jumps over the whole sled, or executes the whole sled when the
+ // latter is ready.
+ //
+ // When |Enable|==false, we set back the first instruction in the sled to be
+ // B #44
+
+ uint32_t *Address = reinterpret_cast<uint32_t *>(Sled.address());
+ if (Enable) {
+ uint32_t LoTracingHookAddr = reinterpret_cast<int64_t>(TracingHook) & 0xfff;
+ uint32_t HiTracingHookAddr =
+ (reinterpret_cast<int64_t>(TracingHook) >> 12) & 0xfffff;
+ uint32_t HigherTracingHookAddr =
+ (reinterpret_cast<int64_t>(TracingHook) >> 32) & 0xfffff;
+ uint32_t HighestTracingHookAddr =
+ (reinterpret_cast<int64_t>(TracingHook) >> 52) & 0xfff;
+ uint32_t LoFunctionID = FuncId & 0xfff;
+ uint32_t HiFunctionID = (FuncId >> 12) & 0xfffff;
+ Address[2] = encodeInstruction_i12(PatchOpcodes::PO_SD, RegNum::RN_RA,
+ RegNum::RN_SP, 0x8);
+ Address[3] = encodeInstruction_si20(PatchOpcodes::PO_LU12IW, RegNum::RN_T0,
+ HiTracingHookAddr);
+ Address[4] = encodeInstruction_i12(PatchOpcodes::PO_ORI, RegNum::RN_T0,
+ RegNum::RN_T0, LoTracingHookAddr);
+ Address[5] = encodeInstruction_si20(PatchOpcodes::PO_LU32ID, RegNum::RN_T0,
+ HigherTracingHookAddr);
+ Address[6] = encodeInstruction_i12(PatchOpcodes::PO_LU52ID, RegNum::RN_T0,
+ RegNum::RN_T0, HighestTracingHookAddr);
+ Address[7] = encodeInstruction_si20(PatchOpcodes::PO_LU12IW, RegNum::RN_T1,
+ HiFunctionID);
+ Address[8] = encodeInstruction_i12(PatchOpcodes::PO_ORI, RegNum::RN_T1,
+ RegNum::RN_T1, LoFunctionID);
+ Address[9] = encodeInstruction_si16(PatchOpcodes::PO_JIRL, RegNum::RN_RA,
+ RegNum::RN_T0, 0);
+ Address[10] = encodeInstruction_i12(PatchOpcodes::PO_LD, RegNum::RN_RA,
+ RegNum::RN_SP, 0x8);
+ Address[11] = encodeInstruction_i12(PatchOpcodes::PO_LD, RegNum::RN_SP,
+ RegNum::RN_SP, 0x10);
+ uint32_t CreateStackSpace = encodeInstruction_i12(
+ PatchOpcodes::PO_ADDID, RegNum::RN_SP, RegNum::RN_SP, 0xfff0);
+ std::atomic_store_explicit(
+ reinterpret_cast<std::atomic<uint32_t> *>(Address), CreateStackSpace,
+ std::memory_order_release);
+ } else {
+ std::atomic_store_explicit(
+ reinterpret_cast<std::atomic<uint32_t> *>(Address),
+ uint32_t(PatchOpcodes::PO_B44), std::memory_order_release);
+ }
+ return true;
+}
+
+bool patchFunctionEntry(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled,
+ void (*Trampoline)()) XRAY_NEVER_INSTRUMENT {
+ return patchSled(Enable, FuncId, Sled, Trampoline);
+}
+
+bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ // FIXME: In the future we'd need to distinguish between non-tail exits and
+ // tail exits for better information preservation.
+ return patchSled(Enable, FuncId, Sled, __xray_FunctionExit);
+}
+
+bool patchCustomEvent(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ // FIXME: Implement in loongarch?
+ return false;
+}
+
+bool patchTypedEvent(const bool Enable, const uint32_t FuncId,
+ const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT {
+ // FIXME: Implement in loongarch?
+ return false;
+}
+} // namespace __xray
+
+extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {
+ // FIXME: this will have to be implemented in the trampoline assembly file
+}
diff --git a/compiler-rt.orig/lib/xray/xray_trampoline_loongarch.S b/compiler-rt.new/lib/xray/xray_trampoline_loongarch.S
new file mode 100644
index 0000000..7ac019b
--- /dev/null
+++ b/compiler-rt.new/lib/xray/xray_trampoline_loongarch.S
@@ -0,0 +1,129 @@
+//===-- xray_trampoline_loongarch.s -----------------------------*- ASM -*-===//
+//
+// 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.
+//
+// This implements the loongarch-specific assembler for the trampolines.
+//
+//===----------------------------------------------------------------------===//
+
+ .text
+ .file "xray_trampoline_loongarch.S"
+ .globl __xray_FunctionEntry
+ .p2align 2
+ .type __xray_FunctionEntry,@function
+__xray_FunctionEntry:
+ .cfi_startproc
+ // Save argument registers before doing any actual work.
+ .cfi_def_cfa_offset 136
+ addi.d $sp, $sp, -136
+ st.d $ra, $sp, 128
+ .cfi_offset 1, -8
+ st.d $a7, $sp, 120
+ st.d $a6, $sp, 112
+ st.d $a5, $sp, 104
+ st.d $a4, $sp, 96
+ st.d $a3, $sp, 88
+ st.d $a2, $sp, 80
+ st.d $a1, $sp, 72
+ st.d $a0, $sp, 64
+ fst.d $f7, $sp, 56
+ fst.d $f6, $sp, 48
+ fst.d $f5, $sp, 40
+ fst.d $f4, $sp, 32
+ fst.d $f3, $sp, 24
+ fst.d $f2, $sp, 16
+ fst.d $f1, $sp, 8
+ fst.d $f0, $sp, 0
+
+
+ lu12i.w $t2, %got_hi20(_ZN6__xray19XRayPatchedFunctionE)
+ ori $t2, $t2, %got_lo12(_ZN6__xray19XRayPatchedFunctionE)
+ lu32i.d $t2, %got64_lo20(_ZN6__xray19XRayPatchedFunctionE)
+ lu52i.d $t2, $t2, %got64_hi12(_ZN6__xray19XRayPatchedFunctionE)
+ ld.d $t2, $t2, 0
+
+ beqz $t2, FunctionEntry_restore
+
+ // a1=0 means that we are tracing an entry event
+ move $a1, $zero
+ // Function ID is in t1 (the first parameter).
+ move $a0, $t1
+ jirl $ra, $t2, 0
+
+FunctionEntry_restore:
+ // Restore argument registers
+ fld.d $f0, $sp, 0
+ fld.d $f1, $sp, 8
+ fld.d $f2, $sp, 16
+ fld.d $f3, $sp, 24
+ fld.d $f4, $sp, 32
+ fld.d $f5, $sp, 40
+ fld.d $f6, $sp, 48
+ fld.d $f7, $sp, 56
+ ld.d $a0, $sp, 64
+ ld.d $a1, $sp, 72
+ ld.d $a2, $sp, 80
+ ld.d $a3, $sp, 88
+ ld.d $a4, $sp, 96
+ ld.d $a5, $sp, 104
+ ld.d $a6, $sp, 112
+ ld.d $a7, $sp, 120
+ ld.d $ra, $sp, 128
+ addi.d $sp, $sp, 136
+ jr $ra
+FunctionEntry_end:
+ .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry
+ .cfi_endproc
+
+ .text
+ .globl __xray_FunctionExit
+ .p2align 2
+ .type __xray_FunctionExit,@function
+__xray_FunctionExit:
+ .cfi_startproc
+ // Save return registers before doing any actual work.
+ .cfi_def_cfa_offset 48
+ addi.d $sp, $sp, -48
+ st.d $ra, $sp, 40
+ .cfi_offset 1, -8
+ st.d $fp, $sp, 32
+ st.d $a1, $sp, 24
+ st.d $a0, $sp, 16
+ fst.d $f1, $sp, 8
+ fst.d $f0, $sp, 0
+
+ lu12i.w $t2, %got_hi20(_ZN6__xray19XRayPatchedFunctionE)
+ ori $t2, $t2, %got_lo12(_ZN6__xray19XRayPatchedFunctionE)
+ lu32i.d $t2, %got64_lo20(_ZN6__xray19XRayPatchedFunctionE)
+ lu52i.d $t2, $t2, %got64_hi12(_ZN6__xray19XRayPatchedFunctionE)
+ ld.d $t2, $t2, 0
+
+ beqz $t2, FunctionExit_restore
+
+ // a1=1 means that we are tracing an exit event
+ ori $a1, $zero, 1
+ // Function ID is in t1 (the first parameter).
+ move $a0, $t1
+ jirl $ra, $t2, 0
+
+FunctionExit_restore:
+ // Restore return registers
+ fld.d $f0, $sp, 0
+ fld.d $f1, $sp, 8
+ ld.d $a1, $sp, 24
+ ld.d $a0, $sp, 16
+ ld.d $fp, $sp, 32
+ ld.d $ra, $sp, 40
+ addi.d $sp, $sp, 48
+ jr $ra
+
+FunctionExit_end:
+ .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit
+ .cfi_endproc
+
--
2.41.0

View File

@ -4,7 +4,7 @@
Name: compiler-rt
Version: 12.0.1
Release: 2
Release: 3
Summary: LLVM "compiler-rt" runtime libraries
License: NCSA or MIT
@ -13,6 +13,9 @@ Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{versio
Source2: tstellar-gpg-key.asc
Patch0: 0001-PATCH-compiler-rt-Workaround-libstdc-limitation-wrt..patch
Patch1000: 1000-add-loongarch64-support-not-upstream-modified.patch
Patch1001: 1001-add-loongarch64-support-not-upstream-new.patch
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: cmake
@ -120,6 +123,9 @@ fi
%endif
%changelog
* Thu Aug 10 2023 herengui <herengui@kylinsec.com.cn> - 12.0.1-3
- add loongarch64 support
* Tue Dec 20 2022 eastb233 <xiezhiheng@huawei.com> - 12.0.1-2
- Delete run path in DSO