ams: support building unit test programs on windows/linux/macos
This commit is contained in:
@@ -21,9 +21,11 @@ namespace ams::sf::cmif {
|
||||
return this->ProcessMessageImpl(ctx, static_cast<DomainServiceObject *>(ctx.srv_obj)->GetServerDomain(), in_raw_data);
|
||||
}
|
||||
|
||||
#if AMS_SF_MITM_SUPPORTED
|
||||
Result DomainServiceObjectDispatchTable::ProcessMessageForMitm(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) const {
|
||||
return this->ProcessMessageForMitmImpl(ctx, static_cast<DomainServiceObject *>(ctx.srv_obj)->GetServerDomain(), in_raw_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
Result DomainServiceObjectDispatchTable::ProcessMessageImpl(ServiceDispatchContext &ctx, ServerDomainBase *domain, const cmif::PointerAndSize &in_raw_data) const {
|
||||
const CmifDomainInHeader *in_header = reinterpret_cast<const CmifDomainInHeader *>(in_raw_data.GetPointer());
|
||||
@@ -59,6 +61,7 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
}
|
||||
|
||||
#if AMS_SF_MITM_SUPPORTED
|
||||
Result DomainServiceObjectDispatchTable::ProcessMessageForMitmImpl(ServiceDispatchContext &ctx, ServerDomainBase *domain, const cmif::PointerAndSize &in_raw_data) const {
|
||||
const CmifDomainInHeader *in_header = reinterpret_cast<const CmifDomainInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
@@ -106,6 +109,7 @@ namespace ams::sf::cmif {
|
||||
return sf::cmif::ResultInvalidInHeader();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Result DomainServiceObjectProcessor::PrepareForProcess(const ServiceDispatchContext &ctx, const ServerMessageRuntimeMetadata runtime_metadata) const {
|
||||
/* Validate in object count. */
|
||||
|
||||
@@ -21,25 +21,36 @@ namespace ams::sf {
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext(os::ThreadType *thread) {
|
||||
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<uintptr_t>));
|
||||
return reinterpret_cast<std::atomic<uintptr_t> *>(std::addressof(thread->atomic_sf_inline_context));
|
||||
}
|
||||
#if !defined(ATMOSPHERE_COMPILER_CLANG)
|
||||
ALWAYS_INLINE util::AtomicRef<uintptr_t> GetAtomicSfInlineContext(os::ThreadType *thread = os::GetCurrentThread()) {
|
||||
uintptr_t * const p = std::addressof(os::GetSdkInternalTlsArray(thread)->sf_inline_context);
|
||||
|
||||
ALWAYS_INLINE std::atomic<uintptr_t> *GetAtomicSfInlineContext() {
|
||||
return GetAtomicSfInlineContext(os::GetCurrentThread());
|
||||
return util::AtomicRef<uintptr_t>(*p);
|
||||
}
|
||||
#else
|
||||
ALWAYS_INLINE util::Atomic<uintptr_t> &GetAtomicSfInlineContext(os::ThreadType *thread = os::GetCurrentThread()) {
|
||||
uintptr_t * const p = std::addressof(os::GetSdkInternalTlsArray(thread)->sf_inline_context);
|
||||
static_assert(sizeof(std::atomic<uintptr_t>) == sizeof(uintptr_t));
|
||||
static_assert(sizeof(util::Atomic<uintptr_t>) == sizeof(std::atomic<uintptr_t>));
|
||||
|
||||
return *reinterpret_cast<util::Atomic<uintptr_t> *>(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
ALWAYS_INLINE void OnSetInlineContext(os::ThreadType *thread) {
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
/* Ensure that libnx receives the priority value. */
|
||||
::fsSetPriority(static_cast<::FsPriority>(::ams::sf::GetFsInlineContext(thread)));
|
||||
#else
|
||||
AMS_UNUSED(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InlineContext GetInlineContext() {
|
||||
/* Get the context. */
|
||||
uintptr_t thread_context = GetAtomicSfInlineContext()->load();
|
||||
uintptr_t thread_context = GetAtomicSfInlineContext().Load();
|
||||
|
||||
/* Copy it out. */
|
||||
InlineContext ctx;
|
||||
@@ -59,7 +70,7 @@ namespace ams::sf {
|
||||
std::memcpy(std::addressof(new_context_value), std::addressof(ctx), sizeof(ctx));
|
||||
|
||||
/* Get the old context. */
|
||||
uintptr_t old_context_value = GetAtomicSfInlineContext(cur_thread)->exchange(new_context_value);
|
||||
uintptr_t old_context_value = GetAtomicSfInlineContext(cur_thread).Exchange(new_context_value);
|
||||
|
||||
/* Convert and copy it out. */
|
||||
InlineContext old_ctx;
|
||||
@@ -71,21 +82,32 @@ namespace ams::sf {
|
||||
|
||||
namespace {
|
||||
|
||||
ALWAYS_INLINE std::atomic<u8> *GetAtomicFsInlineContext(os::ThreadType *thread) {
|
||||
static_assert(sizeof(thread->atomic_sf_inline_context) >= sizeof(std::atomic<u8>));
|
||||
return reinterpret_cast<std::atomic<u8> *>(std::addressof(thread->atomic_sf_inline_context));
|
||||
#if !defined(ATMOSPHERE_COMPILER_CLANG)
|
||||
ALWAYS_INLINE util::AtomicRef<u8> GetAtomicFsInlineContext(os::ThreadType *thread) {
|
||||
uintptr_t * const p = std::addressof(os::GetSdkInternalTlsArray(thread)->sf_inline_context);
|
||||
|
||||
return util::AtomicRef<u8>(*reinterpret_cast<u8 *>(p));
|
||||
}
|
||||
#else
|
||||
ALWAYS_INLINE util::Atomic<u8> &GetAtomicFsInlineContext(os::ThreadType *thread) {
|
||||
uintptr_t * const p = std::addressof(os::GetSdkInternalTlsArray(thread)->sf_inline_context);
|
||||
static_assert(sizeof(std::atomic<u8>) == sizeof(u8));
|
||||
static_assert(sizeof(util::Atomic<u8>) == sizeof(std::atomic<u8>));
|
||||
|
||||
return *reinterpret_cast<util::Atomic<u8> *>(reinterpret_cast<u8 *>(p));
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
u8 GetFsInlineContext(os::ThreadType *thread) {
|
||||
return GetAtomicFsInlineContext(thread)->load();
|
||||
return GetAtomicFsInlineContext(thread).Load();
|
||||
}
|
||||
|
||||
u8 SetFsInlineContext(os::ThreadType *thread, u8 ctx) {
|
||||
ON_SCOPE_EXIT { cmif::OnSetInlineContext(thread); };
|
||||
|
||||
return GetAtomicFsInlineContext(thread)->exchange(ctx);
|
||||
return GetAtomicFsInlineContext(thread).Exchange(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,13 @@ namespace ams::sf::cmif {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr inline u32 InHeaderMagic = util::FourCC<'S','F','C','I'>::Code;
|
||||
constexpr inline u32 OutHeaderMagic = util::FourCC<'S','F','C','O'>::Code;
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
static_assert(InHeaderMagic == CMIF_IN_HEADER_MAGIC);
|
||||
static_assert(OutHeaderMagic == CMIF_OUT_HEADER_MAGIC);
|
||||
#endif
|
||||
|
||||
ALWAYS_INLINE decltype(ServiceCommandMeta::handler) FindCommandHandlerByBinarySearch(const ServiceCommandMeta *entries, const size_t entry_count, const u32 cmd_id, const hos::Version hos_version) {
|
||||
/* Binary search for the handler. */
|
||||
ssize_t lo = 0;
|
||||
@@ -84,7 +91,7 @@ namespace ams::sf::cmif {
|
||||
/* Parse the CMIF in header. */
|
||||
const CmifInHeader *in_header = reinterpret_cast<const CmifInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader());
|
||||
R_UNLESS(in_header->magic == InHeaderMagic && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader());
|
||||
const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header));
|
||||
const u32 cmd_id = in_header->command_id;
|
||||
|
||||
@@ -108,11 +115,12 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
|
||||
/* Write output header to raw data. */
|
||||
*out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result.GetValue(), 0};
|
||||
*out_header = CmifOutHeader{OutHeaderMagic, 0, command_result.GetValue(), 0};
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
#if AMS_SF_MITM_SUPPORTED
|
||||
Result impl::ServiceDispatchTableBase::ProcessMessageForMitmImpl(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const ServiceCommandMeta *entries, const size_t entry_count) const {
|
||||
/* Get versioning info. */
|
||||
const auto hos_version = hos::GetVersion();
|
||||
@@ -121,7 +129,7 @@ namespace ams::sf::cmif {
|
||||
/* Parse the CMIF in header. */
|
||||
const CmifInHeader *in_header = reinterpret_cast<const CmifInHeader *>(in_raw_data.GetPointer());
|
||||
R_UNLESS(in_raw_data.GetSize() >= sizeof(*in_header), sf::cmif::ResultInvalidHeaderSize());
|
||||
R_UNLESS(in_header->magic == CMIF_IN_HEADER_MAGIC && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader());
|
||||
R_UNLESS(in_header->magic == InHeaderMagic && in_header->version <= max_cmif_version, sf::cmif::ResultInvalidInHeader());
|
||||
const cmif::PointerAndSize in_message_raw_data = cmif::PointerAndSize(in_raw_data.GetAddress() + sizeof(*in_header), in_raw_data.GetSize() - sizeof(*in_header));
|
||||
const u32 cmd_id = in_header->command_id;
|
||||
|
||||
@@ -154,9 +162,10 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
|
||||
/* Write output header to raw data. */
|
||||
*out_header = CmifOutHeader{CMIF_OUT_HEADER_MAGIC, 0, command_result.GetValue(), 0};
|
||||
*out_header = CmifOutHeader{OutHeaderMagic, 0, command_result.GetValue(), 0};
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user