From 4f8cac731b2997c43e2a137df67cac78772d96cc Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 9 Feb 2021 12:33:50 +0300 Subject: [PATCH] Fix SAFE_BUFFERS attribute for GCC --- Utilities/StrFmt.h | 14 +++++++------- rpcs3/Emu/Cell/PPUInterpreter.cpp | 4 ++-- rpcs3/Emu/Memory/vm_reservation.h | 10 +++++----- rpcs3/Emu/perf_meter.cpp | 2 +- rpcs3/Emu/perf_meter.hpp | 20 ++++++++++---------- rpcs3/util/atomic.cpp | 4 ++-- rpcs3/util/types.hpp | 8 ++++++-- 7 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index 92c4d19a7c..6bce1fdcc0 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -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(static_cast(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>(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::format(out, arg); @@ -249,7 +249,7 @@ namespace fmt }; template - 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>()...}; @@ -265,7 +265,7 @@ namespace fmt // Formatting function template - 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>()...}; raw_append(out, reinterpret_cast(fmt), type_list, fmt_args_t{fmt_unveil::get(args)...}); @@ -273,7 +273,7 @@ namespace fmt // Formatting function template - 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 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(), diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index 85cedb234c..abbb97df3b 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -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))); diff --git a/rpcs3/Emu/Memory/vm_reservation.h b/rpcs3/Emu/Memory/vm_reservation.h index c486a7b4ef..a40e42e941 100644 --- a/rpcs3/Emu/Memory/vm_reservation.h +++ b/rpcs3/Emu/Memory/vm_reservation.h @@ -89,7 +89,7 @@ namespace vm void reservation_op_internal(u32 addr, std::function func); template - SAFE_BUFFERS inline auto reservation_op(CPU& cpu, _ptr_base ptr, F op) + inline SAFE_BUFFERS(auto) reservation_op(CPU& cpu, _ptr_base 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 - SAFE_BUFFERS inline auto peek_op(CPU&& cpu, _ptr_base ptr, F op) + inline SAFE_BUFFERS(auto) peek_op(CPU&& cpu, _ptr_base 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 - 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(reinterpret_cast(&data) - g_base_addr); @@ -428,7 +428,7 @@ namespace vm } template - SAFE_BUFFERS inline auto atomic_op(T& data, F op) + inline SAFE_BUFFERS(auto) atomic_op(T& data, F op) { return light_op(data, [&](T& data) { @@ -437,7 +437,7 @@ namespace vm } template - SAFE_BUFFERS inline auto fetch_op(T& data, F op) + inline SAFE_BUFFERS(auto) fetch_op(T& data, F op) { return light_op(data, [&](T& data) { diff --git a/rpcs3/Emu/perf_meter.cpp b/rpcs3/Emu/perf_meter.cpp index f70ef3eb9f..f07ff0ac0b 100644 --- a/rpcs3/Emu/perf_meter.cpp +++ b/rpcs3/Emu/perf_meter.cpp @@ -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 diff --git a/rpcs3/Emu/perf_meter.hpp b/rpcs3/Emu/perf_meter.hpp index 0c5c762585..99ffce1d9a 100644 --- a/rpcs3/Emu/perf_meter.hpp +++ b/rpcs3/Emu/perf_meter.hpp @@ -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.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 - SAFE_BUFFERS FORCE_INLINE perf_meter(const perf_meter& r) noexcept + FORCE_INLINE SAFE_BUFFERS() perf_meter(const perf_meter& r) noexcept { m_timestamps[0] = r.get(); std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64)); } template - SAFE_BUFFERS perf_meter(perf_meter&& r) noexcept + SAFE_BUFFERS() perf_meter(perf_meter&& r) noexcept { m_timestamps[0] = r.get(); r.reset(); @@ -124,14 +124,14 @@ public: // Copy first timestamp template - SAFE_BUFFERS perf_meter& operator =(const perf_meter& r) noexcept + SAFE_BUFFERS(perf_meter&) operator =(const perf_meter& r) noexcept { m_timestamps[0] = r.get(); return *this; } template - SAFE_BUFFERS perf_meter& operator =(perf_meter& r) noexcept + SAFE_BUFFERS(perf_meter&) operator =(perf_meter& r) noexcept { m_timestamps[0] = r.get(); r.reset(); @@ -140,7 +140,7 @@ public: // Push subevent data in array template - 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{(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]] diff --git a/rpcs3/util/atomic.cpp b/rpcs3/util/atomic.cpp index c01f505aa2..8bc7c44b6b 100644 --- a/rpcs3/util/atomic.cpp +++ b/rpcs3/util/atomic.cpp @@ -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(data) & (~s_ref_mask >> 17); diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index ae0e8b7d27..802a2d3908 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -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