# HG changeset patch # User Mike Pavone # Date 1377386502 25200 # Node ID f188723c15b4c826162d9ddc8789caad2217d43c # Parent 270d31c6c4cde4c5e5598891c661e4094b37f787 Add call instruction to x86 module diff -r 270d31c6c4cd -r f188723c15b4 modules/x86.tp --- a/modules/x86.tp Sat Aug 24 15:08:00 2013 -0700 +++ b/modules/x86.tp Sat Aug 24 16:21:42 2013 -0700 @@ -10,7 +10,7 @@ validforSize? <- :size { true } isInteger? <- { false } register? <- { true } - localLabel? <- { false } + label? <- { false } upper? <- { true } needsRex? <- { regnum >= 8u8 } rexBitReg <- { @@ -44,7 +44,7 @@ } isInteger? <- { false } register? <- { true } - localLabel? <- { false } + label? <- { false } upper? <- { true } needsRex? <- { false } = <- :other { @@ -267,16 +267,18 @@ label <- { _offset <- -1 + _address <- 0u64 _forwardRefs <- #[] #{ length <- { 0 } hasOffset? <- { _offset >= 0 } offset <- { _offset } register? <- { false } - localLabel? <- { true } + label? <- { true } flattenTo:at <- :dest :idx { if: (not: hasOffset?) { _offset <- idx + _address <- dest addressAt: idx foreach: _forwardRefs :idx fun { fun: _offset } @@ -296,7 +298,7 @@ } jmp <- :jmpDest { - if: (jmpDest localLabel?) { + if: (jmpDest label?) { _size <- -1 #{ length <- { if: _size < 0 { 5 } else: { _size } } @@ -344,10 +346,32 @@ } } + call <- :callDest { + if: (callDest label?) { + #{ + length <- { 5 } + flattenTo:at <- :dest :idx { + dest set: idx 0xE8u8 + callDest withOffset: :off { + rel <- off - (idx + 5) + dest set: (idx + 1) (uint8: rel) + dest set: (idx + 2) (uint8: (rshift: rel by: 8)) + dest set: (idx + 3) (uint8: (rshift: rel by: 16)) + dest set: (idx + 4) (uint8: (rshift: rel by: 24)) + } else: { + } + idx + 5 + } + } + } else: { + inst: 0xFFu8 | (mod_rm: (opex: 2u8) callDest) + } + } main <- { foo <- label: bar <- label: + baz <- label: prog <- #[ mov: rdi rax q sub: 1 rdi q @@ -357,7 +381,11 @@ ret: bar sub: 13 rax q + call: baz jmp: foo + baz + add: 1 rax q + ret: ] ba <- bytearray executableFromBytes: prog