aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormerry <git@mary.rs>2022-02-22 14:11:42 +0000
committerGitHub <noreply@github.com>2022-02-22 11:11:42 -0300
commitdc063eac8330da0b18f0f76c7c9c0e484fa10c56 (patch)
tree9207cf611ba077ffeffaddcbc2ec7585dd337e62
parentccf23fc6295dab55bf49823484b34eb1721f6a50 (diff)
ARMeilleure: Implement single stepping (#3133)1.1.50
* Decoder: Implement SingleInstruction decoder mode * Translator: Implement Step * DecoderMode: Rename Normal to MultipleBlocks
-rw-r--r--ARMeilleure/Decoders/Decoder.cs12
-rw-r--r--ARMeilleure/Decoders/DecoderMode.cs9
-rw-r--r--ARMeilleure/Translation/Translator.cs19
3 files changed, 33 insertions, 7 deletions
diff --git a/ARMeilleure/Decoders/Decoder.cs b/ARMeilleure/Decoders/Decoder.cs
index 46774f41..e4839bf7 100644
--- a/ARMeilleure/Decoders/Decoder.cs
+++ b/ARMeilleure/Decoders/Decoder.cs
@@ -18,7 +18,7 @@ namespace ARMeilleure.Decoders
// For lower code quality translation, we set a lower limit since we're blocking execution.
private const int MaxInstsPerFunctionLowCq = 500;
- public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, bool singleBlock)
+ public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode)
{
List<Block> blocks = new List<Block>();
@@ -38,7 +38,7 @@ namespace ARMeilleure.Decoders
{
block = new Block(blkAddress);
- if ((singleBlock && visited.Count >= 1) || opsCount > instructionLimit || !memory.IsMapped(blkAddress))
+ if ((dMode != DecoderMode.MultipleBlocks && visited.Count >= 1) || opsCount > instructionLimit || !memory.IsMapped(blkAddress))
{
block.Exit = true;
block.EndAddress = blkAddress;
@@ -96,6 +96,12 @@ namespace ARMeilleure.Decoders
}
}
+ if (dMode == DecoderMode.SingleInstruction)
+ {
+ // Only read at most one instruction
+ limitAddress = currBlock.Address + 1;
+ }
+
FillBlock(memory, mode, currBlock, limitAddress);
opsCount += currBlock.OpCodes.Count;
@@ -143,7 +149,7 @@ namespace ARMeilleure.Decoders
throw new InvalidOperationException($"Decoded a single empty exit block. Entry point = 0x{address:X}.");
}
- if (!singleBlock)
+ if (dMode == DecoderMode.MultipleBlocks)
{
return TailCallRemover.RunPass(address, blocks);
}
diff --git a/ARMeilleure/Decoders/DecoderMode.cs b/ARMeilleure/Decoders/DecoderMode.cs
new file mode 100644
index 00000000..55362084
--- /dev/null
+++ b/ARMeilleure/Decoders/DecoderMode.cs
@@ -0,0 +1,9 @@
+namespace ARMeilleure.Decoders
+{
+ enum DecoderMode
+ {
+ MultipleBlocks,
+ SingleBlock,
+ SingleInstruction,
+ }
+} \ No newline at end of file
diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs
index 611716e2..389adf29 100644
--- a/ARMeilleure/Translation/Translator.cs
+++ b/ARMeilleure/Translation/Translator.cs
@@ -209,6 +209,17 @@ namespace ARMeilleure.Translation
return nextAddr;
}
+ public ulong Step(State.ExecutionContext context, ulong address)
+ {
+ TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
+
+ address = func.Execute(context);
+
+ EnqueueForDeletion(address, func);
+
+ return address;
+ }
+
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
{
if (!Functions.TryGetValue(address, out TranslatedFunction func))
@@ -242,7 +253,7 @@ namespace ARMeilleure.Translation
}
}
- internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq)
+ internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false)
{
var context = new ArmEmitterContext(
Memory,
@@ -255,7 +266,7 @@ namespace ARMeilleure.Translation
Logger.StartPass(PassName.Decoding);
- Block[] blocks = Decoder.Decode(Memory, address, mode, highCq, singleBlock: false);
+ Block[] blocks = Decoder.Decode(Memory, address, mode, highCq, singleStep ? DecoderMode.SingleInstruction : DecoderMode.MultipleBlocks);
Logger.EndPass(PassName.Decoding);
@@ -285,14 +296,14 @@ namespace ARMeilleure.Translation
var options = highCq ? CompilerOptions.HighCq : CompilerOptions.None;
- if (context.HasPtc)
+ if (context.HasPtc && !singleStep)
{
options |= CompilerOptions.Relocatable;
}
CompiledFunction compiledFunc = Compiler.Compile(cfg, argTypes, retType, options);
- if (context.HasPtc)
+ if (context.HasPtc && !singleStep)
{
Hash128 hash = Ptc.ComputeHash(Memory, address, funcSize);