From e6cf70a18aa0c207d88a3280a666aaab93d6fc48 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 04:36:14 -0700 Subject: [PATCH] erpt: actually support non-sequential ids, nintendo why --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 30 +++---- .../include/stratosphere/erpt/erpt_types.hpp | 2 - .../stratosphere/erpt/srv/erpt_srv_types.hpp | 78 ++++++++++++++++--- .../erpt/srv/erpt_srv_context_record.cpp | 6 +- .../source/erpt/srv/erpt_srv_formatter.hpp | 5 +- .../source/erpt/srv/erpt_srv_main.cpp | 4 +- .../source/erpt/srv/erpt_srv_reporter.cpp | 2 +- 7 files changed, 91 insertions(+), 36 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index cb3d3173a..92d6db7dc 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -35,7 +35,7 @@ HANDLER(FieldType_NumericU8, 12) \ HANDLER(FieldType_NumericI16, 13) \ HANDLER(FieldType_NumericI8, 14) \ - HANDLER(FieldType_I8Array, 15) \ + HANDLER(FieldType_I8Array, 15) #define AMS_ERPT_FOREACH_CATEGORY(HANDLER) \ HANDLER(Test, 0 ) \ @@ -180,7 +180,7 @@ HANDLER(EthernetAdapterOUIInfo, 139 ) \ HANDLER(NANDTypeInfo, 140 ) \ HANDLER(MicroSDTypeInfo, 141 ) \ - HANDLER(TestNx, 1000) \ + HANDLER(TestNx, 1000) #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ @@ -355,13 +355,13 @@ HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimitDeprecated, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeConfigurationDeprecated, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizModeDeprecated, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyPathDeprecated, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -371,8 +371,8 @@ HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquiredDeprecated, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequestedDeprecated, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ @@ -436,15 +436,15 @@ HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionRegistersDeprecated, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsrDeprecated, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegistersDeprecated, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ @@ -877,5 +877,5 @@ HANDLER(AdspExceptionArmModeRegisters, 1009, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionStackAddress, 1010, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackDump, 1011, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index 858919f4b..3d31b2c42 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -34,7 +34,6 @@ namespace ams::erpt { enum CategoryId { AMS_ERPT_FOREACH_CATEGORY(GENERATE_ENUM) - CategoryId_Count, }; #undef GENERATE_ENUM @@ -43,7 +42,6 @@ namespace ams::erpt { enum FieldId { AMS_ERPT_FOREACH_FIELD(GENERATE_ENUM) - FieldId_Count, }; #undef GENERATE_ENUM diff --git a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp index a4604743b..348f3cb5f 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp @@ -58,34 +58,88 @@ namespace ams::erpt::srv { }; #undef STRINGIZE_HANDLER - #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = CategoryId_##CATEGORY, - constexpr inline const CategoryId FieldToCategoryMap[] = { + #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) CategoryId_##CATEGORY, + constexpr inline const CategoryId FieldIndexToCategoryMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_CATEGORY) }; #undef GET_FIELD_CATEGORY - #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = TYPE, - constexpr inline const FieldType FieldToTypeMap[] = { + #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) TYPE, + constexpr inline const FieldType FieldIndexToTypeMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_TYPE) }; #undef GET_FIELD_TYPE - #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = FLAG, - constexpr inline const FieldFlag FieldToFlagMap[] = { + #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) FLAG, + constexpr inline const FieldFlag FieldIndexToFlagMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_FLAG) }; #undef GET_FIELD_FLAG - inline CategoryId ConvertFieldToCategory(FieldId id) { - return FieldToCategoryMap[id]; + #define GET_FIELD_ID(FIELD, ...) FieldId_##FIELD, + constexpr inline const FieldId FieldIndexToFieldIdMap[] = { + AMS_ERPT_FOREACH_FIELD(GET_FIELD_ID) + }; + #undef GET_FIELD_ID + + #define GET_CATEGORY_ID(CATEGORY, ...) CategoryId_##CATEGORY, + constexpr inline const CategoryId CategoryIndexToCategoryIdMap[] = { + AMS_ERPT_FOREACH_CATEGORY(GET_CATEGORY_ID) + }; + #undef GET_CATEGORY_ID + + constexpr util::optional FindFieldIndex(FieldId id) { + if (std::is_constant_evaluated()) { + for (size_t i = 0; i < util::size(FieldIndexToFieldIdMap); ++i) { + if (FieldIndexToFieldIdMap[i] == id) { + return i; + } + } + + return util::nullopt; + } else { + if (const auto it = std::lower_bound(std::begin(FieldIndexToFieldIdMap), std::end(FieldIndexToFieldIdMap), id); it != std::end(FieldIndexToFieldIdMap) && *it == id) { + return std::distance(FieldIndexToFieldIdMap, it); + } else { + return util::nullopt; + } + } } - inline FieldType ConvertFieldToType(FieldId id) { - return FieldToTypeMap[id]; + constexpr util::optional FindCategoryIndex(CategoryId id) { + if (std::is_constant_evaluated()) { + for (size_t i = 0; i < util::size(CategoryIndexToCategoryIdMap); ++i) { + if (CategoryIndexToCategoryIdMap[i] == id) { + return i; + } + } + + return util::nullopt; + } else { + if (const auto it = std::lower_bound(std::begin(CategoryIndexToCategoryIdMap), std::end(CategoryIndexToCategoryIdMap), id); it != std::end(CategoryIndexToCategoryIdMap) && *it == id) { + return std::distance(CategoryIndexToCategoryIdMap, it); + } else { + return util::nullopt; + } + } } - inline FieldFlag ConvertFieldToFlag(FieldId id) { - return FieldToFlagMap[id]; + constexpr inline CategoryId ConvertFieldToCategory(FieldId id) { + const auto index = FindFieldIndex(id); + AMS_ASSERT(index.has_value()); + return FieldIndexToCategoryMap[index.value()]; + } + + constexpr inline FieldType ConvertFieldToType(FieldId id) { + const auto index = FindFieldIndex(id); + AMS_ASSERT(index.has_value()); + return FieldIndexToTypeMap[index.value()]; + } + + constexpr inline FieldFlag ConvertFieldToFlag(FieldId id) { + const auto index = FindFieldIndex(id); + AMS_ASSERT(index.has_value()); + return FieldIndexToFlagMap[index.value()]; } constexpr inline ReportFlagSet MakeNoReportFlags() { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp index 1d2b4681b..23dde0b33 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp @@ -69,13 +69,13 @@ namespace ams::erpt::srv { auto guard = SCOPE_GUARD { m_ctx.field_count = 0; }; - R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); - R_UNLESS(0 <= m_ctx.category && m_ctx.category < CategoryId_Count, erpt::ResultInvalidArgument()); + R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); + R_UNLESS(FindCategoryIndex(m_ctx.category).has_value(), erpt::ResultInvalidArgument()); for (u32 i = 0; i < m_ctx.field_count; i++) { m_ctx.fields[i] = ctx_ptr->fields[i]; - R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < FieldId_Count, erpt::ResultInvalidArgument()); + R_UNLESS(FindFieldIndex(m_ctx.fields[i].id).has_value(), erpt::ResultInvalidArgument()); R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); R_UNLESS(m_ctx.fields[i].type == ConvertFieldToType(m_ctx.fields[i].id), erpt::ResultFieldTypeMismatch()); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp index b50712be3..fcdb4836a 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp @@ -62,7 +62,10 @@ namespace ams::erpt::srv { static Result AddId(Report *report, FieldId field_id) { static_assert(MaxFieldStringSize < ElementSize_256); - R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); + const auto index = FindFieldIndex(field_id); + AMS_ASSERT(index.has_value()); + + R_TRY(AddStringValue(report, FieldString[index.value()], strnlen(FieldString[index.value()], MaxFieldStringSize))); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp index 6f23bde32..8fb682244 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp @@ -105,8 +105,8 @@ namespace ams::erpt::srv { g_sf_allocator.Attach(g_heap_handle); - for (auto i = 0; i < CategoryId_Count; i++) { - Context *ctx = new Context(static_cast(i)); + for (const auto category_id : CategoryIndexToCategoryIdMap) { + Context *ctx = new Context(category_id); AMS_ABORT_UNLESS(ctx != nullptr); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index afe0ce1fa..274f9d5ab 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -277,7 +277,7 @@ namespace ams::erpt::srv { void SaveSyslogReportIfRequired(const ContextEntry *ctx, const ReportId &report_id) { bool needs_save_syslog = true; for (u32 i = 0; i < ctx->field_count; i++) { - static_assert(FieldToTypeMap[FieldId_HasSyslogFlag] == FieldType_Bool); + static_assert(FieldIndexToTypeMap[*FindFieldIndex(FieldId_HasSyslogFlag)] == FieldType_Bool); if (ctx->fields[i].id == FieldId_HasSyslogFlag && !ctx->fields[i].value_bool) { needs_save_syslog = false; break;