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
}
}
diff --git a/src/csharp/Intel/Iced/Intel/BlockEncoder.cs b/src/csharp/Intel/Iced/Intel/BlockEncoder.cs
index ec0a167c2..a06a5798c 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
@@ -148,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();
@@ -328,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/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.rs b/src/rust/iced-x86/src/block_enc.rs
index be94b0971..468ebe789 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);
}
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