Mercurial > repos > tabletprog
diff modules/x86.tp @ 361:06dceff348ea
llcompile now has Hacky support for calling C functions using dl to lookup symbols and almost has support string constants
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 23 Apr 2015 19:24:20 -0700 |
parents | 023c29e1f595 |
children | 7101ad443081 |
line wrap: on
line diff
--- a/modules/x86.tp Tue Apr 21 09:00:56 2015 -0700 +++ b/modules/x86.tp Thu Apr 23 19:24:20 2015 -0700 @@ -138,6 +138,11 @@ } int_op:withTail <- :value size :tail { + if: (not: (value isInteger?)) { + //label + //FIXME: Needs implementation + value <- 0 + } if: size >= dword { tail <- (uint8: (rshift: value by: 16u64)) | (uint8: (rshift: value by: 24u64)) | tail } @@ -248,11 +253,26 @@ } } } + + data <- :bytes { + #{ + length <- { bytes byte_length } + flattenTo:at <- :dest :idx { + foreach: (range from: 0 to: length) :_ cidx { + dest set: idx + cidx (bytes byte: cidx) + } + idx + length + } + string <- { + "data: " . bytes + } + } + } op:withCode:withImmed:withOpEx <- :src dst size :normal :immed :myopex { reg <- src rm <- dst - base <- if: (src isInteger?) { + base <- if: (src isInteger?) || (src label?) { reg <- fakesrc (size_bit: immed size) | (mod_rm: (opex: myopex) dst withTail: (int_op: src size)) } else: { @@ -323,6 +343,14 @@ myinst } } + _dlHandle <- option none + _getDLHandle <- { + _dlHandle value: :handle { handle } none: { + handle <- dl open: "" withFlags: (dl NOW) + _dlHandle <- option value: handle + handle + } + } _jmprel <- :op jmpDest { } @@ -557,27 +585,65 @@ } call <- :callDest { - if: (callDest label?) { + if: (callDest isInteger?) { #{ - length <- { 5 } + length <- { 12 } //worst case flattenTo:at <- :dest :idx { - dest set: idx 0xE8u8 - callDest withOffset: :off { - rel <- off - (idx + 5) + base <- (dest _buf_ptr) address + rel <- (callDest uint64) - (base + (idx uint64) + 5u64) + if: rel < 0x80000000u64 || rel >= 0xFFFFFFFF80000000u64 { + rel <- rel int64 + dest set: idx 0xE8u8 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)) + idx + 5 } else: { + dst <- callDest uint64 + dest set: idx 0x48u8 //REX size=quad + dest set: idx + 1 0xB8 //mov immed rax + dest set: idx + 2 (uint8: dst) + dest set: idx + 3 (uint8: (rshift: dst by: 8)) + dest set: idx + 4 (uint8: (rshift: dst by: 16)) + dest set: idx + 5 (uint8: (rshift: dst by: 24)) + dest set: idx + 6 (uint8: (rshift: dst by: 32)) + dest set: idx + 7 (uint8: (rshift: dst by: 40)) + dest set: idx + 8 (uint8: (rshift: dst by: 48)) + dest set: idx + 9 (uint8: (rshift: dst by: 56)) + dest set: idx + 10 0xFFu8 //single EA op + dest set: idx + 11 0xd0u8 //call reg direct + idx + 12 } - idx + 5 + } string <- { "call " . callDest } } } else: { - inst: 0xFFu8 | (mod_rm: (opex: 2u8) 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 + } + string <- { + "call " . callDest + } + } + } else: { + inst: 0xFFu8 | (mod_rm: (opex: 2u8) callDest) + } } } @@ -789,12 +855,18 @@ toCall <- inst target if: (toCall isString?) { //TODO: Handle call to undefined label - toCall <- labels get: toCall else: { - print: "Could not find label " . toCall . "\nDefined labels:\n" - foreach: labels :key _ { - print: "\t" . key . "\n" + toCall <- labels get: toCall else: { + handle <- _getDLHandle: + address <- dl sym: toCall from: handle + if: address != 0u64 { + address + } else: { + print: "Could not find label " . toCall . "\nDefined labels:\n" + foreach: labels :key _ { + print: "\t" . key . "\n" + } + false } - false } } outarr append: (call: toCall) @@ -853,6 +925,13 @@ { outarr append: (setcc: (mapcond: (inst cond)) (inst out)) } + //label + { + } + //data + { + outarr append: (data: (inst bytes)) + } ] print: "Opcode: " . (inst opcode) . "\n" fun <- opmap get: (inst opcode)