Memmap: Replace GetPointer with GetSpanForAddress

To ensure memory safety, callers of GetPointer have to perform a bounds
check. But how is this bounds check supposed to be performed?
GetPointerForRange contained one implementation of a bounds check, but
it was cumbersome, and it also isn't obvious why it's correct.

To make doing the right thing easier, this commit changes GetPointer to
return a span that tells the caller how many bytes it's allowed to
access.
This commit is contained in:
JosJuice
2024-04-13 12:08:43 +02:00
parent 017f72f43e
commit 5c9bb80638
5 changed files with 53 additions and 25 deletions

View File

@ -91,26 +91,35 @@ void UpdateVertexArrayPointers()
// Note: Only array bases 0 through 11 are used by the Vertex loaders.
// 12 through 15 are used for loading data into xfmem.
// We also only update the array base if the vertex description states we are going to use it.
// TODO: For memory safety, we need to check the sizes returned by GetSpanForAddress
if (IsIndexed(g_main_cp_state.vtx_desc.low.Position))
{
cached_arraybases[CPArray::Position] =
memory.GetPointer(g_main_cp_state.array_bases[CPArray::Position]);
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::Position]).data();
}
if (IsIndexed(g_main_cp_state.vtx_desc.low.Normal))
{
cached_arraybases[CPArray::Normal] =
memory.GetPointer(g_main_cp_state.array_bases[CPArray::Normal]);
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::Normal]).data();
}
for (u8 i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++)
{
if (IsIndexed(g_main_cp_state.vtx_desc.low.Color[i]))
{
cached_arraybases[CPArray::Color0 + i] =
memory.GetPointer(g_main_cp_state.array_bases[CPArray::Color0 + i]);
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::Color0 + i]).data();
}
}
for (u8 i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++)
{
if (IsIndexed(g_main_cp_state.vtx_desc.high.TexCoord[i]))
{
cached_arraybases[CPArray::TexCoord0 + i] =
memory.GetPointer(g_main_cp_state.array_bases[CPArray::TexCoord0 + i]);
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::TexCoord0 + i]).data();
}
}
g_bases_dirty = false;