From: Vyacheslav Cherkashin Date: Wed, 16 Jun 2021 13:21:55 +0000 (+0300) Subject: [Tizen] Implement ASan wrapper for Linux AMD64 X-Git-Tag: accepted/tizen/unified/20221103.165808~50 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=00bed73747a2ba408feb1f8565f5758fed5035f2;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [Tizen] Implement ASan wrapper for Linux AMD64 Signed-off-by: Vyacheslav Cherkashin Signed-off-by: Slava Barinov --- diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt index 2d943ca5..7c0aa4b 100644 --- a/src/coreclr/vm/CMakeLists.txt +++ b/src/coreclr/vm/CMakeLists.txt @@ -753,6 +753,11 @@ else(CLR_CMAKE_TARGET_WIN32) ${ARCH_SOURCES_DIR}/umthunkstub.S ${ARCH_SOURCES_DIR}/virtualcallstubamd64.S ) + if (TIZEN_ASAN_ENVIRONMENT) + list(APPEND VM_SOURCES_WKS_ARCH_ASM + ${ARCH_SOURCES_DIR}/tizenasanenv.S + ) + endif() elseif(CLR_CMAKE_TARGET_ARCH_I386) set(VM_SOURCES_WKS_ARCH_ASM ${ARCH_SOURCES_DIR}/ehhelpers.S diff --git a/src/coreclr/vm/amd64/cgenamd64.cpp b/src/coreclr/vm/amd64/cgenamd64.cpp index af91cc3..6dbf288 100644 --- a/src/coreclr/vm/amd64/cgenamd64.cpp +++ b/src/coreclr/vm/amd64/cgenamd64.cpp @@ -25,6 +25,10 @@ #include "clrtocomcall.h" #endif // FEATURE_COMINTEROP +#ifdef TIZEN_ASAN_ENVIRONMENT +#include +#endif // TIZEN_ASAN_ENVIRONMENT + void UpdateRegDisplayFromCalleeSavedRegisters(REGDISPLAY * pRD, CalleeSavedRegisters * pRegs) { LIMITED_METHOD_CONTRACT; @@ -526,6 +530,10 @@ void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTarget } CONTRACTL_END; +#ifdef TIZEN_ASAN_ENVIRONMENT + pTargetCode = (BYTE *)TizenASanEnv::CreateWrapperILCode((LPVOID)pTargetCode); +#endif // TIZEN_ASAN_ENVIRONMENT + // padding // CC CC CC CC // mov r10, pUMEntryThunk // 49 ba xx xx xx xx xx xx xx xx // METHODDESC_REGISTER // mov rax, pJmpDest // 48 b8 xx xx xx xx xx xx xx xx // need to ensure this imm64 is qword aligned diff --git a/src/coreclr/vm/amd64/tizenasanenv.S b/src/coreclr/vm/amd64/tizenasanenv.S new file mode 100644 index 0000000..c8735a2 --- /dev/null +++ b/src/coreclr/vm/amd64/tizenasanenv.S @@ -0,0 +1,144 @@ +// Scheme of saving registers to the stack +// +--------+----------------------+ +// | | value | +// | offset | size | register name | +// +--------+------+---------------+ +// | 0x00 | 8 | --- | (returnt addr) +// | -0x08 | 8 | rax | +// | -0x10 | 8 | r11 | +// | -0x18 | 8 | r10 | +// | -0x20 | 8 | r9 | +// | -0x28 | 8 | r8 | +// | -0x30 | 8 | rcx | +// | -0x38 | 8 | rdx | +// | -0x40 | 8 | rsi | +// | -0x48 | 8 | rdi | +// | -0x50 | 16 | xmm7 | +// | -0x60 | 16 | xmm6 | +// | -0x70 | 16 | xmm5 | +// | -0x80 | 16 | xmm4 | +// | -0x90 | 16 | xmm3 | +// | -0xa0 | 16 | xmm2 | +// | -0xb0 | 16 | xmm1 | +// | -0xc0 | 16 | xmm0 | + + +#define GENERAL_SAVED_REGS_COUNT 9 +#define GENERAL_SAVED_REGS_SIZE (8 * GENERAL_SAVED_REGS_COUNT) +.macro PUSH_GENERAL_REGS + push %rdi // 1st argument + push %rsi // 2nd argument + push %rdx // 3rd argument, 2nd return register + push %rcx // 4th argument + push %r8 // 5th argument + push %r9 // 6th argument + push %r10 // 1st return register + push %r11 // temporary register + push %rax // temporary register +.endm + +.macro POP_GENERAL_REGS + pop %rax + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rcx + pop %rdx + pop %rsi + pop %rdi +.endm + +#define XMM_SAVED_REGS_COUNT 8 +#define XMM_SAVED_REGS_SIZE (16 * XMM_SAVED_REGS_COUNT) +.macro PUSH_XMM_REGS + sub $XMM_SAVED_REGS_SIZE, %rsp + movaps %xmm0, 0x00(%rsp) + movaps %xmm1, 0x10(%rsp) + movaps %xmm2, 0x20(%rsp) + movaps %xmm3, 0x30(%rsp) + movaps %xmm4, 0x40(%rsp) + movaps %xmm5, 0x50(%rsp) + movaps %xmm6, 0x60(%rsp) + movaps %xmm7, 0x70(%rsp) +.endm + +.macro POP_XMM_REGS + movaps 0x70(%rsp), %xmm7 + movaps 0x60(%rsp), %xmm6 + movaps 0x50(%rsp), %xmm5 + movaps 0x40(%rsp), %xmm4 + movaps 0x30(%rsp), %xmm3 + movaps 0x20(%rsp), %xmm2 + movaps 0x10(%rsp), %xmm1 + movaps 0x00(%rsp), %xmm0 + add $XMM_SAVED_REGS_SIZE, %rsp +.endm + +#define RETADDR_OFFSET (GENERAL_SAVED_REGS_SIZE + XMM_SAVED_REGS_SIZE) +.macro PUSH_REGS + PUSH_GENERAL_REGS + PUSH_XMM_REGS +.endm + +.macro POP_REGS + POP_XMM_REGS + POP_GENERAL_REGS +.endm + + +// Export symbols +.global tizenASanWrapper +.global tizenASanWrapperSize +.global tizenASanWrapperEntryOffset + +.text +.code64 + +tizenASanWrapper: +// !!! ATTENTION !!! +// Don't move this labels (target, pushAddr, popAddr) +// because they mapped to AuxiliaryCalls struct from src/coreclr/vm/tizenasanenv.cpp +target: .quad 0xdeadbeef0badc0de +pushAddr: .quad 0xdeadbeef0badc0de // void pushAddr(LPVOID addr) +popAddr: .quad 0xdeadbeef0badc0de // LPVOID popAddr() + + +entryPointer: + // Save context + PUSH_REGS + + // Save the return address and call 'pre handler' + mov RETADDR_OFFSET(%rsp), %rdi // rdi: get return address + call *pushAddr(%rip) // save the return address + + // Change the return address + call next +next: + pop %rax // rax: get current rip + add $(postLabel - next), %rax // rax: add offset to 'postLabel' + mov %rax, RETADDR_OFFSET(%rsp) // change the return address + + // Restore context + POP_REGS + + // Call original function + jmp *target(%rip) +postLabel: + sub $8, %rsp // add space for the return addr + + // Save context + PUSH_REGS + + // Get the return address and call 'post handler' + call *popAddr(%rip) // rax: get the return address + mov %rax, (RETADDR_OFFSET)(%rsp) // restore the return address + + // Restore context + POP_REGS + + // Return + ret + +tizenASanWrapperSize: .long . - tizenASanWrapper +tizenASanWrapperEntryOffset: .long entryPointer - tizenASanWrapper