From 0a62d110f280688e9383ecb9351c97cfcdcf2a44 Mon Sep 17 00:00:00 2001 From: tremwil Date: Thu, 12 Dec 2024 02:46:44 -0500 Subject: [PATCH 1/4] add BlockEncoder option to return all instruction offsets --- .../Intel/Generator/Enums/Encoder/BlockEncoderOptions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/csharp/Intel/Generator/Enums/Encoder/BlockEncoderOptions.cs b/src/csharp/Intel/Generator/Enums/Encoder/BlockEncoderOptions.cs index b65be8136..198eee549 100644 --- a/src/csharp/Intel/Generator/Enums/Encoder/BlockEncoderOptions.cs +++ b/src/csharp/Intel/Generator/Enums/Encoder/BlockEncoderOptions.cs @@ -21,5 +21,8 @@ public enum BlockEncoderOptions : uint { [Comment("The #(r:BlockEncoder)# should return #(r:ConstantOffsets)#")] ReturnConstantOffsets = 0x00000008, + + [Comment("The #(r:BlockEncoder)# should return new instruction offsets. For instructions that have been rewritten (e.g. to fix branches), the offset to the resulting block of instructions is returned.")] + ReturnAllNewInstructionOffsets = 0x00000014 } } From a86b611cbe5103aaea8871ae79e536ec3adbdafb Mon Sep 17 00:00:00 2001 From: tremwil Date: Thu, 12 Dec 2024 02:47:57 -0500 Subject: [PATCH 2/4] run codegen --- src/csharp/Intel/Iced/Intel/BlockEncoder.cs | 2 ++ .../com/github/icedland/iced/x86/enc/BlockEncoderOptions.java | 4 ++++ src/rust/iced-x86-js/src/block_encoder_options.rs | 4 ++++ src/rust/iced-x86-lua/lua/BlockEncoderOptions.lua | 2 ++ src/rust/iced-x86/src/block_enc/enums.rs | 4 ++++ 5 files changed, 16 insertions(+) diff --git a/src/csharp/Intel/Iced/Intel/BlockEncoder.cs b/src/csharp/Intel/Iced/Intel/BlockEncoder.cs index ec0a167c2..96b9d2bb8 100644 --- a/src/csharp/Intel/Iced/Intel/BlockEncoder.cs +++ b/src/csharp/Intel/Iced/Intel/BlockEncoder.cs @@ -130,6 +130,8 @@ public enum BlockEncoderOptions { ReturnNewInstructionOffsets = 0x00000004, /// The should return ReturnConstantOffsets = 0x00000008, + /// The should return new instruction offsets. For instructions that have been rewritten (e.g. to fix branches), the offset to the resulting block of instructions is returned. + ReturnAllNewInstructionOffsets = 0x00000014, } // GENERATOR-END: BlockEncoderOptions diff --git a/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoderOptions.java b/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoderOptions.java index 5dabfae93..b056cf11f 100644 --- a/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoderOptions.java +++ b/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoderOptions.java @@ -32,4 +32,8 @@ private BlockEncoderOptions() { * The {@link com.github.icedland.iced.x86.enc.BlockEncoder} should return {@link com.github.icedland.iced.x86.ConstantOffsets} */ public static final int RETURN_CONSTANT_OFFSETS = 0x0000_0008; + /** + * The {@link com.github.icedland.iced.x86.enc.BlockEncoder} should return new instruction offsets. For instructions that have been rewritten (e.g. to fix branches), the offset to the resulting block of instructions is returned. + */ + public static final int RETURN_ALL_NEW_INSTRUCTION_OFFSETS = 0x0000_0014; } diff --git a/src/rust/iced-x86-js/src/block_encoder_options.rs b/src/rust/iced-x86-js/src/block_encoder_options.rs index 149914e5c..d3bbb9862 100644 --- a/src/rust/iced-x86-js/src/block_encoder_options.rs +++ b/src/rust/iced-x86-js/src/block_encoder_options.rs @@ -30,5 +30,9 @@ pub enum BlockEncoderOptions { /// [`BlockEncoder`]: struct.BlockEncoder.html /// [`ConstantOffsets`]: struct.ConstantOffsets.html ReturnConstantOffsets = 0x0000_0008, + /// The [`BlockEncoder`] should return new instruction offsets. For instructions that have been rewritten (e.g. to fix branches), the offset to the resulting block of instructions is returned. + /// + /// [`BlockEncoder`]: struct.BlockEncoder.html + ReturnAllNewInstructionOffsets = 0x0000_0014, } // GENERATOR-END: Enum diff --git a/src/rust/iced-x86-lua/lua/BlockEncoderOptions.lua b/src/rust/iced-x86-lua/lua/BlockEncoderOptions.lua index dc35b7d96..08162a2f2 100644 --- a/src/rust/iced-x86-lua/lua/BlockEncoderOptions.lua +++ b/src/rust/iced-x86-lua/lua/BlockEncoderOptions.lua @@ -15,4 +15,6 @@ return { ReturnNewInstructionOffsets = 0x00000004, ---The `BlockEncoder` should return `ConstantOffsets` ReturnConstantOffsets = 0x00000008, + ---The `BlockEncoder` should return new instruction offsets. For instructions that have been rewritten (e.g. to fix branches), the offset to the resulting block of instructions is returned. + ReturnAllNewInstructionOffsets = 0x00000014, } diff --git a/src/rust/iced-x86/src/block_enc/enums.rs b/src/rust/iced-x86/src/block_enc/enums.rs index c21d5d671..146fd073a 100644 --- a/src/rust/iced-x86/src/block_enc/enums.rs +++ b/src/rust/iced-x86/src/block_enc/enums.rs @@ -161,5 +161,9 @@ impl BlockEncoderOptions { /// [`BlockEncoder`]: struct.BlockEncoder.html /// [`ConstantOffsets`]: struct.ConstantOffsets.html pub const RETURN_CONSTANT_OFFSETS: u32 = 0x0000_0008; + /// The [`BlockEncoder`] should return new instruction offsets. For instructions that have been rewritten (e.g. to fix branches), the offset to the resulting block of instructions is returned. + /// + /// [`BlockEncoder`]: struct.BlockEncoder.html + pub const RETURN_ALL_NEW_INSTRUCTION_OFFSETS: u32 = 0x0000_0014; } // GENERATOR-END: BlockEncoderOptions From b7246fc59b5dd8d2c1d8010a7c1aa8e143941c9c Mon Sep 17 00:00:00 2001 From: tremwil Date: Thu, 12 Dec 2024 02:48:39 -0500 Subject: [PATCH 3/4] implement ReturnAllNewInstructionOffsets logic --- src/csharp/Intel/Iced/Intel/BlockEncoder.cs | 4 +++- .../com/github/icedland/iced/x86/enc/BlockEncoder.java | 7 ++++++- src/rust/iced-x86/src/block_enc.rs | 7 ++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/csharp/Intel/Iced/Intel/BlockEncoder.cs b/src/csharp/Intel/Iced/Intel/BlockEncoder.cs index 96b9d2bb8..a06a5798c 100644 --- a/src/csharp/Intel/Iced/Intel/BlockEncoder.cs +++ b/src/csharp/Intel/Iced/Intel/BlockEncoder.cs @@ -150,6 +150,8 @@ public sealed class BlockEncoder { bool ReturnRelocInfos => (options & BlockEncoderOptions.ReturnRelocInfos) != 0; bool ReturnNewInstructionOffsets => (options & BlockEncoderOptions.ReturnNewInstructionOffsets) != 0; bool ReturnConstantOffsets => (options & BlockEncoderOptions.ReturnConstantOffsets) != 0; + bool ReturnAllNewInstructionOffsets => (options & BlockEncoderOptions.ReturnAllNewInstructionOffsets) != 0; + sealed class NullCodeWriter : CodeWriter { public static readonly NullCodeWriter Instance = new NullCodeWriter(); @@ -330,7 +332,7 @@ bool Encode([NotNullWhen(false)] out string? errorMessage, [NotNullWhen(true)] o return false; } if (newInstructionOffsets is not null) { - if (isOriginalInstruction) + if (isOriginalInstruction || ReturnAllNewInstructionOffsets) newInstructionOffsets[j] = (uint)(ip - block.RIP); else newInstructionOffsets[j] = uint.MaxValue; diff --git a/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoder.java b/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoder.java index e7610179a..ee5368d67 100644 --- a/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoder.java +++ b/src/java/iced-x86/src/main/java/com/github/icedland/iced/x86/enc/BlockEncoder.java @@ -44,6 +44,10 @@ private boolean returnConstantOffsets() { return (options & BlockEncoderOptions.RETURN_CONSTANT_OFFSETS) != 0; } + private boolean returnAllConstantOffsets() { + return (options & BlockEncoderOptions.RETURN_ALL_NEW_INSTRUCTION_OFFSETS) != 0; + } + private static final class NullCodeWriter implements CodeWriter { public static final NullCodeWriter instance = new NullCodeWriter(); @@ -244,6 +248,7 @@ else if (instr.size != oldSize) BlockEncoderResult[] resultArray = new BlockEncoderResult[blocks.length]; TryEncodeResult tryEncResult = new TryEncodeResult(); + boolean returnAllOffsets = returnAllConstantOffsets(); for (int i = 0; i < blocks.length; i++) { Block block = blocks[i]; Encoder encoder = new Encoder(bitness, block.codeWriter); @@ -263,7 +268,7 @@ else if (instr.size != oldSize) if (size != instr.size) return "Internal error: didn't write all bytes"; if (newInstructionOffsets != null) { - if (tryEncResult.isOriginalInstruction) + if (tryEncResult.isOriginalInstruction || returnAllOffsets) newInstructionOffsets[j] = (int)(ip - block.rip); else newInstructionOffsets[j] = 0xFFFF_FFFF; diff --git a/src/rust/iced-x86/src/block_enc.rs b/src/rust/iced-x86/src/block_enc.rs index be94b0971..ceb79dd92 100644 --- a/src/rust/iced-x86/src/block_enc.rs +++ b/src/rust/iced-x86/src/block_enc.rs @@ -421,7 +421,12 @@ impl BlockEncoder { return Err(IcedError::new("Internal error")); } if (self.benc.options & BlockEncoderOptions::RETURN_NEW_INSTRUCTION_OFFSETS) != 0 { - new_instruction_offsets.push(if is_original_instruction { ctx.ip.wrapping_sub(ctx.block.rip) as u32 } else { u32::MAX }); + let return_all_offsets = (self.benc.options & BlockEncoderOptions::RETURN_ALL_NEW_INSTRUCTION_OFFSETS) != 0; + new_instruction_offsets.push(if return_all_offsets || is_original_instruction { + ctx.ip.wrapping_sub(ctx.block.rip) as u32 + } else { + u32::MAX + }); } ctx.ip = ctx.ip.wrapping_add(size as u64); } From bce65d2f1f9a32565b4acb85eb8b910ff5b61b60 Mon Sep 17 00:00:00 2001 From: tremwil Date: Tue, 31 Dec 2024 13:08:23 +0000 Subject: [PATCH 4/4] cargo fmt --- src/rust/iced-x86/src/block_enc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/iced-x86/src/block_enc.rs b/src/rust/iced-x86/src/block_enc.rs index ceb79dd92..468ebe789 100644 --- a/src/rust/iced-x86/src/block_enc.rs +++ b/src/rust/iced-x86/src/block_enc.rs @@ -422,10 +422,10 @@ impl BlockEncoder { } if (self.benc.options & BlockEncoderOptions::RETURN_NEW_INSTRUCTION_OFFSETS) != 0 { let return_all_offsets = (self.benc.options & BlockEncoderOptions::RETURN_ALL_NEW_INSTRUCTION_OFFSETS) != 0; - new_instruction_offsets.push(if return_all_offsets || is_original_instruction { - ctx.ip.wrapping_sub(ctx.block.rip) as u32 - } else { - u32::MAX + new_instruction_offsets.push(if return_all_offsets || is_original_instruction { + ctx.ip.wrapping_sub(ctx.block.rip) as u32 + } else { + u32::MAX }); } ctx.ip = ctx.ip.wrapping_add(size as u64);