1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

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; using type = T;
// Helper function (converts arg to object reference) // 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)); return *reinterpret_cast<const T*>(static_cast<uptr>(arg));
} }
@ -128,7 +128,7 @@ struct fmt_class_string
using convert_t = const char*(*)(T value); using convert_t = const char*(*)(T value);
// Helper function (safely converts arg to enum 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); const auto value = static_cast<std::underlying_type_t<T>>(arg);
@ -147,7 +147,7 @@ struct fmt_class_string
} }
// Helper function (bitset formatting) // 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 // Start from raw value
fmt_class_string<u64>::format(out, arg); fmt_class_string<u64>::format(out, arg);
@ -249,7 +249,7 @@ namespace fmt
}; };
template <typename... Args> 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 // 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>>()...}; 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 // Formatting function
template <typename CharT, usz N, typename... Args> 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>>()...}; 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)...}); 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 // Formatting function
template <typename CharT, usz N, typename... Args> 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; std::string result;
append(result, fmt, args...); append(result, fmt, args...);
@ -287,7 +287,7 @@ namespace fmt
template <typename CharT, usz N, typename... Args> template <typename CharT, usz N, typename... Args>
struct throw_exception 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 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(), u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(), 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)); 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 m = v128::fromV(_mm_and_si128(index, _mm_set1_epi8(0xf)));
v128 a = v128::fromV(data); 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)); 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}; __m128i ab[2]{B, A};
v128 index = v128::fromV(_mm_andnot_si128(C, _mm_set1_epi8(0x1f))); 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); void reservation_op_internal(u32 addr, std::function<bool()> func);
template <bool Ack = false, typename CPU, typename T, typename AT = u32, typename F> 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 // 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"); 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 // Read memory value in pseudo-atomic manner
template <typename CPU, typename T, typename AT = u32, typename F> 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 // 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"); 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> 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 // 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); 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> 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) return light_op<Ack, T>(data, [&](T& data)
{ {
@ -437,7 +437,7 @@ namespace vm
} }
template <bool Ack = false, typename T, typename F> 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) 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(); extern "C" void _mm_lfence();
#endif #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 // Event end
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -88,7 +88,7 @@ class perf_stat final : public perf_stat_base
} g_tls_perf_stat; } g_tls_perf_stat;
public: 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()); 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)]; u64 m_timestamps[1 + sizeof...(SubEvents)];
public: public:
SAFE_BUFFERS FORCE_INLINE perf_meter() noexcept FORCE_INLINE SAFE_BUFFERS() perf_meter() noexcept
{ {
restart(); restart();
} }
// Copy first timestamp // Copy first timestamp
template <auto SN, auto... S> 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(); m_timestamps[0] = r.get();
std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64)); std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64));
} }
template <auto SN, auto... S> 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(); m_timestamps[0] = r.get();
r.reset(); r.reset();
@ -124,14 +124,14 @@ public:
// Copy first timestamp // Copy first timestamp
template <auto SN, auto... S> 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(); m_timestamps[0] = r.get();
return *this; return *this;
} }
template <auto SN, auto... S> 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(); m_timestamps[0] = r.get();
r.reset(); r.reset();
@ -140,7 +140,7 @@ public:
// Push subevent data in array // Push subevent data in array
template <auto Event, usz Index = 0> 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 // 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]) if constexpr (std::array<bool, sizeof...(SubEvents)>{(SubEvents == Event)...}[Index])
@ -162,19 +162,19 @@ public:
} }
// Disable this counter // Disable this counter
SAFE_BUFFERS FORCE_INLINE void reset() noexcept FORCE_INLINE SAFE_BUFFERS(void) reset() noexcept
{ {
m_timestamps[0] = 0; m_timestamps[0] = 0;
} }
// Re-initialize first timestamp // Re-initialize first timestamp
SAFE_BUFFERS FORCE_INLINE void restart() noexcept FORCE_INLINE SAFE_BUFFERS(void) restart() noexcept
{ {
m_timestamps[0] = get_tsc(); m_timestamps[0] = get_tsc();
std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64)); std::memset(m_timestamps + 1, 0, sizeof(m_timestamps) - sizeof(u64));
} }
SAFE_BUFFERS ~perf_meter() SAFE_BUFFERS() ~perf_meter()
{ {
// Disabled counter // Disabled counter
if (!m_timestamps[0]) [[unlikely]] 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(); 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); 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); const uptr iptr = reinterpret_cast<uptr>(data) & (~s_ref_mask >> 17);

View File

@ -24,11 +24,15 @@ using namespace std::literals;
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
#define SAFE_BUFFERS __declspec(safebuffers) #define SAFE_BUFFERS(...) __declspec(safebuffers) __VA_ARGS__
#define NEVER_INLINE __declspec(noinline) #define NEVER_INLINE __declspec(noinline)
#define FORCE_INLINE __forceinline #define FORCE_INLINE __forceinline
#else // not _MSC_VER #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 NEVER_INLINE __attribute__((noinline)) inline
#define FORCE_INLINE __attribute__((always_inline)) inline #define FORCE_INLINE __attribute__((always_inline)) inline
#endif // _MSC_VER #endif // _MSC_VER