public void JumpTo(X86Condition condition, BasicBlock target) { Assembler.Jcc(condition, GetLabel(target)); }
public void EnterBlock(BasicBlock block) { Assembler.MarkLabel(GetLabel(block)); CurrBlock = block; }
public void JumpTo(BasicBlock target) { Assembler.Jmp(GetLabel(target)); }
public byte[] GetCode() { // Write jump relative offsets. bool modified; do { modified = false; for (int index = 0; index < _jumps.Count; index++) { Jump jump = _jumps[index]; long jumpTarget = _blockOffsets[jump.Target.Index]; long offset = jumpTarget - jump.JumpPosition; if (_ptcDisabled) { if (offset < 0) { for (int index2 = index - 1; index2 >= 0; index2--) { Jump jump2 = _jumps[index2]; if (jump2.JumpPosition < jumpTarget) { break; } offset -= jump2.InstSize - ReservedBytesForJump; } } else { for (int index2 = index + 1; index2 < _jumps.Count; index2++) { Jump jump2 = _jumps[index2]; if (jump2.JumpPosition >= jumpTarget) { break; } offset += jump2.InstSize - ReservedBytesForJump; } offset -= ReservedBytesForJump; } if (jump.IsConditional) { jump.InstSize = Assembler.GetJccLength(offset); } else { jump.InstSize = Assembler.GetJmpLength(offset); } // The jump is relative to the next instruction, not the current one. // Since we didn't know the next instruction address when calculating // the offset (as the size of the current jump instruction was not known), // we now need to compensate the offset with the jump instruction size. // It's also worth noting that: // - This is only needed for backward jumps. // - The GetJmpLength and GetJccLength also compensates the offset // internally when computing the jump instruction size. if (offset < 0) { offset -= jump.InstSize; } } else { offset -= jump.InstSize; } if (jump.RelativeOffset != offset) { modified = true; } jump.RelativeOffset = offset; _jumps[index] = jump; } }while (modified); // Write the code, ignoring the dummy bytes after jumps, into a new stream. _stream.Seek(0, SeekOrigin.Begin); using (MemoryStream codeStream = new MemoryStream()) { Assembler assembler = new Assembler(codeStream, _ptcInfo); for (int index = 0; index < _jumps.Count; index++) { Jump jump = _jumps[index]; Span <byte> buffer = new byte[jump.JumpPosition - _stream.Position]; _stream.Read(buffer); _stream.Seek(_ptcDisabled ? ReservedBytesForJump : jump.InstSize, SeekOrigin.Current); codeStream.Write(buffer); if (jump.IsConditional) { assembler.Jcc(jump.Condition, jump.RelativeOffset); } else { assembler.Jmp(jump.RelativeOffset); } } _stream.CopyTo(codeStream); return(codeStream.ToArray()); } }