Example #1
0
 public void JumpTo(X86Condition condition, BasicBlock target)
 {
     Assembler.Jcc(condition, GetLabel(target));
 }
Example #2
0
        public void EnterBlock(BasicBlock block)
        {
            Assembler.MarkLabel(GetLabel(block));

            CurrBlock = block;
        }
Example #3
0
 public void JumpTo(BasicBlock target)
 {
     Assembler.Jmp(GetLabel(target));
 }
Example #4
0
        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());
            }
        }