mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-21 18:22:33 +01:00
Fix SAFE_BUFFERS attribute for GCC
This commit is contained in:
parent
3e496f6625
commit
4f8cac731b
@ -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(),
|
||||
|
@ -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)));
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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]]
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user