libunwind currently supports shadow stack based on the Intel CET and AArch64 GCS technology, but throughout related codes, the Intel-specific keyword, "CET", is used to refer to the generic concept of control-flow integrity/shadow stack. This patch replaces such wordings with architecture-neutral term "shadow stack" (abbr. "shstk") to allow future implementation to avoid using the Intel-specific "CET" term.
64 lines
2.7 KiB
C
64 lines
2.7 KiB
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
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LIBUNWIND_SHADOW_STACK_UNWIND_H
|
|
#define LIBUNWIND_SHADOW_STACK_UNWIND_H
|
|
|
|
#include "libunwind.h"
|
|
|
|
// Currently, CET is implemented on Linux x86 platforms.
|
|
#if defined(_LIBUNWIND_TARGET_LINUX) && defined(__CET__) && defined(__SHSTK__)
|
|
#define _LIBUNWIND_USE_CET 1
|
|
#endif
|
|
|
|
#if defined(_LIBUNWIND_USE_CET)
|
|
#include <cet.h>
|
|
#include <immintrin.h>
|
|
|
|
#define _LIBUNWIND_POP_SHSTK_SSP(x) \
|
|
do { \
|
|
unsigned long ssp = _get_ssp(); \
|
|
if (ssp != 0) { \
|
|
unsigned int tmp = (x); \
|
|
while (tmp > 255) { \
|
|
_inc_ssp(255); \
|
|
tmp -= 255; \
|
|
} \
|
|
_inc_ssp(tmp); \
|
|
} \
|
|
} while (0)
|
|
#endif
|
|
|
|
// On AArch64 we use _LIBUNWIND_USE_GCS to indicate that GCS is supported. We
|
|
// need to guard any use of GCS instructions with __chkfeat though, as GCS may
|
|
// not be enabled.
|
|
#if defined(_LIBUNWIND_TARGET_AARCH64) && defined(__ARM_FEATURE_GCS_DEFAULT)
|
|
#include <arm_acle.h>
|
|
|
|
// We can only use GCS if arm_acle.h defines the GCS intrinsics.
|
|
#ifdef _CHKFEAT_GCS
|
|
#define _LIBUNWIND_USE_GCS 1
|
|
#endif
|
|
|
|
#define _LIBUNWIND_POP_SHSTK_SSP(x) \
|
|
do { \
|
|
if (__chkfeat(_CHKFEAT_GCS)) { \
|
|
unsigned tmp = (x); \
|
|
while (tmp--) \
|
|
__gcspopm(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
extern void *__libunwind_shstk_get_registers(unw_cursor_t *);
|
|
extern void *__libunwind_shstk_get_jump_target(void);
|
|
|
|
#endif
|