diff --git a/thcrap/src/compiler_support.h b/thcrap/src/compiler_support.h index e96fd5ec..93291594 100644 --- a/thcrap/src/compiler_support.h +++ b/thcrap/src/compiler_support.h @@ -136,6 +136,15 @@ #define __has_c_attribute(attr) 0 #endif +// C attributes support namespaces according to the C2X +// standard, but MSVC toolsets fail to parse namespaces +// in that location anyway when not parsing as C++. +#if !defined(__cplusplus) && (MSVC_COMPAT && !GCC_COMPAT && !CLANG_COMPAT && !MINGW_COMPAT && !ICC_COMPAT) +#define __has_c_attribute_with_namespace(attr) 0 +#else +#define __has_c_attribute_with_namespace(attr) __has_c_attribute(attr) +#endif + // - GNU Attributes #ifndef __has_attribute #define __has_attribute(attr) 0 @@ -283,7 +292,7 @@ // - [[likely]] Equivalent Attributes #if __has_cpp_attribute(likely) >= 201803L #define TH_LIKELY [[likely]] -#elif __has_c_attribute(clang::likely) +#elif __has_c_attribute_with_namespace(clang::likely) #define TH_LIKELY [[clang::likely]] #else #define TH_LIKELY @@ -292,7 +301,7 @@ // - [[unlikely]] Equivalent Attributes #if __has_cpp_attribute(unlikely) >= 201803L #define TH_UNLIKELY [[unlikely]] -#elif __has_c_attribute(clang::unlikely) +#elif __has_c_attribute_with_namespace(clang::unlikely) #define TH_UNLIKELY [[clang::unlikely]] #else #define TH_UNLIKELY @@ -542,49 +551,59 @@ extern "C++" { #define read_fs_byte(offset) (*(uint8_t __attribute__((address_space(257)))*)((uintptr_t)offset)) #define read_fs_word(offset) (*(uint16_t __attribute__((address_space(257)))*)((uintptr_t)offset)) #define read_fs_dword(offset) (*(uint32_t __attribute__((address_space(257)))*)((uintptr_t)offset)) +#define read_fs_qword(offset) (*(uint64_t __attribute__((address_space(257)))*)((uintptr_t)offset)) #define write_fs_byte(offset, data) ((void)(*(uint8_t __attribute__((address_space(257)))*)((uintptr_t)offset) = (uint8_t)(data))) #define write_fs_word(offset, data) ((void)(*(uint16_t __attribute__((address_space(257)))*)((uintptr_t)offset) = (uint16_t)(data))) #define write_fs_dword(offset, data) ((void)(*(uint32_t __attribute__((address_space(257)))*)((uintptr_t)offset) = (uint32_t)(data))) -#elif defined(__SEG_FS) && (CLANG_COMPAT || !defined(__cplusplus)) // __seg_fs isn't recognized by GCC when compiling C++ +#define write_fs_qword(offset, data) ((void)(*(uint64_t __attribute__((address_space(257)))*)((uintptr_t)offset) = (uint64_t)(data))) +#elif defined(__SEG_FS) +#if CLANG_COMPAT || !defined(__cplusplus) // __seg_fs isn't recognized by GCC when compiling C++ #define read_fs_byte(offset) (*(__seg_fs uint8_t*)((uintptr_t)offset)) #define read_fs_word(offset) (*(__seg_fs uint16_t*)((uintptr_t)offset)) #define read_fs_dword(offset) (*(__seg_fs uint32_t*)((uintptr_t)offset)) +#define read_fs_qword(offset) (*(__seg_fs uint64_t*)((uintptr_t)offset)) #define write_fs_byte(offset, data) ((void)(*(__seg_fs uint8_t*)((uintptr_t)offset) = (uint8_t)(data))) #define write_fs_word(offset, data) ((void)(*(__seg_fs uint16_t*)((uintptr_t)offset) = (uint16_t)(data))) #define write_fs_dword(offset, data) ((void)(*(__seg_fs uint32_t*)((uintptr_t)offset) = (uint32_t)(data))) -#elif GCC_COMPAT -#ifdef __cplusplus +#define write_fs_qword(offset, data) ((void)(*(__seg_fs uint64_t*)((uintptr_t)offset) = (uint64_t)(data))) +#else extern "C" { -#endif -#define read_fs_byte(offset) read_fs_byte_gcc(offset) -#define read_fs_word(offset) read_fs_word_gcc(offset) -#define read_fs_dword(offset) read_fs_dword_gcc(offset) -#define write_fs_byte(offset, data) write_fs_byte_gcc(offset, data) -#define write_fs_word(offset, data) write_fs_word_gcc(offset, data) -#define write_fs_dword(offset, data) write_fs_dword_gcc(offset, data) uint8_t read_fs_byte_gcc(size_t offset); uint16_t read_fs_word_gcc(size_t offset); uint32_t read_fs_dword_gcc(size_t offset); +uint32_t read_fs_qword_gcc(size_t offset); void write_fs_byte_gcc(size_t offset, uint8_t data); void write_fs_word_gcc(size_t offset, uint16_t data); void write_fs_dword_gcc(size_t offset, uint32_t data); -#ifdef __cplusplus +void write_fs_qword_gcc(size_t offset, uint32_t data); }; +#define read_fs_byte(offset) read_fs_byte_gcc(offset) +#define read_fs_word(offset) read_fs_word_gcc(offset) +#define read_fs_dword(offset) read_fs_dword_gcc(offset) +#define read_fs_qword(offset) read_fs_qword_gcc(offset) +#define write_fs_byte(offset, data) write_fs_byte_gcc(offset, data) +#define write_fs_word(offset, data) write_fs_word_gcc(offset, data) +#define write_fs_dword(offset, data) write_fs_dword_gcc(offset, data) +#define write_fs_qword(offset, data) write_fs_qword_gcc(offset, data) #endif #elif MSVC_COMPAT #define read_fs_byte(offset) __readfsbyte(offset) #define read_fs_word(offset) __readfsword(offset) #define read_fs_dword(offset) __readfsdword(offset) +#define read_fs_qword(offset) __readfsqword(offset) #define write_fs_byte(offset, data) __writefsbyte(offset, data) #define write_fs_word(offset, data) __writefsword(offset, data) #define write_fs_dword(offset, data) __writefsdword(offset, data) +#define write_fs_qword(offset, data) __writefsqword(offset, data) #else #define read_fs_byte(offset) (*(uint8_t*)((uintptr_t)offset)) #define read_fs_word(offset) (*(uint16_t*)((uintptr_t)offset)) #define read_fs_dword(offset) (*(uint32_t*)((uintptr_t)offset)) +#define read_fs_qword(offset) (*(uint64_t*)((uintptr_t)offset)) #define write_fs_byte(offset, data) ((void)(*(uint8_t*)((uintptr_t)offset) = (uint8_t)(data))) #define write_fs_word(offset, data) ((void)(*(uint16_t*)((uintptr_t)offset) = (uint16_t)(data))) #define write_fs_dword(offset, data) ((void)(*(uint32_t*)((uintptr_t)offset) = (uint32_t)(data))) +#define write_fs_qword(offset, data) ((void)(*(uint64_t*)((uintptr_t)offset) = (uint64_t)(data))) #endif #if __has_attribute(address_space) #define read_gs_byte(offset) (*(uint8_t __attribute__((address_space(256)))*)((uintptr_t)offset)) @@ -595,7 +614,8 @@ void write_fs_dword_gcc(size_t offset, uint32_t data); #define write_gs_word(offset, data) ((void)(*(uint16_t __attribute__((address_space(256)))*)((uintptr_t)offset) = (uint16_t)(data))) #define write_gs_dword(offset, data) ((void)(*(uint32_t __attribute__((address_space(256)))*)((uintptr_t)offset) = (uint32_t)(data))) #define write_gs_qword(offset, data) ((void)(*(uint64_t __attribute__((address_space(256)))*)((uintptr_t)offset) = (uint64_t)(data))) -#elif defined(__SEG_GS) && (CLANG_COMPAT || !defined(__cplusplus)) // __seg_gs isn't recognized by GCC when compiling C++ +#elif defined(__SEG_GS) +#if CLANG_COMPAT || !defined(__cplusplus) // __seg_gs isn't recognized by GCC when compiling C++ #define read_gs_byte(offset) (*(__seg_gs uint8_t*)((uintptr_t)offset)) #define read_gs_word(offset) (*(__seg_gs uint16_t*)((uintptr_t)offset)) #define read_gs_dword(offset) (*(__seg_gs uint32_t*)((uintptr_t)offset)) @@ -604,18 +624,8 @@ void write_fs_dword_gcc(size_t offset, uint32_t data); #define write_gs_word(offset, data) ((void)(*(__seg_gs uint16_t*)((uintptr_t)offset) = (uint16_t)(data))) #define write_gs_dword(offset, data) ((void)(*(__seg_gs uint32_t*)((uintptr_t)offset) = (uint32_t)(data))) #define write_gs_qword(offset, data) ((void)(*(__seg_gs uint64_t*)((uintptr_t)offset) = (uint64_t)(data))) -#elif GCC_COMPAT -#ifdef __cplusplus +#else extern "C" { -#endif -#define read_gs_byte(offset) read_gs_byte_gcc(offset) -#define read_gs_word(offset) read_gs_word_gcc(offset) -#define read_gs_dword(offset) read_gs_dword_gcc(offset) -#define read_gs_qword(offset) read_gs_qword_gcc(offset) -#define write_gs_byte(offset, data) write_gs_byte_gcc(offset, data) -#define write_gs_word(offset, data) write_gs_word_gcc(offset, data) -#define write_gs_dword(offset, data) write_gs_dword_gcc(offset, data) -#define write_gs_qword(offset, data) write_gs_qword_gcc(offset, data) uint8_t read_gs_byte_gcc(size_t offset); uint16_t read_gs_word_gcc(size_t offset); uint32_t read_gs_dword_gcc(size_t offset); @@ -624,8 +634,15 @@ void write_gs_byte_gcc(size_t offset, uint8_t data); void write_gs_word_gcc(size_t offset, uint16_t data); void write_gs_dword_gcc(size_t offset, uint32_t data); void write_gs_qword_gcc(size_t offset, uint64_t data); -#ifdef __cplusplus }; +#define read_gs_byte(offset) read_gs_byte_gcc(offset) +#define read_gs_word(offset) read_gs_word_gcc(offset) +#define read_gs_dword(offset) read_gs_dword_gcc(offset) +#define read_gs_qword(offset) read_gs_qword_gcc(offset) +#define write_gs_byte(offset, data) write_gs_byte_gcc(offset, data) +#define write_gs_word(offset, data) write_gs_word_gcc(offset, data) +#define write_gs_dword(offset, data) write_gs_dword_gcc(offset, data) +#define write_gs_qword(offset, data) write_gs_qword_gcc(offset, data) #endif #elif MSVC_COMPAT #define read_gs_byte(offset) __readgsbyte(offset) @@ -647,7 +664,7 @@ void write_gs_qword_gcc(size_t offset, uint64_t data); #define write_gs_qword(offset, data) ((void)(*(uint64_t*)((uintptr_t)offset) = (uint64_t)(data))) #endif -#ifdef GCC_COMPAT +#if GCC_COMPAT #ifndef __sptr #define __sptr #endif diff --git a/thcrap/src/gcc_gs.c b/thcrap/src/gcc_gs.c index 7c618c59..bc5c1aae 100644 --- a/thcrap/src/gcc_gs.c +++ b/thcrap/src/gcc_gs.c @@ -1,7 +1,7 @@ #include "compiler_support.h" /* - * This file is compiled in GCC in C mode - where __seg_gc works. + * This file is compiled in GCC in C mode - where __seg_fs/__seg_gs works. * So we'll juts use our C macro. */ @@ -20,6 +20,10 @@ uint32_t read_fs_dword_gcc(size_t offset) return read_fs_dword(offset); } +uint64_t read_fs_qword_gcc(size_t offset) { + return read_fs_qword(offset); +} + void write_fs_byte_gcc(size_t offset, uint8_t data) { write_fs_byte(offset, data); @@ -35,6 +39,10 @@ void write_fs_dword_gcc(size_t offset, uint32_t data) write_fs_dword(offset, data); } +void write_fs_qword_gcc(size_t offset, uint64_t data) { + write_fs_qword(offset, data); +} + uint8_t read_gs_byte_gcc(size_t offset) { return read_gs_byte(offset);