aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-11-15 00:01:54 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit04102e5c9db600d4ea4ffc0b514bda6f5e300bca (patch)
tree0ac17582778c118b98fc6d1a7f26f17b441374fc /Ryujinx.Graphics.Shader/Decoders/Decoder.cs
parenteea73bc421d359f0df60f377d2f921357a217416 (diff)
Make the shader translator more error resilient
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders/Decoder.cs')
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/Decoder.cs22
1 files changed, 16 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
index 9f039b94..5cee5b3a 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
@@ -29,6 +29,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
Dictionary<ulong, Block> visited = new Dictionary<ulong, Block>();
+ ulong maxAddress = (ulong)code.Length - headerSize;
+
Block GetBlock(ulong blkAddress)
{
if (!visited.TryGetValue(blkAddress, out Block block))
@@ -45,8 +47,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
GetBlock(0);
- ulong maxAddress = (ulong)code.Length - headerSize;
-
while (workQueue.TryDequeue(out Block currBlock))
{
// Check if the current block is inside another block.
@@ -93,6 +93,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
// including those from SSY/PBK instructions.
foreach (OpCodePush pushOp in currBlock.PushOpCodes)
{
+ if (pushOp.GetAbsoluteAddress() >= maxAddress)
+ {
+ return null;
+ }
+
GetBlock(pushOp.GetAbsoluteAddress());
}
@@ -104,6 +109,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
if (lastOp is OpCodeBranch opBr)
{
+ if (opBr.GetAbsoluteAddress() >= maxAddress)
+ {
+ return null;
+ }
+
currBlock.Branch = GetBlock(opBr.GetAbsoluteAddress());
}
else if (lastOp is OpCodeBranchIndir opBrIndir)
@@ -431,11 +441,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
}
else if (current.GetLastOp() is OpCodeBranchPop op)
{
- ulong syncAddress = branchStack.Pop();
+ ulong targetAddress = branchStack.Pop();
if (branchStack.Count == 0)
{
- branchStack.Push(syncAddress);
+ branchStack.Push(targetAddress);
op.Targets.Add(pushOp, op.Targets.Count);
@@ -443,8 +453,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
}
else
{
- Push(new PathBlockState(syncAddress));
- Push(new PathBlockState(blocks[syncAddress]));
+ Push(new PathBlockState(targetAddress));
+ Push(new PathBlockState(blocks[targetAddress]));
}
}
}