Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BlockEncoder option to return all offsets, including for rewritten instructions #643

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
6 changes: 5 additions & 1 deletion src/csharp/Intel/Iced/Intel/BlockEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ public enum BlockEncoderOptions {
ReturnNewInstructionOffsets = 0x00000004,
/// <summary>The <see cref="BlockEncoder"/> should return <see cref="ConstantOffsets"/></summary>
ReturnConstantOffsets = 0x00000008,
/// <summary>The <see cref="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.</summary>
ReturnAllNewInstructionOffsets = 0x00000014,
}
// GENERATOR-END: BlockEncoderOptions

Expand All @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
4 changes: 4 additions & 0 deletions src/rust/iced-x86-js/src/block_encoder_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions src/rust/iced-x86-lua/lua/BlockEncoderOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
7 changes: 6 additions & 1 deletion src/rust/iced-x86/src/block_enc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
4 changes: 4 additions & 0 deletions src/rust/iced-x86/src/block_enc/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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