mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
loader: extend memory region descriptors a touch more gracefully
This commit is contained in:
parent
79c9bed528
commit
25ba61adae
3 changed files with 34 additions and 0 deletions
|
@ -47,6 +47,9 @@ namespace ams::ldr::caps {
|
||||||
return static_cast<CapabilityId>(__builtin_ctz(~cap.value));
|
return static_cast<CapabilityId>(__builtin_ctz(~cap.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr inline util::BitPack32 EmptyCapability = {~u32{}};
|
||||||
|
static_assert(GetCapabilityId(EmptyCapability) == CapabilityId::Empty);
|
||||||
|
|
||||||
#define CAPABILITY_CLASS_NAME(id) Capability##id
|
#define CAPABILITY_CLASS_NAME(id) Capability##id
|
||||||
|
|
||||||
#define DEFINE_CAPABILITY_CLASS(id, member_functions) \
|
#define DEFINE_CAPABILITY_CLASS(id, member_functions) \
|
||||||
|
@ -407,4 +410,28 @@ namespace ams::ldr::caps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessCapabilities(void *kac, size_t kac_size) {
|
||||||
|
util::BitPack32 *caps = reinterpret_cast<util::BitPack32 *>(kac);
|
||||||
|
const size_t num_caps = kac_size / sizeof(*caps);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_caps; i++) {
|
||||||
|
const auto cur_cap = caps[i];
|
||||||
|
switch (GetCapabilityId(cur_cap)) {
|
||||||
|
case CapabilityId::MapRegion:
|
||||||
|
{
|
||||||
|
/* MapRegion was added in 8.0.0+. */
|
||||||
|
/* To prevent kernel error, we should reject the descriptor on lower firmwares. */
|
||||||
|
/* NOTE: We also allow it on any firmware under mesosphere, as an extension. */
|
||||||
|
const bool is_allowed = (hos::GetVersion() >= hos::Version_8_0_0 || svc::IsKernelMesosphere());
|
||||||
|
if (!is_allowed) {
|
||||||
|
caps[i] = EmptyCapability;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,6 @@ namespace ams::ldr::caps {
|
||||||
u16 GetProgramInfoFlags(const void *kac, size_t kac_size);
|
u16 GetProgramInfoFlags(const void *kac, size_t kac_size);
|
||||||
void SetProgramInfoFlags(u16 flags, void *kac, size_t kac_size);
|
void SetProgramInfoFlags(u16 flags, void *kac, size_t kac_size);
|
||||||
|
|
||||||
|
void ProcessCapabilities(void *kac, size_t kac_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,6 +225,11 @@ namespace ams::ldr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pre-process the capabilities. */
|
||||||
|
/* This is used to e.g. avoid passing memory region descriptor to older kernels. */
|
||||||
|
caps::ProcessCapabilities(meta->acid_kac, meta->acid->kac_size);
|
||||||
|
caps::ProcessCapabilities(meta->aci_kac, meta->aci->kac_size);
|
||||||
|
|
||||||
/* Set output. */
|
/* Set output. */
|
||||||
g_cached_program_id = loc.program_id;
|
g_cached_program_id = loc.program_id;
|
||||||
g_cached_override_status = status;
|
g_cached_override_status = status;
|
||||||
|
|
Loading…
Reference in a new issue