Path: blob/main/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
35233 views
//===-- sanitizer_asm.h -----------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Various support for assembler.9//10//===----------------------------------------------------------------------===//1112// Some toolchains do not support .cfi asm directives, so we have to hide13// them inside macros.14#if defined(__clang__) || \15(defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM))16// GCC defined __GCC_HAVE_DWARF2_CFI_ASM if it supports CFI.17// Clang seems to support CFI by default (or not?).18// We need two versions of macros: for inline asm and standalone asm files.19# define CFI_INL_ADJUST_CFA_OFFSET(n) ".cfi_adjust_cfa_offset " #n ";"2021# define CFI_STARTPROC .cfi_startproc22# define CFI_ENDPROC .cfi_endproc23# define CFI_ADJUST_CFA_OFFSET(n) .cfi_adjust_cfa_offset n24# define CFI_DEF_CFA_OFFSET(n) .cfi_def_cfa_offset n25# define CFI_REL_OFFSET(reg, n) .cfi_rel_offset reg, n26# define CFI_OFFSET(reg, n) .cfi_offset reg, n27# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg28# define CFI_DEF_CFA(reg, n) .cfi_def_cfa reg, n29# define CFI_RESTORE(reg) .cfi_restore reg3031#else // No CFI32# define CFI_INL_ADJUST_CFA_OFFSET(n)33# define CFI_STARTPROC34# define CFI_ENDPROC35# define CFI_ADJUST_CFA_OFFSET(n)36# define CFI_DEF_CFA_OFFSET(n)37# define CFI_REL_OFFSET(reg, n)38# define CFI_OFFSET(reg, n)39# define CFI_DEF_CFA_REGISTER(reg)40# define CFI_DEF_CFA(reg, n)41# define CFI_RESTORE(reg)42#endif4344#if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT)45# define ASM_STARTPROC CFI_STARTPROC; hint #3446# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) "\nhint #34"47#else48# define ASM_STARTPROC CFI_STARTPROC49# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC)50#endif51#define ASM_ENDPROC CFI_ENDPROC52#define C_ASM_ENDPROC SANITIZER_STRINGIFY(CFI_ENDPROC)5354#if defined(__x86_64__) || defined(__i386__) || defined(__sparc__)55# define ASM_TAIL_CALL jmp56#elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \57defined(__powerpc__) || defined(__loongarch_lp64)58# define ASM_TAIL_CALL b59#elif defined(__s390__)60# define ASM_TAIL_CALL jg61#elif defined(__riscv)62# define ASM_TAIL_CALL tail63#endif6465// Currently, almost all of the shared libraries rely on the value of66// $t9 to get the address of current function, instead of PCREL, even67// on MIPSr6. To be compatiable with them, we have to set $t9 properly.68// MIPS uses GOT to get the address of preemptible functions.69#if defined(__mips64)70# define C_ASM_TAIL_CALL(t_func, i_func) \71"lui $t8, %hi(%neg(%gp_rel(" t_func ")))\n" \72"daddu $t8, $t8, $t9\n" \73"daddiu $t8, $t8, %lo(%neg(%gp_rel(" t_func ")))\n" \74"ld $t9, %got_disp(" i_func ")($t8)\n" \75"jr $t9\n"76#elif defined(__mips__)77# define C_ASM_TAIL_CALL(t_func, i_func) \78".set noreorder\n" \79".cpload $t9\n" \80".set reorder\n" \81"lw $t9, %got(" i_func ")($gp)\n" \82"jr $t9\n"83#elif defined(ASM_TAIL_CALL)84# define C_ASM_TAIL_CALL(t_func, i_func) \85SANITIZER_STRINGIFY(ASM_TAIL_CALL) " " i_func86#endif8788#if defined(__ELF__) && defined(__x86_64__) || defined(__i386__) || \89defined(__riscv)90# define ASM_PREEMPTIBLE_SYM(sym) sym@plt91#else92# define ASM_PREEMPTIBLE_SYM(sym) sym93#endif9495#if !defined(__APPLE__)96# define ASM_HIDDEN(symbol) .hidden symbol97# if defined(__arm__) || defined(__aarch64__)98# define ASM_TYPE_FUNCTION(symbol) .type symbol, %function99# else100# define ASM_TYPE_FUNCTION(symbol) .type symbol, @function101# endif102# define ASM_SIZE(symbol) .size symbol, .-symbol103# define ASM_SYMBOL(symbol) symbol104# define ASM_SYMBOL_INTERCEPTOR(symbol) symbol105# if defined(__i386__) || defined(__powerpc__) || defined(__s390__) || \106defined(__sparc__)107// For details, see interception.h108# define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol109# define ASM_TRAMPOLINE_ALIAS(symbol, name) \110.weak symbol; \111.set symbol, ASM_WRAPPER_NAME(name)112# define ASM_INTERCEPTOR_TRAMPOLINE(name)113# define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 0114# else // Architecture supports interceptor trampoline115// Keep trampoline implementation in sync with interception/interception.h116# define ASM_WRAPPER_NAME(symbol) ___interceptor_##symbol117# define ASM_TRAMPOLINE_ALIAS(symbol, name) \118.weak symbol; \119.set symbol, __interceptor_trampoline_##name120# define ASM_INTERCEPTOR_TRAMPOLINE(name) \121.weak __interceptor_##name; \122.set __interceptor_##name, ASM_WRAPPER_NAME(name); \123.globl __interceptor_trampoline_##name; \124ASM_TYPE_FUNCTION(__interceptor_trampoline_##name); \125__interceptor_trampoline_##name: \126ASM_STARTPROC; \127ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name); \128ASM_ENDPROC; \129ASM_SIZE(__interceptor_trampoline_##name)130# define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 1131# endif // Architecture supports interceptor trampoline132#else133# define ASM_HIDDEN(symbol)134# define ASM_TYPE_FUNCTION(symbol)135# define ASM_SIZE(symbol)136# define ASM_SYMBOL(symbol) _##symbol137# define ASM_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol138# define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol139#endif140141#if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \142defined(__Fuchsia__) || defined(__linux__))143// clang-format off144#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits145// clang-format on146#else147#define NO_EXEC_STACK_DIRECTIVE148#endif149150#if (defined(__x86_64__) || defined(__i386__)) && defined(__has_include) && __has_include(<cet.h>)151#include <cet.h>152#endif153#ifndef _CET_ENDBR154#define _CET_ENDBR155#endif156157158