Fix SAFE_BUFFERS attribute for GCC

This commit is contained in:
Nekotekina 2021-02-09 12:33:50 +03:00
parent 3e496f6625
commit 4f8cac731b
7 changed files with 33 additions and 29 deletions

View File

@ -119,7 +119,7 @@ struct fmt_class_string
using type = T;
// Helper function (converts arg to object reference)
static SAFE_BUFFERS FORCE_INLINE const T& get_object(u64 arg)
static FORCE_INLINE SAFE_BUFFERS(const T&) get_object(u64 arg)
{
return *reinterpret_cast<const T*>(static_cast<uptr>(arg));
}
@ -128,7 +128,7 @@ struct fmt_class_string
using convert_t = const char*(*)(T value);
// Helper function (safely converts arg to enum value)
static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, convert_t convert)
static FORCE_INLINE SAFE_BUFFERS(void) format_enum(std::string& out, u64 arg, convert_t convert)
{
const auto value = static_cast<std::underlying_type_t<T>>(arg);
@ -147,7 +147,7 @@ struct fmt_class_string
}
// Helper function (bitset formatting)
static SAFE_BUFFERS FORCE_INLINE void format_bitset(std::string& out, u64 arg, const char* prefix, const char* delim, const char* suffix, void (*fmt)(std::string&, u64))
static FORCE_INLINE SAFE_BUFFERS(void) format_bitset(std::string& out, u64 arg, const char* prefix, const char* delim, const char* suffix, void (*fmt)(std::string&, u64))
{
// Start from raw value
fmt_class_string<u64>::format(out, arg);
@ -249,7 +249,7 @@ namespace fmt
};
template <typename... Args>
SAFE_BUFFERS FORCE_INLINE const fmt_type_info* get_type_info()
FORCE_INLINE SAFE_BUFFERS(const fmt_type_info*) get_type_info()
{
// Constantly initialized null-terminated list of type-specific information
static constexpr fmt_type_info result[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};
@ -265,7 +265,7 @@ namespace fmt
// Formatting function
template <typename CharT, usz N, typename... Args>
SAFE_BUFFERS FORCE_INLINE void append(std::string& out, const CharT(&fmt)[N], const Args&... args)
FORCE_INLINE SAFE_BUFFERS(void) append(std::string& out, const CharT(&fmt)[N], const Args&... args)
{
static constexpr fmt_type_info type_list[sizeof...(Args) + 1]{fmt_type_info::make<fmt_unveil_t<Args>>()...};
raw_append(out, reinterpret_cast<const char*>(fmt), type_list, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...});
@ -273,7 +273,7 @@ namespace fmt
// Formatting function
template <typename CharT, usz N, typename... Args>
SAFE_BUFFERS FORCE_INLINE std::string format(const CharT(&fmt)[N], const Args&... args)
FORCE_INLINE SAFE_BUFFERS(std::string) format(const CharT(&fmt)[N], const Args&... args)
{
std::string result;
append(result, fmt, args...);
@ -287,7 +287,7 @@ namespace fmt
template <typename CharT, usz N, typename... Args>
struct throw_exception
{
[[noreturn]] SAFE_BUFFERS FORCE_INLINE throw_exception(const CharT(&fmt)[N], const Args&... args,
[[noreturn]] FORCE_INLINE SAFE_BUFFERS() throw_exception(const CharT(&fmt)[N], const Args&... args,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),

View File

@ -185,7 +185,7 @@ extern __m128 sse_log2_ps(__m128 A)
return _mm_add_ps(_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(x5, x6), x7), x4), _c), _mm_add_ps(_mm_mul_ps(x4, _c), x8));
}
extern SAFE_BUFFERS __m128i sse_pshufb(__m128i data, __m128i index)
extern SAFE_BUFFERS(__m128i) sse_pshufb(__m128i data, __m128i index)
{
v128 m = v128::fromV(_mm_and_si128(index, _mm_set1_epi8(0xf)));
v128 a = v128::fromV(data);
@ -208,7 +208,7 @@ extern SSSE3_FUNC __m128i sse_altivec_vperm(__m128i A, __m128i B, __m128i C)
return _mm_or_si128(_mm_and_si128(mask, sa), _mm_andnot_si128(mask, sb));
}
extern SAFE_BUFFERS __m128i sse_altivec_vperm_v0(__m128i A, __m128i B, __m128i C)
extern SAFE_BUFFERS(__m128i) sse_altivec_vperm_v0(__m128i A, __m128i B, __m128i C)
{
__m128i ab[2]{B, A};
v128 index = v128::fromV(_mm_andnot_si128(C, _mm_set1_epi8(0x1f)));

View File

@ -89,7 +89,7 @@ namespace vm
void reservation_op_internal(u32 addr, std::function<bool()> func);
template <bool Ack = false, typename CPU, typename T, typename AT = u32, typename F>
SAFE_BUFFERS inline auto reservation_op(CPU& cpu, _ptr_base<T, AT> ptr, F op)
inline SAFE_BUFFERS(auto) reservation_op(CPU& cpu, _ptr_base<T, AT> ptr, F op)
{
// Atomic operation will be performed on aligned 128 bytes of data, so the data size and alignment must comply
static_assert(sizeof(T) <= 128 && alignof(T) == sizeof(T), "vm::reservation_op: unsupported type");
@ -328,7 +328,7 @@ namespace vm
// Read memory value in pseudo-atomic manner
template <typename CPU, typename T, typename AT = u32, typename F>
SAFE_BUFFERS inline auto peek_op(CPU&& cpu, _ptr_base<T, AT> ptr, F op)
inline SAFE_BUFFERS(auto) peek_op(CPU&& cpu, _ptr_base<T, AT> ptr, F op)
{
// Atomic operation will be performed on aligned 128 bytes of data, so the data size and alignment must comply
static_assert(sizeof(T) <= 128 && alignof(T) == sizeof(T), "vm::peek_op: unsupported type");
@ -376,7 +376,7 @@ namespace vm
}
template <bool Ack = false, typename T, typename F>
SAFE_BUFFERS inline auto light_op(T& data, F op)
inline SAFE_BUFFERS(auto) light_op(T& data, F op)
{
// Optimized real ptr -> vm ptr conversion, simply UB if out of range
const u32 addr = static_cast<u32>(reinterpret_cast<const u8*>(&data) - g_base_addr);
@ -428,7 +428,7 @@ namespace vm
}
template <bool Ack = false, typename T, typename F>
SAFE_BUFFERS inline auto atomic_op(T& data, F op)
inline SAFE_BUFFERS(auto) atomic_op(T& data, F op)
{
return light_op<Ack, T>(data, [&](T& data)
{
@ -437,7 +437,7 @@ namespace vm
}
template <bool Ack = false, typename T, typename F>
SAFE_BUFFERS inline auto fetch_op(T& data, F op)
inline SAFE_BUFFERS(auto) fetch_op(T& data, F op)
{
return light_op<Ack, T>(data, [&](T& data)
{

View File

@ -72,7 +72,7 @@ void perf_stat_base::print(const char* name) noexcept
extern "C" void _mm_lfence();
#endif
SAFE_BUFFERS void perf_stat_base::push(u64 data[66], u64 start_time, const char* name) noexcept
SAFE_BUFFERS(void) perf_stat_base::push(u64 data[66], u64 start_time, const char* name) noexcept
{
// Event end
#ifdef _MSC_VER

View File

@ -88,7 +88,7 @@ class perf_stat final : public perf_stat_base
} g_tls_perf_stat;
public:
static SAFE_BUFFERS FORCE_INLINE void push(u64 start_time) noexcept
static FORCE_INLINE SAFE_BUFFERS(void) push(u64 start_time) noexcept
{
perf_stat_base::push(g_tls_perf_stat.m_log, start_time, perf_name<ShortName>.data());
}
@ -102,21 +102,21 @@ class perf_meter
u64 m_timestamps[1 + sizeof...(SubEvents)];
public:
SAFE_BUFFERS FORCE_INLINE perf_meter() noexcept
FORCE_INLINE SAFE_BUFFERS() perf_meter() noexcept
{
restart();
}
// Copy first timestamp
template <auto SN, auto... S>
SAFE_BUFFERS FORCE_INLINE perf_meter(const perf_meter<SN, S...>& r) noexcept
FORCE_INLINE SAFE_BUFFERS() perf_meter(const perf_meter<SN, S...>& r) noexcept
{
m_timestamps[0] = r.get();
std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64));
}
template <auto SN, auto... S>
SAFE_BUFFERS perf_meter(perf_meter<SN, S...>&& r) noexcept
SAFE_BUFFERS() perf_meter(perf_meter<SN, S...>&& r) noexcept
{
m_timestamps[0] = r.get();
r.reset();
@ -124,14 +124,14 @@ public:
// Copy first timestamp
template <auto SN, auto... S>
SAFE_BUFFERS perf_meter& operator =(const perf_meter<SN, S...>& r) noexcept
SAFE_BUFFERS(perf_meter&) operator =(const perf_meter<SN, S...>& r) noexcept
{
m_timestamps[0] = r.get();
return *this;
}
template <auto SN, auto... S>
SAFE_BUFFERS perf_meter& operator =(perf_meter<SN, S...>& r) noexcept
SAFE_BUFFERS(perf_meter&) operator =(perf_meter<SN, S...>& r) noexcept
{
m_timestamps[0] = r.get();
r.reset();
@ -140,7 +140,7 @@ public:
// Push subevent data in array
template <auto Event, usz Index = 0>
SAFE_BUFFERS void push() noexcept
SAFE_BUFFERS(void) push() noexcept
{
// TODO: should use more efficient search with type comparison, then value comparison, or pattern matching
if constexpr (std::array<bool, sizeof...(SubEvents)>{(SubEvents == Event)...}[Index])
@ -162,19 +162,19 @@ public:
}
// Disable this counter
SAFE_BUFFERS FORCE_INLINE void reset() noexcept
FORCE_INLINE SAFE_BUFFERS(void) reset() noexcept
{
m_timestamps[0] = 0;
}
// Re-initialize first timestamp
SAFE_BUFFERS FORCE_INLINE void restart() noexcept
FORCE_INLINE SAFE_BUFFERS(void) restart() noexcept
{
m_timestamps[0] = get_tsc();
std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64));
}
SAFE_BUFFERS ~perf_meter()
SAFE_BUFFERS() ~perf_meter()
{
// Disabled counter
if (!m_timestamps[0]) [[unlikely]]

View File

@ -1041,7 +1041,7 @@ FORCE_INLINE auto root_info::slot_search(uptr iptr, u32 size, u64 thread_id, u12
}
}
SAFE_BUFFERS void atomic_wait_engine::wait(const void* data, u32 size, u128 old_value, u64 timeout, u128 mask, atomic_wait::info* ext)
SAFE_BUFFERS(void) atomic_wait_engine::wait(const void* data, u32 size, u128 old_value, u64 timeout, u128 mask, atomic_wait::info* ext)
{
const auto stamp0 = utils::get_unique_tsc();
@ -1531,7 +1531,7 @@ void atomic_wait_engine::notify_one(const void* data, u32 size, u128 mask, u128
s_tls_notify_cb(data, -1);
}
SAFE_BUFFERS void atomic_wait_engine::notify_all(const void* data, u32 size, u128 mask)
SAFE_BUFFERS(void) atomic_wait_engine::notify_all(const void* data, u32 size, u128 mask)
{
const uptr iptr = reinterpret_cast<uptr>(data) & (~s_ref_mask >> 17);

View File

@ -24,11 +24,15 @@ using namespace std::literals;
#endif
#ifdef _MSC_VER
#define SAFE_BUFFERS __declspec(safebuffers)
#define SAFE_BUFFERS(...) __declspec(safebuffers) __VA_ARGS__
#define NEVER_INLINE __declspec(noinline)
#define FORCE_INLINE __forceinline
#else // not _MSC_VER
#define SAFE_BUFFERS __attribute__((no_stack_protector))
#ifdef __clang__
#define SAFE_BUFFERS(...) __attribute__((no_stack_protector)) __VA_ARGS__
#else
#define SAFE_BUFFERS(...) __VA_ARGS__ __attribute__((__optimize__("no-stack-protector")))
#endif
#define NEVER_INLINE __attribute__((noinline)) inline
#define FORCE_INLINE __attribute__((always_inline)) inline
#endif // _MSC_VER