diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -79,5 +79,5 @@ set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64}) if (UNIX) -set(ALL_ORC_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM32}) +set(ALL_ORC_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM32} ${RISCV64}) endif() diff --git a/compiler-rt/test/orc/TestCases/Linux/riscv64/lit.local.cfg.py b/compiler-rt/test/orc/TestCases/Linux/riscv64/lit.local.cfg.py new file mode 100644 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/riscv64/lit.local.cfg.py @@ -0,0 +1,5 @@ +if config.root.host_arch != 'riscv64': + config.unsupported = True + +if config.target_arch != 'riscv64': + config.unsupported = True diff --git a/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-atexit.S b/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-atexit.S new file mode 100644 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-atexit.S @@ -0,0 +1,35 @@ +// Test that the runtime correctly interposes atexit. +// +// RUN: %clang -c -o %t %s +// RUN: %llvm_jitlink %t + + .file "atexit.c" + .option pic + .option norelax + .text + .align 1 +// OnExit destructor resets the test result override to zero. + .globl onExit + .type onExit, @function +onExit: + li a0,0 + tail llvm_jitlink_setTestResultOverride@plt + .size onExit, .-onExit + .section .text.startup,"ax",@progbits + .align 1 + // main registers the atexit and sets the test result to one. + .globl main + .type main, @function +main: + addi sp,sp,-16 + la a0,onExit + sd ra,8(sp) + call atexit@plt + li a0,1 + call llvm_jitlink_setTestResultOverride@plt + ld ra,8(sp) + li a0,0 + addi sp,sp,16 + jr ra + .size main, .-main + .section .note.GNU-stack,"",@progbits diff --git a/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-cxa-atexit.S b/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-cxa-atexit.S new file mode 100644 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-cxa-atexit.S @@ -0,0 +1,42 @@ +// Test that the runtime correctly interposes ___cxa_atexit. +// +// RUN: %clang -c -o %t %s +// RUN: %llvm_jitlink %t + + .option pic + .text + .align 1 + .globl _Z6onExitv + .type _Z6onExitv, @function +_Z6onExitv: + li a0,0 + tail llvm_jitlink_setTestResultOverride@plt + .size _Z6onExitv, .-_Z6onExitv + .section .text.startup,"ax",@progbits + .align 1 + .globl main + .type main, @function +main: + addi sp,sp,-16 + la a0,_Z6onExitv + la a1,t + la a2,__dso_handle + sd ra,8(sp) + call __cxa_atexit@plt + li a0,1 + call llvm_jitlink_setTestResultOverride@plt + ld ra,8(sp) + li a0,0 + addi sp,sp,16 + jr ra + .size main, .-main + .globl t + .section .sbss,"aw",@nobits + .align 3 + .type t, @object + .size t, 1 +t: + .zero 1 + .hidden __dso_handle + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-static-initializer.S b/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-static-initializer.S new file mode 100644 --- /dev/null +++ b/compiler-rt/test/orc/TestCases/Linux/riscv64/trivial-static-initializer.S @@ -0,0 +1,34 @@ +// Test that basic ELF static initializers work. The main function in this +// test returns the value of 'x', which is initially 1 in the data section, +// and reset to 0 if the _static_init function is run. If the static initializer +// does not run then main will return 1, causing the test to be treated as a +// failure. +// +// RUN: %clang -c -o %t %s +// RUN: %llvm_jitlink %t +// + + .text + .globl main + .p2align 1 +main: + la a0, x + ret + + .p2align 1 +static_init: + la a1, x + li a2, 0 + sd a2, (a1) + ret + + .data + .globl x + .p2align 2 +x: + .long 1 + .size x, 4 + + .section .init_array,"aw",@init_array + .p2align 3 + .quad static_init diff --git a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp --- a/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp @@ -10,6 +10,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h" +#include "llvm/ExecutionEngine/JITLink/riscv.h" #include "llvm/ExecutionEngine/JITLink/x86_64.h" #include "llvm/ExecutionEngine/Orc/DebugUtils.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" @@ -47,6 +48,11 @@ Endianness = support::endianness::little; EdgeKind = jitlink::x86_64::Pointer64; break; + case Triple::riscv64: + PointerSize = 8; + Endianness = support::endianness::little; + EdgeKind = jitlink::riscv::R_RISCV_64; + break; default: llvm_unreachable("Unrecognized architecture"); } @@ -227,6 +233,7 @@ bool ELFNixPlatform::supportedTarget(const Triple &TT) { switch (TT.getArch()) { case Triple::x86_64: + case Triple::riscv64: return true; default: return false;